From 0000000000000000000000000000000000000000 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 diff --git a/src/main/java/net/minecraft/world/Container.java b/src/main/java/net/minecraft/world/Container.java index db41ffbd24adccd78edf3368ba1f7a3ab9f6072c..5db5ba026462ca642dcee718af732f80fadabef5 100644 --- a/src/main/java/net/minecraft/world/Container.java +++ b/src/main/java/net/minecraft/world/Container.java @@ -103,7 +103,7 @@ public interface Container extends Clearable { 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/src/main/java/net/minecraft/world/SimpleContainer.java b/src/main/java/net/minecraft/world/SimpleContainer.java index b0963c534afe5be164701cb283f1849e32ae5a86..7ed52b887c4d766c23220a8809914d5d80f12ea4 100644 --- a/src/main/java/net/minecraft/world/SimpleContainer.java +++ b/src/main/java/net/minecraft/world/SimpleContainer.java @@ -30,7 +30,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { // 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; @@ -58,6 +58,11 @@ public class SimpleContainer implements Container, StackedContentsCompatible { } 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; } @@ -86,6 +91,13 @@ public class SimpleContainer implements Container, StackedContentsCompatible { public SimpleContainer(int size) { 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; diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java index 22dc1569aabe69f139d9682ceb81311993706cb8..85caec29a705f216eff8a5ae11f250697891a05c 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java @@ -1054,4 +1054,15 @@ public abstract class AbstractContainerMenu { 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/src/main/java/net/minecraft/world/inventory/BeaconMenu.java b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java index 75f097414f436eee9f179d4d03dd64599cbaad6f..b821c2676ecc252f90eff84cad0c4ba2c664531e 100644 --- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java +++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java @@ -42,7 +42,7 @@ public class BeaconMenu extends AbstractContainerMenu { public BeaconMenu(int syncId, Container inventory, ContainerData propertyDelegate, ContainerLevelAccess context) { super(MenuType.BEACON, syncId); 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/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java index 8b72d1fd551dcb113f4137aee441a9531c00288a..b3a16b024e46ee8203b225ee429a5c973eab12c6 100644 --- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java +++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java @@ -54,7 +54,7 @@ public class CartographyTableMenu extends AbstractContainerMenu { 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); @@ -68,7 +68,7 @@ public class CartographyTableMenu extends AbstractContainerMenu { } // CraftBukkit end }; - this.resultContainer = new ResultContainer() { + this.resultContainer = new ResultContainer(this.createBlockHolder(context)) { // Paper - Add missing InventoryHolders @Override public void setChanged() { CartographyTableMenu.this.slotsChanged(this); diff --git a/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java b/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java index 85e336637db8643fc5aca1dba724c9b341cbf46f..12b466ccb7c36021cf807c4f3fd2bcb037943abc 100644 --- a/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java +++ b/src/main/java/net/minecraft/world/inventory/ContainerLevelAccess.java @@ -21,6 +21,18 @@ public interface ContainerLevelAccess { 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 @@ -48,6 +60,12 @@ public interface ContainerLevelAccess { 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/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java index 68f978be8ec11e0e5bb4ea40e06c61f729e92d46..e200df7fc90de06d420556711ac67fa94a40d1d2 100644 --- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java @@ -62,7 +62,7 @@ public class EnchantmentMenu extends AbstractContainerMenu { 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(); diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java index 8e58dbb4b110338dfe8add26697d0b1c9ec5fa9c..3b303d41b9facfb2892ff8402ee0de4608db7318 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java @@ -60,8 +60,8 @@ public class GrindstoneMenu extends AbstractContainerMenu { 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(); diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java index 4734dd90f2a66e1ac7a64b35ecd62a630108cf07..a5d53a656513ae81cc3f9fc506caf6adaba62a8e 100644 --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java @@ -17,12 +17,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { 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 abstract class ItemCombinerMenu extends AbstractContainerMenu { 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(); @@ -82,7 +85,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { 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(); diff --git a/src/main/java/net/minecraft/world/inventory/LoomMenu.java b/src/main/java/net/minecraft/world/inventory/LoomMenu.java index 1b7cf165ab0818792870f43719a6324b282bb57a..98519dd3bccca516acdedc69a59189b1106fb75b 100644 --- a/src/main/java/net/minecraft/world/inventory/LoomMenu.java +++ b/src/main/java/net/minecraft/world/inventory/LoomMenu.java @@ -73,7 +73,7 @@ public class LoomMenu extends AbstractContainerMenu { 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(); @@ -88,7 +88,7 @@ public class LoomMenu extends AbstractContainerMenu { } // CraftBukkit end }; - this.outputContainer = new SimpleContainer(1) { + this.outputContainer = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders @Override public void setChanged() { super.setChanged(); diff --git a/src/main/java/net/minecraft/world/inventory/ResultContainer.java b/src/main/java/net/minecraft/world/inventory/ResultContainer.java index d4592218d761eb38402e3d95c642e80a708cb333..4c4266a85c38e41e6c7e6144a68624f4daa50c54 100644 --- a/src/main/java/net/minecraft/world/inventory/ResultContainer.java +++ b/src/main/java/net/minecraft/world/inventory/ResultContainer.java @@ -29,7 +29,12 @@ public class ResultContainer implements Container, RecipeCraftingHolder { } 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 @@ -53,6 +58,14 @@ public class ResultContainer implements Container, RecipeCraftingHolder { 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/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java index 74ea3f0154733ed4f096d88403fe011cca663e02..5dce62aead43c7110e06196423458eea2ba31885 100644 --- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java +++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java @@ -69,7 +69,7 @@ public class StonecutterMenu extends AbstractContainerMenu { this.input = ItemStack.EMPTY; this.slotUpdateListener = () -> { }; - this.container = new SimpleContainer(1) { + this.container = new SimpleContainer(this.createBlockHolder(context), 1) { // Paper - Add missing InventoryHolders @Override public void setChanged() { super.setChanged(); @@ -84,7 +84,7 @@ public class StonecutterMenu extends AbstractContainerMenu { } // CraftBukkit end }; - 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)); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java index 7ae484b0fa5bf5494c6ead15f7f1c0fa840ae270..7129eb5f5cea39992b4c690cb421004004a952ea 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftBlockInventoryHolder.java +++ b/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() {