Add missing InventoryHolders to inventories

This commit is contained in:
Jake Potrebic 2022-01-24 00:09:02 -08:00
parent a24a58dfab
commit 183683ecc5
13 changed files with 177 additions and 29 deletions

View file

@ -38,7 +38,7 @@
+
+ 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);
+

View file

@ -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<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;
@ -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<? 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;
+ // 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);

View file

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

View file

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

View file

@ -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();
}

View file

@ -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 <T> Optional<T> evaluate(BiFunction<Level, BlockPos, T> getter) {

View file

@ -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);
}

View file

@ -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);
}

View file

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

View file

@ -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();
}

View file

@ -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<? 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);

View file

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

View file

@ -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() {