Keep non-container slots synced when in container view (#12881)

This commit is contained in:
Noah van der Aa
2025-07-26 23:46:30 +02:00
committed by GitHub
parent a57636189a
commit dbc367ba2d
4 changed files with 26 additions and 3 deletions

View File

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

View File

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

View File

@@ -2281,10 +2281,11 @@
for (Entry<HashedStack> 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.
}
}

View File

@@ -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<net.minecraft.world.item.ItemStack> 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
}