-
Bug
-
Resolution: Unresolved
-
None
-
1.20.4, 24w06a, 1.21, 24w33a
-
None
-
Confirmed
-
Inventory, Networking
-
Normal
-
Platform
External inventory changes (e.g. by picking up items) are not registered on the client if you are in creative mode inventory and are not in the Survival Inventory tab, causing a desync.
Steps to reproduce:
- Fill your hotbar with items.
- Go into the creative mode inventory and go to any tab, but the inventory tab (e.g. the search tab).
- While in the tab, take any other item and throw it onto the ground.
- Wait until you pick it up and observe whether or not the item appears in the inventory.
Expected behavior:
The item is picked up and should show up in the inventory.
Actual behavior:
The item does not appear in the inventory. However, if you try to remove that particular item, e.g. using /clear @s <item>, the server will report that the item indeed was in the inventory.
Code analysis:
public void handleContainerSetSlot(ClientboundContainerSetSlotPacket packet) { // ... boolean conditional = false; // Line 1200 if (minecraft.screen instanceof CreativeModeInventoryScreen x) { // Line 1202 conditional = !x.isInventoryOpen(); // Line 1203 } // 0 means player inventory if (packet.getContainerId() == 0 && InventoryMenu.isHotbarSlot(slotId)) { // ... player.inventoryMenu.setItem(slotId, packet.getStateId(), item); } else if (packet.getContainerId() == player.containerMenu.containerId && (packet.getContainerId() != 0 || !conditional)) { player.containerMenu.setItem(slotId, packet.getStateId(), item); } }
This method is responsible for all of the single slot synchronization on the client side.
Because of it, inventory changes are almost completely ignored if they occur in a non-hotbar slot (first condition) and you are in the creative mode inventory (Line 1202), but not in the "Survival Inventory" tab (Line 1203). (why?)
Potential fix:
Just remove those weird conditions. Why do they even exist in the first place?
public void handleContainerSetSlot(ClientboundContainerSetSlotPacket packet) { // ... if (packet.getContainerId() == 0) { // ... player.inventoryMenu.setItem(slotId, packet.getStateId(), item); } else if (packet.getContainerId() == player.containerMenu.containerId) { player.containerMenu.setItem(slotId, packet.getStateId(), item); } }
Also, because this is a synchronization step, the client should be able to be confident about that particular remote slot, shouldn't it? So please also consider changing this:
public void setItem(int slotId, int stateId, ItemStack item) { getSlot(slotId).set(item); // Line 593 setRemoteSlot(slotId, item); // New line this.stateId = stateId; // Line 594 }
That is the setItem method from above, by the way.
- relates to
-
MC-265640 Moving items before and after switching to the Survival inventory tab desyncs the hotbar
- Open
-
MC-86455 Pick-block creates ghost items in Creative when hotbar is full
- Reopened
-
MC-5415 Creative Mode Item Duplication into hotbar
- Resolved
-
MC-206074 Survival tab of Creative inventory desyncs if changed manually after an external change
- Resolved