From e3a75a689ee531c2d84dc5a44b96388be4f31759 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 27 Sep 2026 08:10:25 -0500 Subject: [PATCH] fix(wire): send NotifyNotEnoughInvSpace with its own message ID WIRE FIX. DLU sent NotifyNotEnoughInvSpace with the ID of VehicleNotifyFinishedRace (1396). The 1.10.64 client registers it as NOTIFY_NOT_ENOUGH_INV_SPACE (1516, 0x00545c90) and reads freeSlotsNeeded followed by the optional inventoryType (0x00d8b850), which is what the payload already was. Only the message ID changes. Co-Authored-By: Claude Opus 5.5 --- dGame/dGameMessages/InventoryMessages.h | 8 ++++---- docs/PacketArchitecture.md | 2 +- .../dGameMessagesTests/InventoryMessagesTests.cpp | 11 ++++++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dGame/dGameMessages/InventoryMessages.h b/dGame/dGameMessages/InventoryMessages.h index 8e3b78af2..a76e8867e 100644 --- a/dGame/dGameMessages/InventoryMessages.h +++ b/dGame/dGameMessages/InventoryMessages.h @@ -187,11 +187,11 @@ namespace GameMessages { LWOOBJID startObjectID{ LWOOBJID_EMPTY }; // optional }; - // Server -> client. DLU sends this with the message ID of VehicleNotifyFinishedRace, not - // NOTIFY_NOT_ENOUGH_INV_SPACE; kept as it has always been sent (see docs/PacketArchitecture.md: wire fixes - // are separate changes). + // Server -> client. WIRE FIX: DLU used to send this with the ID of VehicleNotifyFinishedRace (1396); the client + // registers it as NOTIFY_NOT_ENOUGH_INV_SPACE (1516, msgNotifyNotEnoughInvSpace::GetMsgID @ 00545c90 in 1.10.64) + // and reads freeSlotsNeeded then the optional inventoryType (00d8b850). struct NotifyNotEnoughInvSpace : public NetGameMsg { - NotifyNotEnoughInvSpace() : NetGameMsg(MessageType::Game::VEHICLE_NOTIFY_FINISHED_RACE) {} + NotifyNotEnoughInvSpace() : NetGameMsg(MessageType::Game::NOTIFY_NOT_ENOUGH_INV_SPACE) {} void Serialize(RakNet::BitStream& bitStream) const override; bool Deserialize(RakNet::BitStream& bitStream) override; diff --git a/docs/PacketArchitecture.md b/docs/PacketArchitecture.md index 5c0f9c099..c69fb1c87 100644 --- a/docs/PacketArchitecture.md +++ b/docs/PacketArchitecture.md @@ -309,7 +309,7 @@ the 1.10.64 client. | `PlaceModelResponse` | Fixed (wire fix, see docs/BuildWorkflow.md): used to write a 4-byte `response` where the client expects the rotation. | The client reads a 16-byte w, x, y, z quaternion when the rotation isn't identity (`0x00dc0170`); a live server echoed the rotation the client placed the model with. | | `NotifyPetTamingPuzzleSelected` | Written as the client's `Serialize` (`0x00db6880`) writes it. | The client's own `Deserialize` (`0x00e3a7c0`) reads an extra `u32` its `Serialize` never writes. | | `SetBuildModeConfirmed` | Always sends the default flags. | The client has non-default flag fields. | -| `NotifyNotEnoughInvSpace` | Sent with message ID `VEHICLE_NOTIFY_FINISHED_RACE` (1396). | Its ID is `NOTIFY_NOT_ENOUGH_INV_SPACE` (1516). | +| `NotifyNotEnoughInvSpace` | Fixed (wire fix): used to be sent with message ID `VEHICLE_NOTIFY_FINISHED_RACE` (1396). | Its ID is `NOTIFY_NOT_ENOUGH_INV_SPACE` (1516, `0x00545c90`); payload read at `0x00d8b850`. | | `MoveInventoryBatch` | Now follows the client layout. | | | `UnEquipInventory` | The trailing optional `replacementObjectID` is never read. | The client can send it. | | `SetStatusImmunity` | Writes the flags in DLU's order. | The client reads DOT, ImaginationGain, ImaginationLoss, Interrupt, Knockback, PullToPoint, QuickbuildInterrupt, Speed, BasicAttack (`0x00d8f140`). | diff --git a/tests/dGameTests/dGameMessagesTests/InventoryMessagesTests.cpp b/tests/dGameTests/dGameMessagesTests/InventoryMessagesTests.cpp index 878c45819..8f490b852 100644 --- a/tests/dGameTests/dGameMessagesTests/InventoryMessagesTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/InventoryMessagesTests.cpp @@ -202,7 +202,16 @@ TEST_F(InventoryMessagesTests, SmallMessagesMatchLegacy) { msg.target = target; msg.freeSlotsNeeded = slots; msg.inventoryType = type; - ExpectSameAsLegacy([&](const SystemAddress& a) { LegacyGameMessages::SendNotifyNotEnoughInvSpace(target, slots, type, a); }, msg); + // WIRE FIX: the legacy bytes carry VEHICLE_NOTIFY_FINISHED_RACE (1396) as the message ID; everything + // else is unchanged, so compare against them with the ID (bytes 16-17, after the header and object ID) + // swapped for NOTIFY_NOT_ENOUGH_INV_SPACE (1516). + const auto legacy = Capture([&] { LegacyGameMessages::SendNotifyNotEnoughInvSpace(target, slots, type, ClientAddress()); }); + ASSERT_FALSE(legacy.empty()); + auto expected = FromCapture(legacy[0]); + ASSERT_EQ(expected.bytes[16] | (expected.bytes[17] << 8), 1396); + expected.bytes[16] = 1516 & 0xFF; + expected.bytes[17] = 1516 >> 8; + EXPECT_PACKET_EQ(expected, StructPacket(msg)); const auto copy = RoundTrip(msg); EXPECT_EQ(copy.freeSlotsNeeded, slots); EXPECT_EQ(copy.inventoryType, type);