Fix inventory items with Count=0 persisting in player inventory

- Fix TryMergeSlot: add count to destination before zeroing source
- Fix ShiftClick: clean up source slot when depleted by partial merges
- Fix OnWindowItems: filter out empty items from server data
- Fix LeftClick/RightClick: remove cursor item when count reaches zero
This commit is contained in:
copilot-swe-agent[bot] 2026-06-05 21:31:05 +00:00 committed by GitHub
parent 913c0f0f72
commit 052042150d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2004,8 +2004,8 @@ namespace MinecraftClient
if (item.Count <= spaceLeft)
{
// Can fit into the stack
item.Count = 0;
curItem.Count += item.Count;
item.Count = 0;
changedSlots.Add(new Tuple<short, Item?>((short)curId, curItem));
changedSlots.Add(new Tuple<short, Item?>((short)slotId, null));
@ -2214,6 +2214,10 @@ namespace MinecraftClient
changedSlots.Add(new Tuple<short, Item?>((short)slotId, inventory.Items[slotId]));
else
changedSlots.Add(new Tuple<short, Item?>((short)slotId, null));
// Clean up cursor item if count reached zero
if (playerInventory.Items.TryGetValue(-1, out Item? cursorAfterLeft) && cursorAfterLeft.IsEmpty)
playerInventory.Items.Remove(-1);
}
else
{
@ -2302,6 +2306,9 @@ namespace MinecraftClient
}
}
}
// Clean up cursor item if count reached zero
if (playerInventory.Items.TryGetValue(-1, out Item? cursorItem) && cursorItem.IsEmpty)
playerInventory.Items.Remove(-1);
if (inventory.Items.ContainsKey(slotId))
changedSlots.Add(new Tuple<short, Item?>((short)slotId, inventory.Items[slotId]));
else
@ -2851,6 +2858,13 @@ namespace MinecraftClient
changedSlots.Add(new Tuple<short, Item?>((short)slotId, inventory.Items[slotId]));
}
}
// Clean up source slot if fully depleted by partial merges
if (item!.Count <= 0 && inventory.Items.ContainsKey(slotId))
{
inventory.Items.Remove(slotId);
changedSlots.Add(new Tuple<short, Item?>((short)slotId, null));
}
}
break;
case WindowActionType.DropItem:
@ -3913,6 +3927,10 @@ namespace MinecraftClient
{
if (inventories.ContainsKey(inventoryID))
{
// Filter out empty items (Count=0 or Air) that some servers may send
foreach (int key in itemList.Where(slot => slot.Value.IsEmpty).Select(slot => slot.Key).ToList())
itemList.Remove(key);
inventories[inventoryID].Items = itemList;
inventories[inventoryID].StateID = stateId;
bool playerInventoryChanged = SyncPlayerInventorySlotsFromWindow(inventories[inventoryID]);