From 841004e6a4f8ba43587f9f7987f647aa606605ce Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Fri, 2 Oct 2026 10:31:02 -0500 Subject: [PATCH] fix(inventory): an inventory group holds at most 1000 LOTs, as the client LWOInventoryComponent_Common::msgUpdateInventoryGroupContents (0x00ce1f50) ignores an ADD to an unlocked group that already holds 1000 LOTs. The server had no cap, so a modified client could grow the charxml without limit. Co-Authored-By: Claude Opus 5.5 --- dGame/dComponents/InventoryComponent.cpp | 2 ++ dGame/dComponents/InventoryComponent.h | 1 + tests/dGameTests/dComponentsTests/InventoryGroupTests.cpp | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 8075579c7..a2798068c 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -2021,6 +2021,8 @@ void InventoryComponent::UpdateGroup(const GroupUpdate& groupUpdate) { break; } case GroupUpdateCommand::ADD_LOT: { + // msgUpdateInventoryGroupContents (0x00ce1f50): a group holds at most 1000 LOTs + if (groupItr->lots.size() >= MaximumGroupLotCount) break; groupItr->lots.insert(groupUpdate.lot); break; } diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index b9e1c107a..d7d7e1832 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -101,6 +101,7 @@ public: static constexpr uint32_t MaximumGroupCount = 50; static constexpr size_t MaximumGroupNameLength = 64; // UTF-16 characters + static constexpr size_t MaximumGroupLotCount = 1000; static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY; diff --git a/tests/dGameTests/dComponentsTests/InventoryGroupTests.cpp b/tests/dGameTests/dComponentsTests/InventoryGroupTests.cpp index c697950d0..e9a8376c6 100644 --- a/tests/dGameTests/dComponentsTests/InventoryGroupTests.cpp +++ b/tests/dGameTests/dComponentsTests/InventoryGroupTests.cpp @@ -88,3 +88,11 @@ TEST_F(InventoryGroupTests, ClearEmptiesAGroup) { ASSERT_EQ(Groups().size(), 1u); EXPECT_TRUE(Groups()[0].lots.empty()); } + +TEST_F(InventoryGroupTests, AGroupHoldsAtMost1000Lots) { + Group("ADD", "user_group1", u"bricks"); + for (LOT lot = 1; lot <= 1001; lot++) Contents("ADD", "user_group1", lot); + + EXPECT_EQ(Groups()[0].lots.size(), 1000u); + EXPECT_FALSE(Groups()[0].lots.contains(1001)); +}