refactor: mission, flag and collectible game messages as structs

Converts OfferMission, NotifyMission, NotifyMissionTask, ResetMissions,
NotifyClientFlagChange and NotifyLevelRewards (sent with SendToClient:
the old functions never broadcast) and the received RespondToMission,
MissionDialogueOK, RequestLinkedMission, SetFlag and HasBeenCollected
to NetGameMsgs in MissionMessages.{h,cpp}. Callers are switched,
OfferMission's send-it-twice behaviour moves to MissionOfferComponent,
the received messages are registered in GameMessageHandler's map and
the old functions are deleted. Handlers are copied verbatim. The
byte-equality helper can now compare SendToClient messages.

No wire change and no change in recipients. Verified byte for byte
against a frozen verbatim copy of the old functions over an input grid
(including OfferMission's two packets), received messages compared with
the old handlers' read sequences and every truncated payload rejected,
hand computed golden bytes and round trips. Layouts confirmed against
the 1.10.64 client in Ghidra.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-26 12:44:51 -05:00
parent 9f142c9cc7
commit 55fd5aa8c3
16 changed files with 904 additions and 275 deletions

View File

@@ -32,14 +32,18 @@ namespace GameMessageTestUtils {
return FromBitStream(bitStream);
}
// Sends the same message through the frozen legacy function and through the struct, to one client and as a
// broadcast, and requires identical bytes and the same effective destination.
// How the struct is sent in a comparison: Send (UNASSIGNED broadcasts; legacy functions that did
// "if (UNASSIGNED) SEND_PACKET_BROADCAST; SEND_PACKET;") or SendToClient (legacy functions with only SEND_PACKET).
enum class SendMode { Send, SendToClient };
// Sends the same message through the frozen legacy function and through the struct, to one client and to
// UNASSIGNED_SYSTEM_ADDRESS, and requires identical bytes and the same effective destination.
// legacySend receives the address to send to.
inline void ExpectSameAsLegacy(const std::function<void(const SystemAddress&)>& legacySend, const GameMessages::NetGameMsg& msg) {
inline void ExpectSameAsLegacy(const std::function<void(const SystemAddress&)>& legacySend, const GameMessages::NetGameMsg& msg, SendMode mode = SendMode::Send) {
for (const auto& address : g_Addresses) {
SCOPED_TRACE(address == UNASSIGNED_SYSTEM_ADDRESS ? "broadcast" : "single client");
SCOPED_TRACE(address == UNASSIGNED_SYSTEM_ADDRESS ? "unassigned address" : "single client");
const auto legacyPackets = Capture([&] { legacySend(address); });
const auto newPackets = Capture([&] { msg.Send(address); });
const auto newPackets = Capture([&] { mode == SendMode::Send ? msg.Send(address) : msg.SendToClient(address); });
ASSERT_FALSE(legacyPackets.empty());
ASSERT_EQ(newPackets.size(), 1);