diff --git a/ngc_ext_common.hpp b/ngc_ext_common.hpp new file mode 100644 index 0000000..a5fd94c --- /dev/null +++ b/ngc_ext_common.hpp @@ -0,0 +1,100 @@ +#include + +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +#include + +struct _GroupKey { + std::array data; + + _GroupKey(void) = default; + _GroupKey(const _GroupKey& other) : data(other.data) {} + _GroupKey(_GroupKey&&) = delete; + + bool operator<(const _GroupKey& rhs) const { + for (size_t i = 0; i < data.size(); i++) { + if (data[i] < rhs.data[i]) { + return true; + } else if (data[i] > rhs.data[i]) { + return false; + } + } + return false; // equal + } + + bool operator==(const _GroupKey& rhs) const { + for (size_t i = 0; i < data.size(); i++) { + if (data[i] != rhs.data[i]) { + return false; + } + } + return true; + } +}; + +struct _PeerKey { + std::array data; + + _PeerKey(void) = default; + _PeerKey(const _PeerKey& other) : data(other.data) {} + _PeerKey(_PeerKey&&) = delete; + + bool operator<(const _PeerKey& rhs) const { + for (size_t i = 0; i < data.size(); i++) { + if (data[i] < rhs.data[i]) { + return true; + } else if (data[i] > rhs.data[i]) { + return false; + } + } + return false; // equal + } + + bool operator==(const _PeerKey& rhs) const { + for (size_t i = 0; i < data.size(); i++) { + if (data[i] != rhs.data[i]) { + return false; + } + } + return true; + } +}; + +enum _PacketType : uint8_t { + // TODO: why? + INVALID = 0u, + + //TODO: make it possible to go further back + + // request last (few) message_ids for a peer + // - peer_key bytes (peer key we want to know ids for) + // - 1 byte (uint8_t count ids, atleast 1) + HS1_REQUEST_LAST_IDS, + + // respond to a request with 0 or more message ids, sorted by newest first + // - peer_key bytes (the msg_ids are from) + // - 1 byte (uint8_t count ids, can be 0) + // - array [ + // - msg_id bytes (the message id + // - ] + HS1_RESPONSE_LAST_IDS, + +}; + +static const char* _pkgid2str(_PacketType type) { +#define _HS1_CASE(x) case (x): return #x; + switch (type) { + _HS1_CASE(INVALID) + _HS1_CASE(HS1_REQUEST_LAST_IDS) + _HS1_CASE(HS1_RESPONSE_LAST_IDS) + default: return ""; + } +#undef _HS1_CASE +} + diff --git a/ngc_hs1.cpp b/ngc_hs1.cpp index 1279f4c..fd5881a 100644 --- a/ngc_hs1.cpp +++ b/ngc_hs1.cpp @@ -1,5 +1,7 @@ #include "./ngc_hs1.h" +#include "ngc_ext_common.hpp" + #include #include #include @@ -9,93 +11,6 @@ #include #include -struct _GroupID { - std::array data; - - _GroupID(void) = default; - _GroupID(const _GroupID& other) : data(other.data) {} - _GroupID(_GroupID&&) = delete; - //_GroupID(_GroupID&& other) : data(std::move(other.data)) {} - - bool operator<(const _GroupID& rhs) const { - for (size_t i = 0; i < data.size(); i++) { - if (data[i] < rhs.data[i]) { - return true; - } else if (data[i] > rhs.data[i]) { - return false; - } - } - return false; // equal - } - - bool operator==(const _GroupID& rhs) const { - for (size_t i = 0; i < data.size(); i++) { - if (data[i] != rhs.data[i]) { - return false; - } - } - return true; - } -}; - -struct _PeerID { - std::array data; - - _PeerID(void) = default; - _PeerID(const _PeerID& other) : data(other.data) {} - _PeerID(_PeerID&&) = delete; - - bool operator<(const _PeerID& rhs) const { - for (size_t i = 0; i < data.size(); i++) { - if (data[i] < rhs.data[i]) { - return true; - } else if (data[i] > rhs.data[i]) { - return false; - } - } - return false; // equal - } - - bool operator==(const _PeerID& rhs) const { - for (size_t i = 0; i < data.size(); i++) { - if (data[i] != rhs.data[i]) { - return false; - } - } - return true; - } -}; - -enum _PacketType : uint8_t { - INVALID = 0u, - - // request last (few) message_ids for a peer - // - peer_key bytes (peer key we want to know ids for) - // - 1 byte (uint8_t count ids, atleast 1) - HS_REQUEST_LAST_IDS, - - // respond to a request with 0 or more message ids, sorted by newest first - // - peer_key bytes (the msg_ids are from) - // - 1 byte (uint8_t count ids, can be 0) - // - array [ - // - msg_id bytes (the message id - // - ] - HS_RESPONSE_LAST_IDS, - - //TODO: make it possible to go further back -}; - -const char* _pkgid2str(_PacketType type) { -#define _HS1_CASE(x) case (x): return #x; - switch (type) { - _HS1_CASE(INVALID) - _HS1_CASE(HS_REQUEST_LAST_IDS) - _HS1_CASE(HS_RESPONSE_LAST_IDS) - default: return ""; - } -#undef _HS1_CASE -} - struct NGC_HS1 { NGC_HS1_options options; @@ -122,52 +37,56 @@ struct NGC_HS1 { // dont start immediatly float time_since_last_request_sent {0.f}; - void append(uint32_t msg_id, Tox_Message_Type type, const std::string& text) { - order.push_back(msg_id); - - // overwrites - auto& new_msg = dict[msg_id]; - new_msg.msg_id = msg_id; - new_msg.type = type; - new_msg.text = text; - - if (heard_of.count(msg_id)) { - // we got history before we got the message - heard_of.erase(msg_id); - } - - fprintf(stderr, "######## last msgs ########\n"); - auto rit = order.crbegin(); - for (size_t i = 0; i < 10 && rit != order.crend(); i++, rit++) { - fprintf(stderr, " %08X - %s\n", *rit, dict.at(*rit).text.c_str()); - } - } + void append(uint32_t msg_id, Tox_Message_Type type, const std::string& text); // returns if new (from that peer) - bool hear(uint32_t msg_id, uint32_t peer_number) { - if (dict.count(msg_id)) { - // we know - return false; - } - - if (heard_of.count(msg_id) && heard_of.at(msg_id).count(peer_number)) { - // we heard it from that peer before - return false; - } - - heard_of[msg_id].emplace(peer_number); - - return true; - } + bool hear(uint32_t msg_id, uint32_t peer_number); }; struct Group { - std::map<_PeerID, Peer> peers; + std::map<_PeerKey, Peer> peers; }; - std::map<_GroupID, Group> history; + std::map<_GroupKey, Group> history; }; +void NGC_HS1::Peer::append(uint32_t msg_id, Tox_Message_Type type, const std::string& text) { + order.push_back(msg_id); + + // overwrites + auto& new_msg = dict[msg_id]; + new_msg.msg_id = msg_id; + new_msg.type = type; + new_msg.text = text; + + if (heard_of.count(msg_id)) { + // we got history before we got the message + heard_of.erase(msg_id); + } + + fprintf(stderr, "######## last msgs ########\n"); + auto rit = order.crbegin(); + for (size_t i = 0; i < 10 && rit != order.crend(); i++, rit++) { + fprintf(stderr, " %08X - %s\n", *rit, dict.at(*rit).text.c_str()); + } +} + +bool NGC_HS1::Peer::hear(uint32_t msg_id, uint32_t peer_number) { + if (dict.count(msg_id)) { + // we know + return false; + } + + if (heard_of.count(msg_id) && heard_of.at(msg_id).count(peer_number)) { + // we heard it from that peer before + return false; + } + + heard_of[msg_id].emplace(peer_number); + + return true; +} + NGC_HS1* NGC_HS1_new(const struct NGC_HS1_options* options) { NGC_HS1* context = new NGC_HS1; @@ -182,7 +101,7 @@ void NGC_HS1_kill(NGC_HS1* ngc_hs1_ctx) { static void _iterate_group(Tox *tox, NGC_HS1* ngc_hs1_ctx, uint32_t group_number, float time_delta) { //fprintf(stderr, "g:%u\n", g_i); - _GroupID g_id{}; + _GroupKey g_id{}; { // TODO: error tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); } @@ -203,7 +122,7 @@ static void _iterate_group(Tox *tox, NGC_HS1* ngc_hs1_ctx, uint32_t group_number for (auto& [key, peer] : group.peers) { //fprintf(stderr, " p: %X%X%X%X\n", key.data.data()[0], key.data.data()[1], key.data.data()[2], key.data.data()[3]); peer.time_since_last_request_sent += time_delta; - if (peer.time_since_last_request_sent > 15.f) { + if (peer.time_since_last_request_sent > ngc_hs1_ctx->options.query_interval_per_peer) { peer.time_since_last_request_sent = 0.f; fprintf(stderr, "requesting ids for %X%X%X%X\n", key.data.data()[0], key.data.data()[1], key.data.data()[2], key.data.data()[3]); @@ -215,9 +134,9 @@ static void _iterate_group(Tox *tox, NGC_HS1* ngc_hs1_ctx, uint32_t group_number // - peer_key bytes (peer key we want to know ids for) // - 1 byte (uint8_t count ids, atleast 1) std::array pkg; - pkg[0] = HS_REQUEST_LAST_IDS; + pkg[0] = HS1_REQUEST_LAST_IDS; std::copy(key.data.begin(), key.data.end(), pkg.begin()+1); - pkg[1+TOX_GROUP_PEER_PUBLIC_KEY_SIZE] = 5; // request last (up to) 5 msg_ids + pkg[1+TOX_GROUP_PEER_PUBLIC_KEY_SIZE] = ngc_hs1_ctx->options.last_msg_ids_count; // request last (up to) 5 msg_ids tox_group_send_custom_packet(tox, group_number, true, pkg.data(), pkg.size(), nullptr); } @@ -256,7 +175,7 @@ void NGC_HS1_iterate(Tox *tox, NGC_HS1* ngc_hs1_ctx/*, void *user_data*/) { void NGC_HS1_peer_online(Tox* tox, NGC_HS1* ngc_hs1_ctx, uint32_t group_number, uint32_t peer_number, bool online) { // get group id - _GroupID g_id{}; + _GroupKey g_id{}; { // TODO: error tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); } @@ -265,7 +184,7 @@ void NGC_HS1_peer_online(Tox* tox, NGC_HS1* ngc_hs1_ctx, uint32_t group_number, if (online) { // get peer id - _PeerID p_id{}; + _PeerKey p_id{}; { // TODO: error tox_group_peer_get_public_key(tox, group_number, peer_number, p_id.data.data(), nullptr); } @@ -319,13 +238,13 @@ void NGC_HS1_record_own_message( ) { fprintf(stderr, "record_own_message %08X\n", message_id); // get group id - _GroupID g_id{}; + _GroupKey g_id{}; { // TODO: error tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); } // get peer id - _PeerID p_id{}; + _PeerKey p_id{}; { // TODO: error tox_group_self_get_public_key(tox, group_number, p_id.data.data(), nullptr); } @@ -351,13 +270,13 @@ void NGC_HS1_record_message( fprintf(stderr, "record_message %08X\n", message_id); // get group id - _GroupID g_id{}; + _GroupKey g_id{}; { // TODO: error tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); } // get peer id - _PeerID p_id{}; + _PeerKey p_id{}; { // TODO: error tox_group_peer_get_public_key(tox, group_number, peer_number, p_id.data.data(), nullptr); } @@ -365,7 +284,7 @@ void NGC_HS1_record_message( ngc_hs1_ctx->history[g_id].peers[p_id].append(message_id, type, std::string{message, message+length}); } -static void _handle_HS_REQUEST_LAST_IDS( +static void _handle_HS1_REQUEST_LAST_IDS( Tox* tox, NGC_HS1* ngc_hs1_ctx, @@ -376,7 +295,7 @@ static void _handle_HS_REQUEST_LAST_IDS( size_t length ); -static void _handle_HS_RESPONSE_LAST_IDS( +static void _handle_HS1_RESPONSE_LAST_IDS( Tox* tox, NGC_HS1* ngc_hs1_ctx, @@ -411,17 +330,17 @@ void NGC_HS1_handle_group_custom_packet( switch (pkg_type) { case INVALID: break; - case HS_REQUEST_LAST_IDS: - _handle_HS_REQUEST_LAST_IDS(tox, ngc_hs1_ctx, group_number, peer_number, data+curser, length-curser); + case HS1_REQUEST_LAST_IDS: + _handle_HS1_REQUEST_LAST_IDS(tox, ngc_hs1_ctx, group_number, peer_number, data+curser, length-curser); break; - case HS_RESPONSE_LAST_IDS: - _handle_HS_RESPONSE_LAST_IDS(tox, ngc_hs1_ctx, group_number, peer_number, data+curser, length-curser); + case HS1_RESPONSE_LAST_IDS: + _handle_HS1_RESPONSE_LAST_IDS(tox, ngc_hs1_ctx, group_number, peer_number, data+curser, length-curser); break; } } -static void _handle_HS_REQUEST_LAST_IDS( +static void _handle_HS1_REQUEST_LAST_IDS( Tox* tox, NGC_HS1* ngc_hs1_ctx, @@ -433,7 +352,7 @@ static void _handle_HS_REQUEST_LAST_IDS( ) { size_t curser = 0; - _PeerID p_key; + _PeerKey p_key; _HS1_HAVE(p_key.data.size(), fprintf(stderr, "packet too small, missing pkey\n"); return) std::copy(data+curser, data+curser+p_key.data.size(), p_key.data.begin()); @@ -445,7 +364,7 @@ static void _handle_HS_REQUEST_LAST_IDS( fprintf(stderr, "got request for last %u ids\n", last_msg_id_count); // get group id - _GroupID g_id{}; + _GroupKey g_id{}; { // TODO: error tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); } @@ -475,7 +394,7 @@ static void _handle_HS_REQUEST_LAST_IDS( size_t packing_curser = 0; - pkg[packing_curser++] = HS_RESPONSE_LAST_IDS; + pkg[packing_curser++] = HS1_RESPONSE_LAST_IDS; std::copy(p_key.data.begin(), p_key.data.end(), pkg.begin()+packing_curser); packing_curser += p_key.data.size(); @@ -493,7 +412,7 @@ static void _handle_HS_REQUEST_LAST_IDS( tox_group_send_custom_private_packet(tox, group_number, peer_number, true, pkg.data(), pkg.size(), nullptr); } -static void _handle_HS_RESPONSE_LAST_IDS( +static void _handle_HS1_RESPONSE_LAST_IDS( Tox* tox, NGC_HS1* ngc_hs1_ctx, @@ -505,7 +424,7 @@ static void _handle_HS_RESPONSE_LAST_IDS( ) { size_t curser = 0; - _PeerID p_key; + _PeerKey p_key; _HS1_HAVE(p_key.data.size(), fprintf(stderr, "packet too small, missing pkey\n"); return) std::copy(data+curser, data+curser+p_key.data.size(), p_key.data.begin()); @@ -523,7 +442,7 @@ static void _handle_HS_RESPONSE_LAST_IDS( } // get group id - _GroupID g_id{}; + _GroupKey g_id{}; { // TODO: error tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); } diff --git a/ngc_hs1.h b/ngc_hs1.h index e17b233..7fd3180 100644 --- a/ngc_hs1.h +++ b/ngc_hs1.h @@ -42,6 +42,10 @@ struct NGC_HS1_options { uint8_t default_trust_level /*= 2*/; bool record_others; + + float query_interval_per_peer; // 15.f + + size_t last_msg_ids_count; // 5 }; // ========== init / kill ==========