mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-30 04:02:50 +01:00
89d51d5f29
Because this exploit has been widely known for years and has not been fixed by Mojang, we decided that it was worth allowing people to toggle it on/off due to how easy it is to make it configurable. It should be noted that this decision does not promise all future exploits will be configurable.
302 lines
17 KiB
Diff
302 lines
17 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
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 da5ff65fade5cdf14fad3705c08b48896bc4c36d..d6cbe98e67fdbf8db46338a88ab1356dd63b50a3 100644
|
|
--- a/src/main/java/net/minecraft/world/Container.java
|
|
+++ b/src/main/java/net/minecraft/world/Container.java
|
|
@@ -100,7 +100,7 @@ public interface Container extends Clearable {
|
|
|
|
java.util.List<org.bukkit.entity.HumanEntity> 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 ff1aba1e69cfde633fd01724f1a8d0af7f59437f..9546d93f90ca34b4d35bd98df847bf896c654043 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<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
|
private int maxStack = MAX_STACK;
|
|
- protected org.bukkit.inventory.InventoryHolder bukkitOwner;
|
|
+ protected @Nullable org.bukkit.inventory.InventoryHolder bukkitOwner; // Paper - annotation
|
|
|
|
public List<ItemStack> 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<? extends org.bukkit.inventory.InventoryHolder> bukkitOwnerCreator;
|
|
+ public SimpleContainer(java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> 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 75f836f07c66dbf71017ef0b7697851353d0f2e1..eef0d3c59f0ce6e89033a5e228d31b63339c2773 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java
|
|
@@ -993,4 +993,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<org.bukkit.inventory.BlockInventoryHolder> 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 2813a87a01d0704a3de210cd005073f953d538f8..88842f31836df70717fdf7f77f39a2ad8bb45326 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/BeaconMenu.java
|
|
@@ -41,7 +41,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) {
|
|
+ this.beacon = new SimpleContainer(this.createBlockHolder(context), 1) { // 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 ca3c8b31967a6efd7b0caacb091ab2151e7c0bee..45bf1c95d86bdfc709c5f1a1fbefb18e1cc51f4c 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/CartographyTableMenu.java
|
|
@@ -52,7 +52,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);
|
|
@@ -66,7 +66,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 <T> Optional<T> evaluate(BiFunction<Level, BlockPos, T> getter) {
|
|
diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
|
index c2d6265933dc4ceed80e2bd517970d02164a63df..343f44db579839eb61376f876b5eff2e615dc2e5 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java
|
|
@@ -61,7 +61,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 95ac3446fba1f37637c9700080de2e1ce7a3550a..23462de504932bd351b8dfacde514fe361343912 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
|
@@ -59,8 +59,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 eb36a69b8da492aec9609cc9ef80d7d68ff9af03..62e1b7096fa659778b737b3d520389e73138dc5d 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
|
|
@@ -18,7 +18,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
|
protected final Player player;
|
|
protected final Container inputSlots;
|
|
private final List<Integer> inputSlotIndexes;
|
|
- protected final ResultContainer resultSlots = new ResultContainer();
|
|
+ protected final ResultContainer resultSlots; // Paper - Add missing InventoryHolders; delay field init
|
|
private final int resultSlotIndex;
|
|
|
|
protected abstract boolean mayPickup(Player player, boolean present);
|
|
@@ -30,6 +30,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
|
public ItemCombinerMenu(@Nullable MenuType<?> type, int syncId, Inventory playerInventory, ContainerLevelAccess context) {
|
|
super(type, syncId);
|
|
this.access = context;
|
|
+ this.resultSlots = new ResultContainer(this.createBlockHolder(this.access)); // Paper - Add missing InventoryHolders; delay field init
|
|
this.player = playerInventory.player;
|
|
ItemCombinerMenuSlotDefinition itemcombinermenuslotdefinition = this.createInputSlotDefinitions();
|
|
|
|
@@ -96,7 +97,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
|
|
protected abstract ItemCombinerMenuSlotDefinition createInputSlotDefinitions();
|
|
|
|
private SimpleContainer createContainer(int size) {
|
|
- return new SimpleContainer(size) {
|
|
+ return new SimpleContainer(this.createBlockHolder(this.access), size) { // Paper - Add missing InventoryHolders
|
|
@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 e8c755dc71d9818f025eb25224122b19c5f9e15b..c1c9cfd3f77b2dbbc39741d629c7dfb24a48d4f6 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<? extends org.bukkit.inventory.InventoryHolder> holderCreator;
|
|
+ private @Nullable org.bukkit.inventory.InventoryHolder holder;
|
|
+ public ResultContainer(java.util.function.Supplier<? extends org.bukkit.inventory.InventoryHolder> 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 1a5d8debc053b24e5856de916f1d248b36f645ba..eade15820dd9db38b6af2a5c4314acfb14ca03e9 100644
|
|
--- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
|
+++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
|
|
@@ -68,7 +68,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();
|
|
@@ -83,7 +83,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() {
|