From 3599dbe3c27ad950700b9a76d198951e15f882ba Mon Sep 17 00:00:00 2001 From: Senmori Date: Wed, 25 Jul 2018 18:03:26 +1000 Subject: [PATCH] SPIGOT-3981: Make custom inventories return specialised types where practical. --- .../org/bukkit/craftbukkit/CraftServer.java | 12 ++- .../craftbukkit/entity/CraftHumanEntity.java | 9 ++ .../util/CraftCustomInventoryConverter.java | 27 +++++ .../inventory/util/CraftInventoryCreator.java | 59 +++++++++++ .../util/CraftTileInventoryConverter.java | 100 ++++++++++++++++++ 5 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/util/CraftCustomInventoryConverter.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index c5e1c03747..61d9fa33c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -145,6 +145,7 @@ import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.command.BukkitCommandWrapper; import org.bukkit.craftbukkit.command.CraftCommandMap; import org.bukkit.craftbukkit.command.VanillaCommandWrapper; +import org.bukkit.craftbukkit.inventory.util.CraftInventoryCreator; import org.bukkit.craftbukkit.tag.CraftBlockTag; import org.bukkit.craftbukkit.tag.CraftItemTag; import org.bukkit.craftbukkit.util.CraftNamespacedKey; @@ -1474,25 +1475,26 @@ public final class CraftServer implements Server { @Override public Inventory createInventory(InventoryHolder owner, InventoryType type) { - // TODO: Create the appropriate type, rather than Custom? - return new CraftInventoryCustom(owner, type); + Validate.isTrue(type.isCreatable(), "Cannot open an inventory of type ", type); + return CraftInventoryCreator.INSTANCE.createInventory(owner, type); } @Override public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { - return new CraftInventoryCustom(owner, type, title); + Validate.isTrue(type.isCreatable(), "Cannot open an inventory of type ", type); + return CraftInventoryCreator.INSTANCE.createInventory(owner, type, title); } @Override public Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException { Validate.isTrue(size % 9 == 0, "Chests must have a size that is a multiple of 9!"); - return new CraftInventoryCustom(owner, size); + return CraftInventoryCreator.INSTANCE.createInventory(owner, size); } @Override public Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException { Validate.isTrue(size % 9 == 0, "Chests must have a size that is a multiple of 9!"); - return new CraftInventoryCustom(owner, size, title); + return CraftInventoryCreator.INSTANCE.createInventory(owner, size, title); } @Override diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index 073c8acf2c..d96c6afdb3 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -189,6 +189,15 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { IInventory iinventory = (inventory instanceof CraftInventory) ? ((CraftInventory) inventory).getInventory() : new org.bukkit.craftbukkit.inventory.InventoryWrapper(inventory); + if (iinventory instanceof ITileInventory) { + if (iinventory instanceof TileEntity) { + TileEntity te = (TileEntity) iinventory; + if (!te.u()) { // PAIL rename hasWorld + te.setWorld(getHandle().world); + } + } + } + switch (type) { case PLAYER: case CHEST: diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftCustomInventoryConverter.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftCustomInventoryConverter.java new file mode 100644 index 0000000000..ed4415f6dd --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftCustomInventoryConverter.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.inventory.util; + +import org.bukkit.craftbukkit.inventory.CraftInventoryCustom; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +public class CraftCustomInventoryConverter implements CraftInventoryCreator.InventoryConverter { + + @Override + public Inventory createInventory(InventoryHolder holder, InventoryType type) { + return new CraftInventoryCustom(holder, type); + } + + @Override + public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { + return new CraftInventoryCustom(owner, type, title); + } + + public Inventory createInventory(InventoryHolder owner, int size) { + return new CraftInventoryCustom(owner, size); + } + + public Inventory createInventory(InventoryHolder owner, int size, String title) { + return new CraftInventoryCustom(owner, size, title); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java new file mode 100644 index 0000000000..f3ad95406a --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftInventoryCreator.java @@ -0,0 +1,59 @@ +package org.bukkit.craftbukkit.inventory.util; + +import java.util.HashMap; +import java.util.Map; +import net.minecraft.server.TileEntityDispenser; +import net.minecraft.server.TileEntityDropper; +import net.minecraft.server.TileEntityHopper; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +public final class CraftInventoryCreator { + + public static final CraftInventoryCreator INSTANCE = new CraftInventoryCreator(); + // + private final CraftCustomInventoryConverter DEFAULT_CONVERTER = new CraftCustomInventoryConverter(); + private final Map converterMap = new HashMap<>(); + + private CraftInventoryCreator() { + converterMap.put(InventoryType.CHEST, DEFAULT_CONVERTER); + converterMap.put(InventoryType.DISPENSER, new CraftTileInventoryConverter(new TileEntityDispenser())); + converterMap.put(InventoryType.DROPPER, new CraftTileInventoryConverter(new TileEntityDropper())); + // furnace needs a world + converterMap.put(InventoryType.FURNACE, new CraftTileInventoryConverter.Furnace()); + converterMap.put(InventoryType.WORKBENCH, DEFAULT_CONVERTER); + converterMap.put(InventoryType.ENCHANTING, DEFAULT_CONVERTER); + converterMap.put(InventoryType.BREWING, new CraftTileInventoryConverter.BrewingStand()); + converterMap.put(InventoryType.PLAYER, DEFAULT_CONVERTER); + converterMap.put(InventoryType.MERCHANT, DEFAULT_CONVERTER); + converterMap.put(InventoryType.ENDER_CHEST, DEFAULT_CONVERTER); + converterMap.put(InventoryType.ANVIL, DEFAULT_CONVERTER); + converterMap.put(InventoryType.BEACON, new CraftTileInventoryConverter.Beacon()); + converterMap.put(InventoryType.HOPPER, new CraftTileInventoryConverter(new TileEntityHopper())); + converterMap.put(InventoryType.SHULKER_BOX, DEFAULT_CONVERTER); + } + + public Inventory createInventory(InventoryHolder holder, InventoryType type) { + return converterMap.get(type).createInventory(holder, type); + } + + public Inventory createInventory(InventoryHolder holder, InventoryType type, String title) { + return converterMap.get(type).createInventory(holder, type, title); + } + + public Inventory createInventory(InventoryHolder holder, int size) { + return DEFAULT_CONVERTER.createInventory(holder, size); + } + + public Inventory createInventory(InventoryHolder holder, int size, String title) { + return DEFAULT_CONVERTER.createInventory(holder, size, title); + } + + public interface InventoryConverter { + + Inventory createInventory(InventoryHolder holder, InventoryType type); + + Inventory createInventory(InventoryHolder holder, InventoryType type, String title); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java new file mode 100644 index 0000000000..ad2ca4420b --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java @@ -0,0 +1,100 @@ +package org.bukkit.craftbukkit.inventory.util; + +import net.minecraft.server.ITileInventory; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBrewingStand; +import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityLootable; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryBeacon; +import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; +import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +public class CraftTileInventoryConverter implements CraftInventoryCreator.InventoryConverter { + + protected final ITileInventory tileEntity; + + public CraftTileInventoryConverter(ITileInventory tileEntity) { + this.tileEntity = tileEntity; + } + + @Override + public Inventory createInventory(InventoryHolder holder, InventoryType type) { + return getInventory(tileEntity); + } + + @Override + public Inventory createInventory(InventoryHolder holder, InventoryType type, String title) { + if (tileEntity instanceof TileEntityLootable) { + ((TileEntityLootable) tileEntity).setCustomName(CraftChatMessage.fromStringOrNull(title)); + } + + return getInventory(tileEntity); + } + + public Inventory getInventory(ITileInventory tileEntity) { + return new CraftInventory(tileEntity); + } + + public static class Furnace extends CraftTileInventoryConverter { + + public Furnace() { + super(new TileEntityFurnace()); + } + + @Override + public Inventory createInventory(InventoryHolder owner, InventoryType type) { + return getInventory(tileEntity); + } + + @Override + public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { + ((TileEntityFurnace) tileEntity).setCustomName(CraftChatMessage.fromStringOrNull(title)); + return getInventory(tileEntity); + } + + @Override + public Inventory getInventory(ITileInventory tileEntity) { + ((TileEntityFurnace) tileEntity).setWorld(MinecraftServer.getServer().getWorldServer(0)); // TODO: customize this if required + return new CraftInventoryFurnace((TileEntityFurnace) tileEntity); + } + } + + public static class BrewingStand extends CraftTileInventoryConverter { + + public BrewingStand() { + super(new TileEntityBrewingStand()); + } + + @Override + public Inventory createInventory(InventoryHolder holder, InventoryType type, String title) { + // BrewingStand does not extend TileEntityLootable + if (tileEntity instanceof TileEntityBrewingStand) { + ((TileEntityBrewingStand) tileEntity).setCustomName(CraftChatMessage.fromStringOrNull(title)); + } + return getInventory(tileEntity); + } + + @Override + public Inventory getInventory(ITileInventory tileEntity) { + return new CraftInventoryBrewer(tileEntity); + } + } + + public static class Beacon extends CraftTileInventoryConverter { + + public Beacon() { + super(new TileEntityBeacon()); + } + + @Override + public Inventory getInventory(ITileInventory tileInventory) { + return new CraftInventoryBeacon((TileEntityBeacon) tileInventory); + } + } +}