r-type  0.0.0
R-Type main
Loading...
Searching...
No Matches
HandlerPacket.hpp
Go to the documentation of this file.
1///
2/// @file HandlerPacket.hpp
3/// @brief Network packet handler for RNP protocol
4/// @namespace rnp
5///
6
7#pragma once
8
9#include "Protocol.hpp"
10#include "Serializer.hpp"
11#include <chrono>
12#include <functional>
13#include <memory>
14#include <stdexcept>
15#include <unordered_map>
16
17namespace rnp
18{
19
20 ///
21 /// @brief Packet processing result
22 ///
32
33 ///
34 /// @brief Context information for packet processing
35 ///
37 {
38 std::uint32_t sessionId;
39 std::chrono::steady_clock::time_point receiveTime;
40 std::string senderAddress;
41 std::uint16_t senderPort;
44 };
45
46 ///
47 /// @brief Forward declarations for callback types
48 ///
49 class HandlerPacket;
50
51 using ConnectHandler = std::function<HandlerResult(const PacketConnect &, const PacketContext &)>;
52 using ConnectAcceptHandler = std::function<HandlerResult(const PacketConnectAccept &, const PacketContext &)>;
53 using DisconnectHandler = std::function<HandlerResult(const PacketDisconnect &, const PacketContext &)>;
54 using WorldStateHandler = std::function<HandlerResult(const PacketWorldState &, const PacketContext &)>;
55 using PingHandler = std::function<HandlerResult(const PacketPingPong &, const PacketContext &)>;
56 using PongHandler = std::function<HandlerResult(const PacketPingPong &, const PacketContext &)>;
57 using ErrorHandler = std::function<HandlerResult(const PacketError &, const PacketContext &)>;
58 using EntityEventHandler = std::function<HandlerResult(const std::vector<EventRecord> &, const PacketContext &)>;
59 using AckHandler = std::function<HandlerResult(std::uint32_t sequenceId, const PacketContext &)>;
60
61 // Lobby system handlers
62 using LobbyListRequestHandler = std::function<HandlerResult(const PacketContext &)>;
64 std::function<HandlerResult(const PacketLobbyListResponse &, const PacketContext &)>;
65 using LobbyCreateHandler = std::function<HandlerResult(const PacketLobbyCreate &, const PacketContext &)>;
67 std::function<HandlerResult(const PacketLobbyCreateResponse &, const PacketContext &)>;
68 using LobbyJoinHandler = std::function<HandlerResult(const PacketLobbyJoin &, const PacketContext &)>;
70 std::function<HandlerResult(const PacketLobbyJoinResponse &, const PacketContext &)>;
71 using LobbyLeaveHandler = std::function<HandlerResult(const PacketContext &)>;
72 using LobbyUpdateHandler = std::function<HandlerResult(const PacketLobbyUpdate &, const PacketContext &)>;
73 using GameStartHandler = std::function<HandlerResult(const PacketGameStart &, const PacketContext &)>;
75
76 ///
77 /// @brief Statistics for packet handling
78 ///
80 {
81 std::uint64_t totalPacketsReceived = 0;
82 std::uint64_t totalPacketsProcessed = 0;
83 std::uint64_t totalPacketsDropped = 0;
84 std::uint64_t totalBytesReceived = 0;
85 std::unordered_map<PacketType, std::uint64_t> packetTypeCount;
86 std::unordered_map<HandlerResult, std::uint64_t> resultCount;
87 };
88
89 ///
90 /// @brief Main packet handler class
91 ///
93 {
94 private:
95 // Handler callbacks
105
106 // Lobby system handlers
117
118 // Statistics
120
121 // Rate limiting (simple token bucket per session)
122 std::unordered_map<std::uint32_t, std::chrono::steady_clock::time_point> lastPacketTime_;
123 std::chrono::milliseconds rateLimitInterval_{10}; // 10ms minimum between packets
124
125 ///
126 /// @brief Check rate limiting for a session
127 /// @param sessionId Session to check
128 /// @param currentTime Current time
129 /// @return True if packet should be rate limited
130 ///
131 bool isRateLimited(std::uint32_t sessionId, const std::chrono::steady_clock::time_point &currentTime)
132 {
133 auto it = lastPacketTime_.find(sessionId);
134 if (it == lastPacketTime_.end())
135 {
136 lastPacketTime_[sessionId] = currentTime;
137 return false;
138 }
139
140 auto timeSinceLastPacket = currentTime - it->second;
141 if (timeSinceLastPacket < rateLimitInterval_)
142 {
143 return true;
144 }
145
146 it->second = currentTime;
147 return false;
148 }
149
150 ///
151 /// @brief Update statistics
152 /// @param packetType Type of packet processed
153 /// @param result Processing result
154 /// @param bytesReceived Number of bytes in the packet
155 ///
156 void updateStats(PacketType packetType, HandlerResult result, std::size_t bytesReceived)
157 {
159 stats_.totalBytesReceived += bytesReceived;
160 stats_.packetTypeCount[packetType]++;
161 stats_.resultCount[result]++;
162
163 if (result == HandlerResult::SUCCESS)
164 {
166 }
167 else
168 {
170 }
171 }
172
173 ///
174 /// @brief Parse and handle ENTITY_EVENT packet
175 /// @param serializer Serializer containing the packet data
176 /// @param payloadSize Size of the payload
177 /// @return Vector of event records
178 ///
179 std::vector<EventRecord> parseEntityEvents(Serializer &serializer, std::size_t payloadSize)
180 {
181 std::vector<EventRecord> events;
182 std::size_t bytesRead = 0;
183
184 while (bytesRead < payloadSize)
185 {
186 EventRecord event;
187 event.type = static_cast<EventType>(serializer.readByte());
188 event.entityId = serializer.readUInt32();
189
190 std::uint16_t dataLength = serializer.readUInt16();
191 bytesRead += 7; // 1 + 4 + 2 bytes for type, entityId, dataLength
192
193 if (dataLength > 0)
194 {
195 event.data.resize(dataLength);
196 serializer.readBytes(event.data.data(), dataLength);
197 bytesRead += dataLength;
198 }
199
200 events.push_back(std::move(event));
201 }
202
203 return events;
204 }
205
206 public:
207 ///
208 /// @brief Constructor
209 ///
210 HandlerPacket() = default;
211
212 ///
213 /// @brief Destructor
214 ///
215 ~HandlerPacket() = default;
216
217 // Delete copy constructor and assignment operator
218 HandlerPacket(const HandlerPacket &) = delete;
220
221 ///
222 /// @brief Set rate limiting interval
223 /// @param interval Minimum time between packets per session
224 ///
225 void setRateLimitInterval(std::chrono::milliseconds interval) { rateLimitInterval_ = interval; }
226
227 ///
228 /// @brief Register CONNECT packet handler
229 /// @param handler Callback function for CONNECT packets
230 ///
231 void onConnect(ConnectHandler handler) { connectHandler_ = std::move(handler); }
232
233 ///
234 /// @brief Register CONNECT_ACCEPT packet handler
235 /// @param handler Callback function for CONNECT_ACCEPT packets
236 ///
237 void onConnectAccept(ConnectAcceptHandler handler) { connectAcceptHandler_ = std::move(handler); }
238
239 ///
240 /// @brief Register DISCONNECT packet handler
241 /// @param handler Callback function for DISCONNECT packets
242 ///
243 void onDisconnect(DisconnectHandler handler) { disconnectHandler_ = std::move(handler); }
244
245 ///
246 /// @brief Register WORLD_STATE packet handler
247 /// @param handler Callback function for WORLD_STATE packets
248 ///
249 void onWorldState(WorldStateHandler handler) { worldStateHandler_ = std::move(handler); }
250
251 ///
252 /// @brief Register PING packet handler
253 /// @param handler Callback function for PING packets
254 ///
255 void onPing(PingHandler handler) { pingHandler_ = std::move(handler); }
256
257 ///
258 /// @brief Register PONG packet handler
259 /// @param handler Callback function for PONG packets
260 ///
261 void onPong(PongHandler handler) { pongHandler_ = std::move(handler); }
262
263 ///
264 /// @brief Register ERROR packet handler
265 /// @param handler Callback function for ERROR packets
266 ///
267 void onError(ErrorHandler handler) { errorHandler_ = std::move(handler); }
268
269 ///
270 /// @brief Register ENTITY_EVENT packet handler
271 /// @param handler Callback function for ENTITY_EVENT packets
272 ///
273 void onEntityEvent(EntityEventHandler handler) { entityEventHandler_ = std::move(handler); }
274
275 ///
276 /// @brief Register LOBBY_LIST_REQUEST packet handler
277 /// @param handler Callback function for LOBBY_LIST_REQUEST packets
278 ///
280
281 ///
282 /// @brief Register LOBBY_LIST_RESPONSE packet handler
283 /// @param handler Callback function for LOBBY_LIST_RESPONSE packets
284 ///
286 {
287 lobbyListResponseHandler_ = std::move(handler);
288 }
289
290 ///
291 /// @brief Register LOBBY_CREATE packet handler
292 /// @param handler Callback function for LOBBY_CREATE packets
293 ///
294 void onLobbyCreate(LobbyCreateHandler handler) { lobbyCreateHandler_ = std::move(handler); }
295
296 ///
297 /// @brief Register LOBBY_CREATE_RESPONSE packet handler
298 /// @param handler Callback function for LOBBY_CREATE_RESPONSE packets
299 ///
301 {
302 lobbyCreateResponseHandler_ = std::move(handler);
303 }
304
305 ///
306 /// @brief Register LOBBY_JOIN packet handler
307 /// @param handler Callback function for LOBBY_JOIN packets
308 ///
309 void onLobbyJoin(LobbyJoinHandler handler) { lobbyJoinHandler_ = std::move(handler); }
310
311 ///
312 /// @brief Register LOBBY_JOIN_RESPONSE packet handler
313 /// @param handler Callback function for LOBBY_JOIN_RESPONSE packets
314 ///
316 {
317 lobbyJoinResponseHandler_ = std::move(handler);
318 }
319
320 ///
321 /// @brief Register LOBBY_LEAVE packet handler
322 /// @param handler Callback function for LOBBY_LEAVE packets
323 ///
324 void onLobbyLeave(LobbyLeaveHandler handler) { lobbyLeaveHandler_ = std::move(handler); }
325
326 ///
327 /// @brief Register LOBBY_UPDATE packet handler
328 /// @param handler Callback function for LOBBY_UPDATE packets
329 ///
330 void onLobbyUpdate(LobbyUpdateHandler handler) { lobbyUpdateHandler_ = std::move(handler); }
331
332 ///
333 /// @brief Register GAME_START packet handler
334 /// @param handler Callback function for GAME_START packets
335 ///
336 void onGameStart(GameStartHandler handler) { gameStartHandler_ = std::move(handler); }
337
338 ///
339 /// @brief Register START_GAME_REQUEST packet handler
340 /// @param handler Callback function for START_GAME_REQUEST packets
341 ///
343
344 ///
345 /// @brief Process a received packet
346 /// @param data Raw packet data
347 /// @param context Packet context information
348 /// @return Processing result
349 ///
350 HandlerResult processPacket(const std::vector<std::uint8_t> &data, const PacketContext &context)
351 {
352 // PacketHeader serialized size: 1 (type) + 2 (length) + 4 (sessionId) = 7 bytes
353 constexpr std::size_t PACKET_HEADER_SIZE = 7;
354 if (data.size() < PACKET_HEADER_SIZE)
355 {
356 updateStats(static_cast<PacketType>(0), HandlerResult::INVALID_PACKET, data.size());
358 }
359
360 // Check rate limiting
361 if (isRateLimited(context.sessionId, context.receiveTime))
362 {
363 updateStats(static_cast<PacketType>(0), HandlerResult::RATE_LIMITED, data.size());
365 }
366
367 try
368 {
369 Serializer serializer(data);
370 PacketHeader header = serializer.deserializeHeader();
371
372 // Validate header
373 if (header.length > MAX_PAYLOAD || header.sessionId != context.sessionId)
374 {
375 updateStats(static_cast<PacketType>(header.type), HandlerResult::INVALID_PACKET, data.size());
377 }
378
379 PacketType packetType = static_cast<PacketType>(header.type);
381
382 switch (packetType)
383 {
385 if (connectHandler_)
386 {
387 auto packet = serializer.deserializeConnect();
388 result = connectHandler_(packet, context);
389 }
390 break;
391
394 {
395 auto packet = serializer.deserializeConnectAccept();
396 result = connectAcceptHandler_(packet, context);
397 }
398 break;
399
402 {
403 auto packet = serializer.deserializeDisconnect();
404 result = disconnectHandler_(packet, context);
405 }
406 break;
407
410 {
411 auto packet = serializer.deserializeWorldState();
412 result = worldStateHandler_(packet, context);
413 }
414 break;
415
416 case PacketType::PING:
417 if (pingHandler_)
418 {
419 auto packet = serializer.deserializePingPong();
420 result = pingHandler_(packet, context);
421 }
422 break;
423
424 case PacketType::PONG:
425 if (pongHandler_)
426 {
427 auto packet = serializer.deserializePingPong();
428 result = pongHandler_(packet, context);
429 }
430 break;
431
433 if (errorHandler_)
434 {
435 auto packet = serializer.deserializeError();
436 result = errorHandler_(packet, context);
437 }
438 break;
439
442 {
443 auto events = parseEntityEvents(serializer, header.length);
444 result = entityEventHandler_(events, context);
445 }
446 break;
447
450 {
451 result = lobbyListRequestHandler_(context);
452 }
453 break;
454
457 {
458 auto packet = serializer.deserializeLobbyListResponse();
459 result = lobbyListResponseHandler_(packet, context);
460 }
461 break;
462
465 {
466 auto packet = serializer.deserializeLobbyCreate();
467 result = lobbyCreateHandler_(packet, context);
468 }
469 break;
470
473 {
474 auto packet = serializer.deserializeLobbyCreateResponse();
475 result = lobbyCreateResponseHandler_(packet, context);
476 }
477 break;
478
481 {
482 auto packet = serializer.deserializeLobbyJoin();
483 result = lobbyJoinHandler_(packet, context);
484 }
485 break;
486
489 {
490 auto packet = serializer.deserializeLobbyJoinResponse();
491 result = lobbyJoinResponseHandler_(packet, context);
492 }
493 break;
494
497 {
498 result = lobbyLeaveHandler_(context);
499 }
500 break;
501
504 {
505 auto packet = serializer.deserializeLobbyUpdate();
506 result = lobbyUpdateHandler_(packet, context);
507 }
508 break;
509
512 {
513 auto packet = serializer.deserializeGameStart();
514 result = gameStartHandler_(packet, context);
515 }
516 break;
517
520 {
521 auto packet = serializer.deserializeStartGameRequest();
522 result = startGameRequestHandler_(packet, context);
523 }
524 break;
525
526 default:
528 break;
529 }
530
531 updateStats(packetType, result, data.size());
532 return result;
533 }
534 catch (const std::exception &)
535 {
536 updateStats(static_cast<PacketType>(0), HandlerResult::PROCESSING_ERROR, data.size());
538 }
539 }
540
541 ///
542 /// @brief Get handler statistics
543 /// @return Current statistics
544 ///
545 const HandlerStats &getStats() const { return stats_; }
546
547 ///
548 /// @brief Reset statistics
549 ///
551
552 ///
553 /// @brief Clear rate limiting data for a session
554 /// @param sessionId Session to clear
555 ///
556 void clearSession(std::uint32_t sessionId) { lastPacketTime_.erase(sessionId); }
557
558 ///
559 /// @brief Clear all rate limiting data
560 ///
562 };
563
564} // namespace rnp
This file contains the network protocol.
Network packet serializer for RNP protocol.
Main packet handler class.
std::unordered_map< std::uint32_t, std::chrono::steady_clock::time_point > lastPacketTime_
GameStartHandler gameStartHandler_
void onLobbyListResponse(LobbyListResponseHandler handler)
Register LOBBY_LIST_RESPONSE packet handler.
void onPing(PingHandler handler)
Register PING packet handler.
void onPong(PongHandler handler)
Register PONG packet handler.
void onLobbyJoin(LobbyJoinHandler handler)
Register LOBBY_JOIN packet handler.
void onLobbyLeave(LobbyLeaveHandler handler)
Register LOBBY_LEAVE packet handler.
LobbyListRequestHandler lobbyListRequestHandler_
void resetStats()
Reset statistics.
LobbyLeaveHandler lobbyLeaveHandler_
HandlerResult processPacket(const std::vector< std::uint8_t > &data, const PacketContext &context)
Process a received packet.
void onLobbyListRequest(LobbyListRequestHandler handler)
Register LOBBY_LIST_REQUEST packet handler.
void setRateLimitInterval(std::chrono::milliseconds interval)
Set rate limiting interval.
EntityEventHandler entityEventHandler_
void onConnect(ConnectHandler handler)
Register CONNECT packet handler.
LobbyCreateResponseHandler lobbyCreateResponseHandler_
void clearAllSessions()
Clear all rate limiting data.
LobbyCreateHandler lobbyCreateHandler_
DisconnectHandler disconnectHandler_
ErrorHandler errorHandler_
LobbyJoinResponseHandler lobbyJoinResponseHandler_
void onWorldState(WorldStateHandler handler)
Register WORLD_STATE packet handler.
void onConnectAccept(ConnectAcceptHandler handler)
Register CONNECT_ACCEPT packet handler.
HandlerPacket()=default
Constructor.
LobbyJoinHandler lobbyJoinHandler_
const HandlerStats & getStats() const
Get handler statistics.
LobbyListResponseHandler lobbyListResponseHandler_
void onStartGameRequest(StartGameRequestHandler handler)
Register START_GAME_REQUEST packet handler.
void onError(ErrorHandler handler)
Register ERROR packet handler.
WorldStateHandler worldStateHandler_
HandlerPacket(const HandlerPacket &)=delete
void onLobbyCreate(LobbyCreateHandler handler)
Register LOBBY_CREATE packet handler.
bool isRateLimited(std::uint32_t sessionId, const std::chrono::steady_clock::time_point &currentTime)
Check rate limiting for a session.
void onLobbyUpdate(LobbyUpdateHandler handler)
Register LOBBY_UPDATE packet handler.
void onEntityEvent(EntityEventHandler handler)
Register ENTITY_EVENT packet handler.
void onLobbyJoinResponse(LobbyJoinResponseHandler handler)
Register LOBBY_JOIN_RESPONSE packet handler.
void updateStats(PacketType packetType, HandlerResult result, std::size_t bytesReceived)
Update statistics.
HandlerPacket & operator=(const HandlerPacket &)=delete
ConnectAcceptHandler connectAcceptHandler_
std::vector< EventRecord > parseEntityEvents(Serializer &serializer, std::size_t payloadSize)
Parse and handle ENTITY_EVENT packet.
void onLobbyCreateResponse(LobbyCreateResponseHandler handler)
Register LOBBY_CREATE_RESPONSE packet handler.
~HandlerPacket()=default
Destructor.
LobbyUpdateHandler lobbyUpdateHandler_
std::chrono::milliseconds rateLimitInterval_
StartGameRequestHandler startGameRequestHandler_
void onGameStart(GameStartHandler handler)
Register GAME_START packet handler.
void onDisconnect(DisconnectHandler handler)
Register DISCONNECT packet handler.
void clearSession(std::uint32_t sessionId)
Clear rate limiting data for a session.
ConnectHandler connectHandler_
Binary serializer for RNP protocol packets.
PacketStartGameRequest deserializeStartGameRequest()
Deserialize START_GAME_REQUEST packet.
PacketLobbyJoinResponse deserializeLobbyJoinResponse()
Deserialize LOBBY_JOIN_RESPONSE packet.
PacketHeader deserializeHeader()
Deserialize packet header.
PacketConnect deserializeConnect()
Deserialize CONNECT packet.
void readBytes(void *data, std::size_t size)
Read raw bytes.
PacketLobbyUpdate deserializeLobbyUpdate()
Deserialize LOBBY_UPDATE packet.
PacketError deserializeError()
Deserialize ERROR packet.
PacketLobbyJoin deserializeLobbyJoin()
Deserialize LOBBY_JOIN packet.
PacketConnectAccept deserializeConnectAccept()
Deserialize CONNECT_ACCEPT packet.
PacketLobbyCreate deserializeLobbyCreate()
Deserialize LOBBY_CREATE packet.
PacketGameStart deserializeGameStart()
Deserialize GAME_START packet.
std::uint8_t readByte()
Read a single byte.
PacketLobbyListResponse deserializeLobbyListResponse()
Deserialize LOBBY_LIST_RESPONSE packet.
PacketPingPong deserializePingPong()
Deserialize PING/PONG packet.
PacketWorldState deserializeWorldState()
Deserialize WORLD_STATE packet.
std::uint16_t readUInt16()
Read a 16-bit integer (network byte order)
std::uint32_t readUInt32()
Read a 32-bit integer (network byte order)
PacketDisconnect deserializeDisconnect()
Deserialize DISCONNECT packet.
PacketLobbyCreateResponse deserializeLobbyCreateResponse()
Deserialize LOBBY_CREATE_RESPONSE packet.
EventType
Event types for ENTITY_EVENT packets.
Definition Protocol.hpp:92
HandlerResult
Packet processing result.
std::function< HandlerResult(const PacketLobbyCreateResponse &, const PacketContext &)> LobbyCreateResponseHandler
std::function< HandlerResult(const PacketConnect &, const PacketContext &)> ConnectHandler
std::function< HandlerResult(const PacketLobbyCreate &, const PacketContext &)> LobbyCreateHandler
std::function< HandlerResult(const std::vector< EventRecord > &, const PacketContext &)> EntityEventHandler
std::function< HandlerResult(const PacketWorldState &, const PacketContext &)> WorldStateHandler
std::function< HandlerResult(const PacketGameStart &, const PacketContext &)> GameStartHandler
std::function< HandlerResult(const PacketPingPong &, const PacketContext &)> PingHandler
std::function< HandlerResult(const PacketContext &)> LobbyLeaveHandler
PacketType
Packet types according to RNP specification.
Definition Protocol.hpp:24
std::function< HandlerResult(const PacketConnectAccept &, const PacketContext &)> ConnectAcceptHandler
std::function< HandlerResult(const PacketPingPong &, const PacketContext &)> PongHandler
std::function< HandlerResult(std::uint32_t sequenceId, const PacketContext &)> AckHandler
std::function< HandlerResult(const PacketLobbyJoin &, const PacketContext &)> LobbyJoinHandler
std::function< HandlerResult(const PacketLobbyListResponse &, const PacketContext &)> LobbyListResponseHandler
std::function< HandlerResult(const PacketDisconnect &, const PacketContext &)> DisconnectHandler
std::function< HandlerResult(const PacketLobbyJoinResponse &, const PacketContext &)> LobbyJoinResponseHandler
std::function< HandlerResult(const PacketContext &)> LobbyListRequestHandler
std::function< HandlerResult(const PacketLobbyUpdate &, const PacketContext &)> LobbyUpdateHandler
std::function< HandlerResult(const PacketStartGameRequest &, const PacketContext &)> StartGameRequestHandler
std::function< HandlerResult(const PacketError &, const PacketContext &)> ErrorHandler
constexpr std::size_t MAX_PAYLOAD
Definition Protocol.hpp:18
Event record for ENTITY_EVENT packets (TLV format)
Definition Protocol.hpp:117
std::vector< std::uint8_t > data
Definition Protocol.hpp:120
Statistics for packet handling.
std::unordered_map< PacketType, std::uint64_t > packetTypeCount
std::uint64_t totalPacketsDropped
std::unordered_map< HandlerResult, std::uint64_t > resultCount
std::uint64_t totalPacketsReceived
std::uint64_t totalBytesReceived
std::uint64_t totalPacketsProcessed
CONNECT_ACCEPT packet payload.
Definition Protocol.hpp:148
CONNECT packet payload.
Definition Protocol.hpp:138
Context information for packet processing.
std::uint32_t sessionId
std::chrono::steady_clock::time_point receiveTime
std::string senderAddress
std::uint16_t senderPort
DISCONNECT packet payload.
Definition Protocol.hpp:159
ERROR packet payload.
Definition Protocol.hpp:217
GAME_START packet payload.
Definition Protocol.hpp:309
Packet header according to RNP specification (Big Endian) Total size: 7 bytes (1 + 2 + 4)
Definition Protocol.hpp:128
std::uint32_t sessionId
Definition Protocol.hpp:131
std::uint8_t type
Definition Protocol.hpp:129
std::uint16_t length
Definition Protocol.hpp:130
LOBBY_CREATE_RESPONSE packet payload.
Definition Protocol.hpp:272
LOBBY_CREATE packet payload.
Definition Protocol.hpp:261
LOBBY_JOIN_RESPONSE packet payload.
Definition Protocol.hpp:290
LOBBY_JOIN packet payload.
Definition Protocol.hpp:282
LOBBY_LIST_RESPONSE packet payload.
Definition Protocol.hpp:252
LOBBY_UPDATE packet payload.
Definition Protocol.hpp:301
PING/PONG packet payload.
Definition Protocol.hpp:208
START_GAME_REQUEST packet payload (client requests to start game)
Definition Protocol.hpp:317
WORLD_STATE packet payload.
Definition Protocol.hpp:198