From 183683ecc5dcf029cf4b81feed34749d78e4b49b Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 24 Jan 2022 00:09:02 -0800 Subject: [PATCH] Add missing InventoryHolders to inventories --- .../net/minecraft/world/Container.java.patch | 2 +- .../world/SimpleContainer.java.patch | 24 +++++++--- .../AbstractContainerMenu.java.patch | 27 +++++++++--- .../world/inventory/BeaconMenu.java.patch | 2 +- .../inventory/CartographyTableMenu.java.patch | 14 ++++-- .../inventory/ContainerLevelAccess.java.patch | 20 ++++++++- .../inventory/EnchantmentMenu.java.patch | 9 +++- .../world/inventory/GrindstoneMenu.java.patch | 11 ++++- .../inventory/ItemCombinerMenu.java.patch | 44 +++++++++++++++++-- .../world/inventory/LoomMenu.java.patch | 15 +++++-- .../inventory/ResultContainer.java.patch | 17 ++++++- .../inventory/StonecutterMenu.java.patch | 14 ++++-- .../inventory/CraftBlockInventoryHolder.java | 7 +++ 13 files changed, 177 insertions(+), 29 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/Container.java.patch b/paper-server/patches/sources/net/minecraft/world/Container.java.patch index aec1c158f1..cc552af92d 100644 --- a/paper-server/patches/sources/net/minecraft/world/Container.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/Container.java.patch @@ -38,7 +38,7 @@ + + java.util.List getViewers(); + -+ org.bukkit.inventory.InventoryHolder getOwner(); ++ org.bukkit.inventory.@org.jetbrains.annotations.Nullable InventoryHolder getOwner(); // Paper - annotation + + void setMaxStackSize(int size); + diff --git a/paper-server/patches/sources/net/minecraft/world/SimpleContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/SimpleContainer.java.patch index 177f071e31..ff3587753c 100644 --- a/paper-server/patches/sources/net/minecraft/world/SimpleContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/SimpleContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/SimpleContainer.java +++ b/net/minecraft/world/SimpleContainer.java -@@ -14,16 +14,84 @@ +@@ -14,18 +14,98 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -20,7 +20,7 @@ + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; -+ protected org.bukkit.inventory.InventoryHolder bukkitOwner; ++ protected @Nullable org.bukkit.inventory.InventoryHolder bukkitOwner; // Paper - annotation + + public List getContents() { + return this.items; @@ -48,6 +48,11 @@ + } + + public org.bukkit.inventory.InventoryHolder getOwner() { ++ // Paper start - Add missing InventoryHolders ++ if (this.bukkitOwner == null && this.bukkitOwnerCreator != null) { ++ this.bukkitOwner = this.bukkitOwnerCreator.get(); ++ } ++ // Paper end - Add missing InventoryHolders + return this.bukkitOwner; + } @@ -78,12 +83,21 @@ - this.items = NonNullList.withSize(size, ItemStack.EMPTY); + this(size, null); + } -+ ++ // Paper start - Add missing InventoryHolders ++ private @Nullable java.util.function.Supplier bukkitOwnerCreator; ++ public SimpleContainer(java.util.function.Supplier bukkitOwnerCreator, int size) { ++ this(size); ++ this.bukkitOwnerCreator = bukkitOwnerCreator; + } ++ // Paper end - Add missing InventoryHolders + + public SimpleContainer(int i, org.bukkit.inventory.InventoryHolder owner) { + this.bukkitOwner = owner; + // CraftBukkit end + this.size = i; + this.items = NonNullList.withSize(i, ItemStack.EMPTY); - } - ++ } ++ public SimpleContainer(ItemStack... items) { + this.size = items.length; + this.items = NonNullList.of(ItemStack.EMPTY, items); diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch index ca24079af3..2d1f1c42ed 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch @@ -61,26 +61,27 @@ protected AbstractContainerMenu(@Nullable MenuType type, int syncId) { this.carried = ItemStack.EMPTY; this.remoteSlots = NonNullList.create(); -@@ -188,9 +228,19 @@ +@@ -188,10 +228,20 @@ if (this.synchronizer != null) { this.synchronizer.sendInitialData(this, this.remoteSlots, this.remoteCarried, this.remoteDataSlots.toIntArray()); + this.synchronizer.sendOffHandSlotChange(); // Paper - Sync offhand slot in menus; update player's offhand since the offhand slot is not added to the slots for menus but can be changed by swapping from a menu slot } -+ } -+ + } + + // CraftBukkit start + public void broadcastCarriedItem() { + this.remoteCarried = this.getCarried().copy(); + if (this.synchronizer != null) { + this.synchronizer.sendCarriedChange(this, this.remoteCarried); + } - } ++ } + // CraftBukkit end - ++ public void removeSlotListener(ContainerListener listener) { this.containerListeners.remove(listener); + } @@ -281,7 +331,7 @@ while (iterator.hasNext()) { ContainerListener icrafting = (ContainerListener) iterator.next(); @@ -225,3 +226,19 @@ return this.carried; } +@@ -947,4 +1054,15 @@ + this.stateId = this.stateId + 1 & 32767; + return this.stateId; + } ++ ++ // Paper start - Add missing InventoryHolders ++ // The reason this is a supplier, is that the createHolder method uses the bukkit InventoryView#getTopInventory to get the inventory in question ++ // and that can't be obtained safely until the AbstractContainerMenu has been fully constructed. Using a supplier lazily ++ // initializes the InventoryHolder safely. ++ protected final Supplier createBlockHolder(final ContainerLevelAccess context) { ++ //noinspection ConstantValue ++ Preconditions.checkArgument(context != null, "context was null"); ++ return () -> context.createBlockHolder(this); ++ } ++ // Paper end - Add missing InventoryHolders + } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch index 6a57db5ede..587f354b49 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/BeaconMenu.java.patch @@ -31,7 +31,7 @@ super(MenuType.BEACON, syncId); - this.beacon = new SimpleContainer(this, 1) { + this.player = (Inventory) inventory; // CraftBukkit - TODO: check this -+ this.beacon = new SimpleContainer(1) { // CraftBukkit - decompile error ++ this.beacon = new SimpleContainer(this.createBlockHolder(context), 1) { // CraftBukkit - decompile error // Paper - Add missing InventoryHolders @Override public boolean canPlaceItem(int slot, ItemStack stack) { return stack.is(ItemTags.BEACON_PAYMENT_ITEMS); diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/CartographyTableMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/CartographyTableMenu.java.patch index c639a918c9..f196694f53 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/CartographyTableMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/CartographyTableMenu.java.patch @@ -38,7 +38,14 @@ public static final int MAP_SLOT = 0; public static final int ADDITIONAL_SLOT = 1; public static final int RESULT_SLOT = 2; -@@ -40,6 +60,13 @@ +@@ -34,28 +54,42 @@ + + public CartographyTableMenu(int syncId, Inventory inventory, final ContainerLevelAccess context) { + super(MenuType.CARTOGRAPHY_TABLE, syncId); +- this.container = new SimpleContainer(2) { ++ this.container = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders + @Override + public void setChanged() { CartographyTableMenu.this.slotsChanged(this); super.setChanged(); } @@ -50,9 +57,10 @@ + } + // CraftBukkit end }; - this.resultContainer = new ResultContainer() { +- this.resultContainer = new ResultContainer() { ++ this.resultContainer = new ResultContainer(this.createBlockHolder(context)) { // Paper - Add missing InventoryHolders @Override -@@ -47,15 +74,22 @@ + public void setChanged() { CartographyTableMenu.this.slotsChanged(this); super.setChanged(); } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ContainerLevelAccess.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ContainerLevelAccess.java.patch index d146703cc4..3202223f24 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/ContainerLevelAccess.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/ContainerLevelAccess.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/ContainerLevelAccess.java +++ b/net/minecraft/world/inventory/ContainerLevelAccess.java -@@ -8,16 +8,48 @@ +@@ -8,16 +8,66 @@ public interface ContainerLevelAccess { @@ -17,6 +17,18 @@ + return new org.bukkit.Location(this.getWorld().getWorld(), this.getPosition().getX(), this.getPosition().getY(), this.getPosition().getZ()); + } + // CraftBukkit end ++ // Paper start - Add missing InventoryHolders ++ default boolean isBlock() { ++ return false; ++ } ++ ++ default org.bukkit.inventory.@org.jetbrains.annotations.Nullable BlockInventoryHolder createBlockHolder(AbstractContainerMenu menu) { ++ if (!this.isBlock()) { ++ return null; ++ } ++ return new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(this, menu.getBukkitView().getTopInventory()); ++ } ++ // Paper end - Add missing InventoryHolders + ContainerLevelAccess NULL = new ContainerLevelAccess() { @Override @@ -44,6 +56,12 @@ + return pos; + } + // CraftBukkit end ++ // Paper start - Add missing InventoryHolders ++ @Override ++ public boolean isBlock() { ++ return true; ++ } ++ // Paper end - Add missing InventoryHolders + + @Override public Optional evaluate(BiFunction getter) { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch index 4c042c3cc9..f15ea762a8 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -38,7 +38,14 @@ public EnchantmentMenu(int syncId, Inventory playerInventory) { this(syncId, playerInventory, ContainerLevelAccess.NULL); -@@ -53,6 +68,13 @@ +@@ -47,12 +62,19 @@ + + public EnchantmentMenu(int syncId, Inventory playerInventory, ContainerLevelAccess context) { + super(MenuType.ENCHANTMENT, syncId); +- this.enchantSlots = new SimpleContainer(2) { ++ this.enchantSlots = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders + @Override + public void setChanged() { super.setChanged(); EnchantmentMenu.this.slotsChanged(this); } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch index 767316ea7c..478faaf181 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch @@ -39,7 +39,16 @@ public static final int MAX_NAME_LENGTH = 35; public static final int INPUT_SLOT = 0; public static final int ADDITIONAL_SLOT = 1; -@@ -47,15 +67,22 @@ +@@ -40,22 +60,29 @@ + + public GrindstoneMenu(int syncId, Inventory playerInventory, final ContainerLevelAccess context) { + super(MenuType.GRINDSTONE, syncId); +- this.resultSlots = new ResultContainer(); +- this.repairSlots = new SimpleContainer(2) { ++ this.resultSlots = new ResultContainer(this.createBlockHolder(context)); // Paper - Add missing InventoryHolders ++ this.repairSlots = new SimpleContainer(this.createBlockHolder(context), 2) { // Paper - Add missing InventoryHolders + @Override + public void setChanged() { super.setChanged(); GrindstoneMenu.this.slotsChanged(this); } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch index c1682e5ad7..7d50fbdafb 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/ItemCombinerMenu.java.patch @@ -1,6 +1,35 @@ --- a/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/net/minecraft/world/inventory/ItemCombinerMenu.java -@@ -50,7 +50,7 @@ +@@ -17,12 +17,7 @@ + protected final ContainerLevelAccess access; + protected final Player player; + protected final Container inputSlots; +- protected final ResultContainer resultSlots = new ResultContainer() { +- @Override +- public void setChanged() { +- ItemCombinerMenu.this.slotsChanged(this); +- } +- }; ++ protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init + private final int resultSlotIndex; + + protected boolean mayPickup(Player player, boolean present) { +@@ -36,6 +31,14 @@ + public ItemCombinerMenu(@Nullable MenuType type, int syncId, Inventory playerInventory, ContainerLevelAccess context, ItemCombinerMenuSlotDefinition forgingSlotsManager) { + super(type, syncId); + this.access = context; ++ // Paper start - Add missing InventoryHolders; delay field init ++ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)) { ++ @Override ++ public void setChanged() { ++ ItemCombinerMenu.this.slotsChanged(this); ++ } ++ }; ++ // Paper end - Add missing InventoryHolders; delay field init + this.player = playerInventory.player; + this.inputSlots = this.createContainer(forgingSlotsManager.getNumOfInputSlots()); + this.resultSlotIndex = forgingSlotsManager.getResultSlotIndex(); +@@ -50,7 +53,7 @@ while (iterator.hasNext()) { final ItemCombinerMenuSlotDefinition.SlotDefinition itemcombinermenuslotdefinition_b = (ItemCombinerMenuSlotDefinition.SlotDefinition) iterator.next(); @@ -9,7 +38,16 @@ @Override public boolean mayPlace(ItemStack stack) { return itemcombinermenuslotdefinition_b.mayPlace().test(stack); -@@ -96,6 +96,7 @@ +@@ -82,7 +85,7 @@ + public abstract void createResult(); + + private SimpleContainer createContainer(int size) { +- return new SimpleContainer(size) { ++ return new SimpleContainer(this.createBlockHolder(this.access), size) { + @Override + public void setChanged() { + super.setChanged(); +@@ -96,6 +99,7 @@ super.slotsChanged(inventory); if (inventory == this.inputSlots) { this.createResult(); @@ -17,7 +55,7 @@ } } -@@ -110,6 +111,7 @@ +@@ -110,6 +114,7 @@ @Override public boolean stillValid(Player player) { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/LoomMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/LoomMenu.java.patch index c55f828f1b..1d534db5e0 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/LoomMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/LoomMenu.java.patch @@ -39,7 +39,15 @@ private static final int PATTERN_NOT_SET = -1; private static final int INV_SLOT_START = 4; private static final int INV_SLOT_END = 31; -@@ -60,6 +80,13 @@ +@@ -53,35 +73,49 @@ + this.selectablePatterns = List.of(); + this.slotUpdateListener = () -> { + }; +- this.inputContainer = new SimpleContainer(3) { ++ this.inputContainer = new SimpleContainer(this.createBlockHolder(context), 3) { // Paper - Add missing InventoryHolders + @Override + public void setChanged() { + super.setChanged(); LoomMenu.this.slotsChanged(this); LoomMenu.this.slotUpdateListener.run(); } @@ -51,9 +59,10 @@ + } + // CraftBukkit end }; - this.outputContainer = new SimpleContainer(1) { +- this.outputContainer = new SimpleContainer(1) { ++ this.outputContainer = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders @Override -@@ -67,21 +94,28 @@ + public void setChanged() { super.setChanged(); LoomMenu.this.slotUpdateListener.run(); } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ResultContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ResultContainer.java.patch index f0ecbe2239..a26bc470cf 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/ResultContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/ResultContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/ResultContainer.java +++ b/net/minecraft/world/inventory/ResultContainer.java -@@ -9,12 +9,51 @@ +@@ -9,12 +9,64 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeHolder; @@ -24,7 +24,12 @@ + } + + public org.bukkit.inventory.InventoryHolder getOwner() { -+ return null; // Result slots don't get an owner ++ // Paper start - Add missing InventoryHolders ++ if (this.holder == null && this.holderCreator != null) { ++ this.holder = this.holderCreator.get(); ++ } ++ return this.holder; // Result slots don't get an owner ++ // Paper end - Add missing InventoryHolders + } + + // Don't need a transaction; the InventoryCrafting keeps track of it for us @@ -48,6 +53,14 @@ + return null; + } + // CraftBukkit end ++ // Paper start - Add missing InventoryHolders ++ private @Nullable java.util.function.Supplier holderCreator; ++ private @Nullable org.bukkit.inventory.InventoryHolder holder; ++ public ResultContainer(java.util.function.Supplier holderCreator) { ++ this(); ++ this.holderCreator = holderCreator; ++ } ++ // Paper end - Add missing InventoryHolders + public ResultContainer() { this.itemStacks = NonNullList.withSize(1, ItemStack.EMPTY); diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/StonecutterMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/StonecutterMenu.java.patch index fca190ec45..95cd1f3220 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/StonecutterMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/StonecutterMenu.java.patch @@ -22,7 +22,7 @@ public class StonecutterMenu extends AbstractContainerMenu { public static final int INPUT_SLOT = 0; -@@ -36,14 +42,29 @@ +@@ -36,27 +42,49 @@ Runnable slotUpdateListener; public final Container container; final ResultContainer resultContainer; @@ -53,7 +53,12 @@ this.recipesForInput = SelectableRecipe.SingleInputSet.empty(); this.input = ItemStack.EMPTY; this.slotUpdateListener = () -> { -@@ -55,6 +76,13 @@ + }; +- this.container = new SimpleContainer(1) { ++ this.container = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders + @Override + public void setChanged() { + super.setChanged(); StonecutterMenu.this.slotsChanged(this); StonecutterMenu.this.slotUpdateListener.run(); } @@ -65,8 +70,11 @@ + } + // CraftBukkit end }; - this.resultContainer = new ResultContainer(); +- this.resultContainer = new ResultContainer(); ++ this.resultContainer = new ResultContainer(this.createBlockHolder(context)); // Paper - Add missing InventoryHolders this.access = context; + this.level = playerInventory.player.level(); + this.inputSlot = this.addSlot(new Slot(this.container, 0, 20, 33)); @@ -67,7 +95,7 @@ } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java index 7ae484b0fa..7129eb5f5c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java @@ -17,6 +17,13 @@ public class CraftBlockInventoryHolder implements BlockInventoryHolder { this.block = CraftBlock.at(world, pos); this.inventory = new CraftInventory(inv); } + // Paper start - Add missing InventoryHolders + public CraftBlockInventoryHolder(net.minecraft.world.inventory.ContainerLevelAccess levelAccess, Inventory inventory) { + com.google.common.base.Preconditions.checkArgument(levelAccess.isBlock()); + this.block = CraftBlock.at(levelAccess.getWorld(), levelAccess.getPosition()); + this.inventory = inventory; + } + // Paper end - Add missing InventoryHolders @Override public Block getBlock() {