refactor: skill and projectile game messages as structs

Converts the skill messages to NetGameMsgs in SkillMessages.{h,cpp}:
AddSkill and RemoveSkill (SendToClient, as before), EchoStartSkill,
EchoSyncSkill and DoClientProjectileImpact, and the received
SelectSkill, StartSkill, SyncSkill and RequestServerProjectileImpact.
The one-off StartSkill, EchoStartSkill, SyncSkill, EchoSyncSkill,
RequestServerProjectileImpact and DoClientProjectileImpact classes are
deleted; SkillComponent, BehaviorContext and InventoryComponent build
the structs, and the dashboard's message decoder reads them.

The received messages are registered in GameMessageHandler's map and
their switch cases are deleted; the handlers call SkillComponent as
before. The echoes still go to every client except the caster, through
the new NetGameMsg::BroadcastExcept. SelectSkill still accepts any
payload, since the old case read nothing. Handler logic is unchanged
(the SyncSkill case's unused hex dump of the payload is dropped).

No wire change. Verified byte for byte against frozen verbatim copies
of the old classes and functions over an input grid (every optional
field set and unset, empty, short and long behavior streams), received
messages compared with the old classes' read sequences and truncated
payloads rejected, the echo's broadcast-except destination compared
with the old send, hand computed golden bytes, round trips, and a
deliberate mutation made the tests fail. Messages that fail to
deserialize are now dropped instead of being handled half read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-26 19:11:26 -05:00
parent 2711c69e3e
commit 27de0cf268
20 changed files with 1385 additions and 801 deletions

View File

@@ -87,6 +87,10 @@ namespace GameMessages {
// nothing is delivered (RakNet rejects a non-broadcast send without an address).
void SendToClient(const SystemAddress& sysAddr) const;
// Sends the message to every client except excluded (a RakNet broadcast with that address left out).
// Used to echo a client's message to everyone else.
void BroadcastExcept(const SystemAddress& excluded) const;
// Writes the complete client packet (CLIENT/GAME_MSG header, target, msgId, then Serialize()) into bitStream.
// This is exactly what Send(sysAddr) puts on the wire; tests use it to compare bytes without a server.
void WritePacket(RakNet::BitStream& bitStream) const;
@@ -169,9 +173,6 @@ namespace GameMessages {
void SendSetPlayerControlScheme(Entity* entity, eControlScheme controlScheme);
void SendPlayerReachedRespawnCheckpoint(Entity* entity, const NiPoint3& position, const NiQuaternion& rotation);
void SendAddSkill(Entity* entity, TSkillID skillID, BehaviorSlot slotID);
void SendRemoveSkill(Entity* entity, TSkillID skillID);
void SendMatchResponse(Entity* entity, const SystemAddress& sysAddr, int response);
void SendMatchUpdate(Entity* entity, const SystemAddress& sysAddr, std::string data, eMatchUpdate type);