diff --git a/build-data/paper.at b/build-data/paper.at index 95ad8b7f6e..da0e0eefe6 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -510,6 +510,8 @@ public net.minecraft.world.inventory.AbstractContainerMenu quickcraftSlots public net.minecraft.world.inventory.AbstractContainerMenu quickcraftStatus public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType public net.minecraft.world.inventory.AbstractContainerMenu resetQuickCraft()V +public net.minecraft.world.inventory.AbstractContainerMenu synchronizeSlotToRemote(ILnet/minecraft/world/item/ItemStack;Ljava/util/function/Supplier;)V +public net.minecraft.world.inventory.AbstractContainerMenu triggerSlotListeners(ILnet/minecraft/world/item/ItemStack;Ljava/util/function/Supplier;)V public net.minecraft.world.inventory.AbstractCraftingMenu craftSlots public net.minecraft.world.inventory.AbstractCraftingMenu resultSlots public net.minecraft.world.inventory.AnvilMenu cost diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index 325bd2461e..a4471a75f0 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -216,7 +216,7 @@ this.tickClientLoadTimeout(); this.gameMode.tick(); this.wardenSpawnTracker.tick(); -@@ -614,9 +_,14 @@ +@@ -614,9 +_,18 @@ this.invulnerableTime--; } @@ -226,6 +226,10 @@ + // Paper start - Configurable container update tick rate + if (--this.containerUpdateDelay <= 0) { + this.containerMenu.broadcastChanges(); ++ // Broadcast equipment and crafting slots when the player is in a container, fixes MC-297508 ++ if (this.containerMenu != this.inventoryMenu) { ++ this.inventoryMenu.broadcastNonContainerSlotChanges(); ++ } + this.containerUpdateDelay = this.level().paperConfig().tickRates.containerUpdate; + } + // Paper end - Configurable container update tick rate diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 5bd2ab9d5b..1f7ee400cd 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -2281,10 +2281,11 @@ for (Entry entry : Int2ObjectMaps.fastIterable(packet.changedSlots())) { this.player.containerMenu.setRemoteSlotUnsafe(entry.getIntKey(), entry.getValue()); -@@ -1824,6 +_,7 @@ +@@ -1824,6 +_,8 @@ } else { this.player.containerMenu.broadcastChanges(); } ++ if (packet.buttonNum() == Inventory.SLOT_OFFHAND && this.player.containerMenu != this.player.inventoryMenu) this.player.containerSynchronizer.sendOffHandSlotChange(); // Paper - update offhand data when the player is clicking in an inventory not their own as the sychronizer does not include offhand slots + if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. } } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/InventoryMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/InventoryMenu.java.patch index add37f1e16..5a34b07001 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/InventoryMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/InventoryMenu.java.patch @@ -15,7 +15,7 @@ this.active = active; this.owner = owner; this.addResultSlot(owner, 154, 28); -@@ -188,4 +_,38 @@ +@@ -188,4 +_,54 @@ protected Player owner() { return this.owner; } @@ -53,4 +53,20 @@ + } + + // CraftBukkit end ++ ++ // Paper start - utility methods for synchronizing slots usually not synchronized by the container menus ++ public void broadcastNonContainerSlotChanges() { ++ for (int i = RESULT_SLOT; i < ARMOR_SLOT_END; i++) { ++ this.broadcastSlotChange(i); ++ } ++ this.broadcastSlotChange(SHIELD_SLOT); ++ } ++ ++ private void broadcastSlotChange(int slot) { ++ ItemStack item = this.slots.get(slot).getItem(); ++ java.util.function.Supplier supplier = com.google.common.base.Suppliers.memoize(item::copy); ++ this.triggerSlotListeners(slot, item, supplier); ++ this.synchronizeSlotToRemote(slot, item, supplier); ++ } ++ // Paper end - utility methods for synchronizing slots usually not synchronized by the container menus }