Botcraft 1.21.4
Loading...
Searching...
No Matches
ClientboundPlayerInfoPacket.hpp
Go to the documentation of this file.
1#if PROTOCOL_VERSION < 761 /* < 1.19.3 */
2#pragma once
3
4#include <string>
5#include <map>
6
11
12namespace ProtocolCraft
13{
14 enum class PlayerInfoAction
15 {
16 AddPlayer = 0,
18 UpdateLatency = 2,
20 RemovePlayer = 4
21 };
22
23 class ClientboundPlayerInfoPacket : public BaseMessage<ClientboundPlayerInfoPacket>
24 {
25 public:
26 static constexpr std::string_view packet_name = "Player Info";
27
28 private:
29 std::map<UUID, PlayerUpdate> ReadEntries(ReadIterator& iter, size_t& length) const
30 {
31 std::map<UUID, PlayerUpdate> entries;
32 switch (GetAction())
33 {
34 case PlayerInfoAction::AddPlayer:
35 entries = ReadData<std::map<UUID, PlayerUpdate>>(iter, length);
36 break;
37 case PlayerInfoAction::UpdateGameMode:
38 {
39 const int map_size = ReadData<VarInt>(iter, length);
40 for (int i = 0; i < map_size; ++i)
41 {
42 const UUID uuid = ReadData<UUID>(iter, length);
43 const int game_mode = ReadData<VarInt>(iter, length);
44 entries[uuid].SetGameMode(game_mode);
45 }
46 break;
47 }
48 case PlayerInfoAction::UpdateLatency:
49 {
50 const int map_size = ReadData<VarInt>(iter, length);
51 for (int i = 0; i < map_size; ++i)
52 {
53 const UUID uuid = ReadData<UUID>(iter, length);
54 const int latency = ReadData<VarInt>(iter, length);
55 entries[uuid].SetLatency(latency);
56 }
57 break;
58 }
59 case PlayerInfoAction::UpdateDisplayName:
60 {
61 const int map_size = ReadData<VarInt>(iter, length);
62 for (int i = 0; i < map_size; ++i)
63 {
64 const UUID uuid = ReadData<UUID>(iter, length);
65 const std::optional<Chat> display_name = ReadData<std::optional<Chat>>(iter, length);
66 entries[uuid].SetDisplayName(display_name);
67 }
68 break;
69 }
70 case PlayerInfoAction::RemovePlayer:
71 {
72 const int map_size = ReadData<VarInt>(iter, length);
73 for (int i = 0; i < map_size; ++i)
74 {
75 const UUID uuid = ReadData<UUID>(iter, length);
76 entries[uuid] = PlayerUpdate();
77 }
78 break;
79 }
80 default:
81 break;
82 }
83 return entries;
84 }
85
86 void WriteEntries(const std::map<UUID, PlayerUpdate>& entries, WriteContainer& container) const
87 {
88 switch (GetAction())
89 {
90 case PlayerInfoAction::AddPlayer:
91 WriteData<std::map<UUID, PlayerUpdate>>(entries, container);
92 break;
93 case PlayerInfoAction::UpdateGameMode:
94 WriteData<VarInt>(static_cast<int>(entries.size()), container);
95 for (const auto& [uuid, player_update] : entries)
96 {
97 WriteData<UUID>(uuid, container);
98 WriteData<VarInt>(player_update.GetGameMode(), container);
99 }
100 break;
101 case PlayerInfoAction::UpdateLatency:
102 WriteData<VarInt>(static_cast<int>(entries.size()), container);
103 for (const auto& [uuid, player_update] : entries)
104 {
105 WriteData<UUID>(uuid, container);
106 WriteData<VarInt>(player_update.GetLatency(), container);
107 }
108 break;
109 case PlayerInfoAction::UpdateDisplayName:
110 WriteData<VarInt>(static_cast<int>(entries.size()), container);
111 for (const auto& [uuid, player_update] : entries)
112 {
113 WriteData<UUID>(uuid, container);
114 WriteData<std::optional<Chat>>(player_update.GetDisplayName(), container);
115 }
116 break;
117 case PlayerInfoAction::RemovePlayer:
118 WriteData<VarInt>(static_cast<int>(entries.size()), container);
119 for (const auto& [uuid, player_update] : entries)
120 {
121 WriteData<UUID>(uuid, container);
122 }
123 break;
124 default:
125 break;
126 }
127 }
128
129 std::optional<Json::Value> SerializeEntries(const std::map<UUID, PlayerUpdate>& entries) const
130 {
131 Json::Array output;
132 switch (GetAction())
133 {
134 case PlayerInfoAction::AddPlayer:
135 for (const auto& p : entries)
136 {
137 output.push_back({ {"uuid", p.first}, {"player_info", p.second} });
138 }
139 break;
140 case PlayerInfoAction::UpdateGameMode:
141 for (const auto& p : entries)
142 {
143 output.push_back({ {"uuid", p.first}, {"game_mode", p.second.GetGameMode()} });
144 }
145 break;
146 case PlayerInfoAction::UpdateLatency:
147 for (const auto& p : entries)
148 {
149 output.push_back({ {"uuid", p.first}, {"latency", p.second.GetLatency()} });
150 }
151 break;
152 case PlayerInfoAction::UpdateDisplayName:
153 for (const auto& p : entries)
154 {
155 Json::Value entry;
156 entry["uuid"] = p.first;
157 if (p.second.GetDisplayName().has_value())
158 {
159 entry["display_name"] = p.second.GetDisplayName().value().Serialize();
160 }
161 output.push_back(entry);
162 }
163 break;
164 case PlayerInfoAction::RemovePlayer:
165 for (const auto& p : entries)
166 {
167 output.push_back(p.first);
168 }
169 break;
170 default:
171 break;
172 }
173
174 return output;
175 }
176
177 SERIALIZED_FIELD(Action, Internal::DiffType<PlayerInfoAction, VarInt>);
178 SERIALIZED_FIELD(Entries, Internal::CustomType<std::map<UUID, PlayerUpdate>, &THIS::ReadEntries, &THIS::WriteEntries, &THIS::SerializeEntries>);
179
181 };
182} //ProtocolCraft
183#endif
#define DECLARE_READ_WRITE_SERIALIZE
Define auto serializable utilities and declare ReadImpl, WriteImpl and SerializeImpl virtual function...
#define SERIALIZED_FIELD(Name,...)
std::array< unsigned char, 16 > UUID