diff --git a/ngc_hs1.cpp b/ngc_hs1.cpp index 8f7a4ff..4cb2ab8 100644 --- a/ngc_hs1.cpp +++ b/ngc_hs1.cpp @@ -12,22 +12,19 @@ struct _GroupID { std::array data; _GroupID(void) = default; - _GroupID(const _GroupID& other) : data(other.data) { - fprintf(stderr, "gcopy\n"); - assert(data.data() != other.data.data()); - assert(data[0] == other.data[0]); - assert(data[1] == other.data[1]); - } + _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]) { + if (data[i] < rhs.data[i]) { + return true; + } else if (data[i] > rhs.data[i]) { return false; } } - return true; + return false; // equal } bool operator==(const _GroupID& rhs) const { @@ -49,11 +46,13 @@ struct _PeerID { bool operator<(const _PeerID& rhs) const { for (size_t i = 0; i < data.size(); i++) { - if (data[i] >= rhs.data[i]) { + if (data[i] < rhs.data[i]) { + return true; + } else if (data[i] > rhs.data[i]) { return false; } } - return true; + return false; // equal } bool operator==(const _PeerID& rhs) const { @@ -128,6 +127,12 @@ struct NGC_HS1 { new_msg.msg_id = msg_id; new_msg.type = type; new_msg.text = text; + + 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()); + } } }; @@ -173,7 +178,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 > 5.f) { + if (peer.time_since_last_request_sent > 15.f) { 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]); @@ -210,7 +215,7 @@ void NGC_HS1_iterate(Tox *tox, NGC_HS1* ngc_hs1_ctx/*, void *user_data*/) { if (tox_group_is_connected(tox, g_i, &g_err)) { // valid and connected here // TODO: delta time, or other timers - _iterate_group(tox, ngc_hs1_ctx, g_i, 0.2f); + _iterate_group(tox, ngc_hs1_ctx, g_i, 0.02f); g_c_done++; } else if (g_err != TOX_ERR_GROUP_IS_CONNECTED_GROUP_NOT_FOUND) { g_c_done++; @@ -346,6 +351,17 @@ static void _handle_HS_REQUEST_LAST_IDS( size_t length ); +static void _handle_HS_RESPONSE_LAST_IDS( + Tox* tox, + NGC_HS1* ngc_hs1_ctx, + + uint32_t group_number, + uint32_t peer_number, + + const uint8_t *data, + size_t length +); + #define _HS1_HAVE(x, error) if ((length - curser) < (x)) { error; } void NGC_HS1_handle_group_custom_packet( Tox* tox, @@ -374,6 +390,7 @@ void NGC_HS1_handle_group_custom_packet( _handle_HS_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); break; } @@ -401,6 +418,75 @@ static void _handle_HS_REQUEST_LAST_IDS( uint8_t last_msg_id_count = data[curser++]; fprintf(stderr, "got request for last %u ids\n", last_msg_id_count); + + // get group id + _GroupID g_id{}; + { // TODO: error + tox_group_get_chat_id(tox, group_number, g_id.data.data(), nullptr); + } + + auto& group = ngc_hs1_ctx->history[g_id]; + + std::vector message_ids{}; + + if (!group.peers.empty() && group.peers.count(p_key)) { + const auto& peer = group.peers.at(p_key); + auto rit = peer.order.crbegin(); + for (size_t c = 0; c < last_msg_id_count && rit != peer.order.crend(); c++, rit++) { + message_ids.push_back(*rit); + } + } + + // - 1 byte packet id + // 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 + // - ] + //std::array pkg; + std::vector pkg; + pkg.resize(1+TOX_GROUP_PEER_PUBLIC_KEY_SIZE+1+sizeof(uint32_t)*message_ids.size()); + + pkg[0] = HS_RESPONSE_LAST_IDS; + + std::copy(p_key.data.begin(), p_key.data.end(), pkg.begin()+1); + + pkg[1+TOX_GROUP_PEER_PUBLIC_KEY_SIZE] = message_ids.size(); + + for (size_t i = 0; i < message_ids.size(); i++) { + uint8_t* tmp_ptr = reinterpret_cast(message_ids.data()+i); + // HACK: little endian + std::copy(tmp_ptr, tmp_ptr+sizeof(uint32_t), pkg.begin()+1+TOX_GROUP_PEER_PUBLIC_KEY_SIZE+1+i*sizeof(uint32_t)); + } + + tox_group_send_custom_private_packet(tox, group_number, peer_number, true, pkg.data(), pkg.size(), nullptr); +} + +static void _handle_HS_RESPONSE_LAST_IDS( + Tox* tox, + NGC_HS1* ngc_hs1_ctx, + + uint32_t group_number, + uint32_t peer_number, + + const uint8_t *data, + size_t length +) { + size_t curser = 0; + + _PeerID 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()); + curser += p_key.data.size(); + + // TODO: did we ask? + + _HS1_HAVE(1, fprintf(stderr, "packet too small, missing count\n"); return) + uint8_t last_msg_id_count = data[curser++]; + + fprintf(stderr, "got response with last %u ids\n", last_msg_id_count); } #undef _HS1_HAVE