Botcraft 1.21.5
Loading...
Searching...
No Matches
LastSeenMessagesTracker.cpp
Go to the documentation of this file.
1#if PROTOCOL_VERSION > 759 /* > 1.19 */
2
4
5namespace Botcraft
6{
8 {
9#if PROTOCOL_VERSION > 760 /* > 1.19.2 */
10 tail = 0;
11 offset = 0;
12#endif
13 }
14
19
21 {
22 return mutex;
23 }
24
25#if PROTOCOL_VERSION < 761 /* < 1.19.3 */
26 const std::vector<unsigned char>& LastSeenMessagesTracker::GetLastSignature() const
27 {
28 return last_signature_sent;
29 }
30
31 void LastSeenMessagesTracker::SetLastSignature(const std::vector<unsigned char>& last_signature_sent_)
32 {
33 last_signature_sent = last_signature_sent_;
34 }
35
36 void LastSeenMessagesTracker::AddSeenMessage(const std::vector<unsigned char>& signature, const ProtocolCraft::UUID& sender)
37 {
38 std::scoped_lock<std::mutex> lock_messages(mutex);
39
41 entry.SetLastSignature(signature);
42 entry.SetProfileId(sender);
43
44 // Remove old messages from the same player
45 int index = 0;
46 while (index < last_seen.size())
47 {
48 if (last_seen[index].GetProfileId() == sender)
49 {
50 last_seen.erase(last_seen.begin() + index);
51 }
52 else
53 {
54 index += 1;
55 }
56 }
57
58 // Push new header in front
59 last_seen.push_front(entry);
60
61 // Limit the size to 5 messages
62 while (last_seen.size() > 5)
63 {
64 last_seen.pop_back();
65 }
66 }
67
69 {
70 ProtocolCraft::LastSeenMessagesUpdate last_seen_messages_update;
71 last_seen_messages_update.SetLastSeen({ last_seen.begin(), last_seen.begin() + std::min(static_cast<int>(last_seen.size()), 5) });
72 return last_seen_messages_update;
73 }
74#else
76 {
77 std::scoped_lock<std::mutex> lock_messages(mutex);
78 std::pair<std::vector<std::vector<unsigned char>>, ProtocolCraft::LastSeenMessagesUpdate> output;
79 output.second.SetOffset(GetAndResetOffset());
80
81 output.first.reserve(last_seen_signatures.size());
82 std::bitset<20> bitset;
83 for (size_t i = 0; i < last_seen_signatures.size(); ++i)
84 {
85 const size_t index = (tail + i) % last_seen_signatures.size();
86 if (last_seen_signatures[index].empty())
87 {
88 continue;
89 }
90 bitset.set(i, true);
91 output.first.push_back(last_seen_signatures[index]);
92 }
93 output.second.SetAcknowledged(bitset);
94
95#if PROTOCOL_VERSION > 769 /* > 1.21.4 */
96 // Compute the checksum for last seen messages for 1.21.5+
97 int checksum = 1;
98
99 for (const auto& signature : output.first)
100 {
101 int signature_hashcode = 1;
102 for (const unsigned char c : signature)
103 {
104 signature_hashcode = 31 * signature_hashcode + static_cast<int>(c);
105 }
106 checksum = 31 * checksum + signature_hashcode;
107 }
108
109 const unsigned char byte_checksum = static_cast<unsigned char>(checksum);
110 output.second.SetChecksum(byte_checksum == 0 ? 1 : byte_checksum);
111#endif
112
113 return output;
114 }
115
116 void LastSeenMessagesTracker::AddSeenMessage(const std::vector<unsigned char>& signature)
117 {
118 last_seen_signatures[tail] = signature;
119 tail = (tail + 1) % last_seen_signatures.size();
120 offset += 1;
121 }
122
124 {
125 return offset;
126 }
127
129 {
130 const int current_offset = offset;
131 offset = 0;
132 return current_offset;
133 }
134#endif
135}
136#endif
std::array< std::vector< unsigned char >, 20 > last_seen_signatures
Circular buffer to store previously seen message signatures.
void AddSeenMessage(const std::vector< unsigned char > &signature)
std::pair< std::vector< std::vector< unsigned char > >, ProtocolCraft::LastSeenMessagesUpdate > GetLastSeenMessagesUpdate()
Get both a vector of previous messages signatures and the LastSeenMessagesUpdate object.
std::array< unsigned char, 16 > UUID