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 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-27 08:10:25 -05:00
parent 3dd4ebf853
commit e3a75a689e
3 changed files with 15 additions and 6 deletions

View File

@@ -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;

View File

@@ -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`). |

View File

@@ -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);