From fcc9a4c0cbe891bfa3fe87961f84a0e9da2c9e7a Mon Sep 17 00:00:00 2001 From: Jikoo Date: Wed, 23 Nov 2016 21:57:05 -0500 Subject: [PATCH] Almost entirely functional silent shulker boxes For whatever reason, the shulker box EnumDirection isn't being retrieved properly, so AnyChest will only trigger on shulker boxes that would not be able to open if placed downwards (opening upwards). Silentchest and anychest will work, though. Suppressed a few deprecation warnings that don't make sense to keep. If you do use my fork of OpenInv's API, it's not yet stable (specifically, IAnySilentContainer), and will change a little more as I polish things up. --- OpenInv/pom.xml | 2 +- .../openinv/internal/IAnySilentChest.java | 2 +- .../openinv/internal/IAnySilentContainer.java | 1 + .../internal/v1_11_R1/AnySilentContainer.java | 90 +++++++++++++------ .../v1_11_R1/SilentContainerShulkerBox.java | 11 --- .../internal/v1_7_R2/PlayerDataManager.java | 1 + .../main/java/com/lishid/openinv/OpenInv.java | 2 +- OpenInvPlugin/src/main/resources/plugin.yml | 10 +-- 8 files changed, 73 insertions(+), 46 deletions(-) diff --git a/OpenInv/pom.xml b/OpenInv/pom.xml index badccd8..c762f51 100644 --- a/OpenInv/pom.xml +++ b/OpenInv/pom.xml @@ -9,7 +9,7 @@ openinv OpenInv - 2.5.3-SNAPSHOT + 2.5.4 diff --git a/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentChest.java b/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentChest.java index 12a08c0..02d13ea 100644 --- a/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentChest.java +++ b/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentChest.java @@ -25,7 +25,7 @@ import org.bukkit.entity.Player; public interface IAnySilentChest { /** - * @deprecated Use {@link IAnySilentContainer#activateContainer(Player, boolean, boolean, int, int, int)}. + * @deprecated Use {@link IAnySilentContainer#activateContainer(Player, boolean, int, int, int)}. */ @Deprecated public boolean activateChest(Player player, boolean anychest, boolean silentchest, int x, int y, int z); diff --git a/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentContainer.java b/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentContainer.java index ebaed8e..380c742 100644 --- a/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentContainer.java +++ b/OpenInvCore/src/main/java/com/lishid/openinv/internal/IAnySilentContainer.java @@ -3,6 +3,7 @@ package com.lishid.openinv.internal; import org.bukkit.block.Block; import org.bukkit.entity.Player; +@SuppressWarnings("deprecation") public interface IAnySilentContainer extends IAnySilentChest { /** diff --git a/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/AnySilentContainer.java b/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/AnySilentContainer.java index 3b16fe6..dfcc975 100644 --- a/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/AnySilentContainer.java +++ b/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/AnySilentContainer.java @@ -18,16 +18,19 @@ package com.lishid.openinv.internal.v1_11_R1; import com.lishid.openinv.internal.IAnySilentContainer; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; // Volatile import net.minecraft.server.v1_11_R1.AxisAlignedBB; import net.minecraft.server.v1_11_R1.Block; import net.minecraft.server.v1_11_R1.BlockChest; import net.minecraft.server.v1_11_R1.BlockChest.Type; +import net.minecraft.server.v1_11_R1.BlockEnderChest; import net.minecraft.server.v1_11_R1.BlockPosition; import net.minecraft.server.v1_11_R1.BlockShulkerBox; import net.minecraft.server.v1_11_R1.Container; @@ -62,16 +65,22 @@ public class AnySilentContainer implements IAnySilentContainer { @Override public boolean activateContainer(Player p, boolean silentchest, int x, int y, int z) { + // TODO backport to all modules? TODO change new API to activateContainer(Player, Block)? Use BlockState instead? + if (silentchest && p.getWorld().getBlockAt(x, y, z).getType() == Material.ENDER_CHEST) { + p.openInventory(p.getEnderChest()); + return true; + } + EntityPlayer player = ((CraftPlayer) p).getHandle(); - World world = player.world; - BlockPosition blockPosition = new BlockPosition(x, y, z); + final World world = player.world; + final BlockPosition blockPosition = new BlockPosition(x, y, z); Object tile = world.getTileEntity(blockPosition); if (tile == null) { return false; } - Block block = world.getType(new BlockPosition(x, y, z)).getBlock(); + Block block = world.getType(blockPosition).getBlock(); Container container = null; if (block instanceof BlockChest) { @@ -115,41 +124,56 @@ public class AnySilentContainer implements IAnySilentContainer { player.b(StatisticList.ae); if (silentchest && tile instanceof TileEntityShulkerBox) { - // TODO: End state allows for silent opening by other players while open (not close) - // increases by 1 when animation is scheduled to complete, even though animation does not occur - // Can't set value lower than 0, it corrects. - // Could schedule a reset for a couple seconds later when the animation finishes. - // Could say "that's good enough" and get some rest - int value = SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile); - if (value < 1) { - SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile, 2); - } + // Set value to current + 1. Ensures consistency later when resetting. + SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile, + SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) + 1); + container = new SilentContainerShulkerBox(player.inventory, (IInventory) tile, player); - // Reset value to start - SilentContainerShulkerBox.setOpenValue((TileEntityShulkerBox) tile, value); } } + if (!(tile instanceof IInventory)) { + // TODO anyenderchest + p.sendMessage(ChatColor.RED + "Unhandled non-IInventory for block!"); + return false; + } + boolean returnValue = false; + final IInventory iInventory = (IInventory) tile; if (!silentchest || container == null) { - player.openContainer((IInventory) tile); + player.openContainer(iInventory); returnValue = true; } else { try { int windowId = player.nextContainerCounter(); - player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, "minecraft:chest", ((IInventory) tile).getScoreboardDisplayName(), ((IInventory) tile).getSize())); + player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, iInventory.getName(), iInventory.getScoreboardDisplayName(), iInventory.getSize())); player.activeContainer = container; player.activeContainer.windowId = windowId; player.activeContainer.addSlotListener(player); returnValue = true; + if (tile instanceof TileEntityShulkerBox) { + new BukkitRunnable() { + @Override + public void run() { + // TODO hacky + Object tile = world.getTileEntity(blockPosition); + if (!(tile instanceof TileEntityShulkerBox)) { + return; + } + TileEntityShulkerBox box = (TileEntityShulkerBox) tile; + // Reset back - we added 1, and calling TileEntityShulkerBox#startOpen adds 1 more. + SilentContainerShulkerBox.setOpenValue(box, + SilentContainerShulkerBox.getOpenValue((TileEntityShulkerBox) tile) - 2); + } + }.runTaskLater(Bukkit.getPluginManager().getPlugin("OpenInv"), 2); + } } catch (Exception e) { e.printStackTrace(); p.sendMessage(ChatColor.RED + "Error while sending silent chest."); } } - return returnValue; } @@ -164,16 +188,31 @@ public class AnySilentContainer implements IAnySilentContainer { return isBlockedShulkerBox(world, blockPosition, block); } - // For reference, loot at net.minecraft.server.BlockChest + if (block instanceof BlockEnderChest) { + // Ender chests are not blocked by ocelots. + return world.getType(new BlockPosition(x, y + 1, z)).m(); + } + // Check if chest is blocked or has an ocelot on top - if (world.getType(new BlockPosition(x, y + 1, z)).m() || hasOcelotOnTop(world, blockPosition)) { + if (isBlockedChest(world, blockPosition)) { return true; } // Check for matching adjacent chests that are blocked or have an ocelot on top for (EnumDirection localEnumDirection : EnumDirection.EnumDirectionLimit.HORIZONTAL) { BlockPosition localBlockPosition = blockPosition.shift(localEnumDirection); - if (isBlockedChest(world, block, localBlockPosition)) { + Block localBlock = world.getType(localBlockPosition).getBlock(); + + if (localBlock != block) { + continue; + } + + TileEntity localTileEntity = world.getTileEntity(localBlockPosition); + if (!(localTileEntity instanceof TileEntityChest)) { + continue; + } + + if (isBlockedChest(world, localBlockPosition)) { return true; } } @@ -198,17 +237,14 @@ public class AnySilentContainer implements IAnySilentContainer { .a(enumDirection.getAdjacentX(), enumDirection.getAdjacentY(), enumDirection.getAdjacentZ()); - return !(world.b(axisAlignedBB.a(blockPosition.shift(enumDirection)))); + return world.b(axisAlignedBB.a(blockPosition.shift(enumDirection))); } - return true; + return false; } - private boolean isBlockedChest(World world, Block block, BlockPosition blockPosition) { - if (world.getType(blockPosition).getBlock() == block) { - return false; - } - + private boolean isBlockedChest(World world, BlockPosition blockPosition) { + // For reference, loot at net.minecraft.server.BlockChest return world.getType(blockPosition.up()).m() || hasOcelotOnTop(world, blockPosition); } diff --git a/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/SilentContainerShulkerBox.java b/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/SilentContainerShulkerBox.java index 6768cbe..eba7979 100644 --- a/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/SilentContainerShulkerBox.java +++ b/OpenInvCraftbukkit1_11_R1/src/main/java/com/lishid/openinv/internal/v1_11_R1/SilentContainerShulkerBox.java @@ -38,24 +38,13 @@ public class SilentContainerShulkerBox extends ContainerShulkerBox { } } - private final TileEntityShulkerBox tile; - public SilentContainerShulkerBox(PlayerInventory playerInventory, IInventory iInventory, EntityHuman entityHuman) { super(playerInventory, iInventory, entityHuman); - if (iInventory instanceof TileEntityShulkerBox) { - tile = (TileEntityShulkerBox) iInventory; - } else { - tile = null; - } } @Override public void b(EntityHuman entityHuman) { - if (tile != null) { - setOpenValue(tile, tile.getViewers().size()); - } - PlayerInventory playerinventory = entityHuman.inventory; if (!playerinventory.getCarried().isEmpty()) { diff --git a/OpenInvCraftbukkit1_7_R2/src/main/java/com/lishid/openinv/internal/v1_7_R2/PlayerDataManager.java b/OpenInvCraftbukkit1_7_R2/src/main/java/com/lishid/openinv/internal/v1_7_R2/PlayerDataManager.java index 15c98dc..03df176 100644 --- a/OpenInvCraftbukkit1_7_R2/src/main/java/com/lishid/openinv/internal/v1_7_R2/PlayerDataManager.java +++ b/OpenInvCraftbukkit1_7_R2/src/main/java/com/lishid/openinv/internal/v1_7_R2/PlayerDataManager.java @@ -30,6 +30,7 @@ import net.minecraft.util.com.mojang.authlib.GameProfile; import org.bukkit.craftbukkit.v1_7_R2.CraftServer; +@SuppressWarnings("deprecation") // Deprecated methods are used properly and will not change. public class PlayerDataManager implements IPlayerDataManager { @Override diff --git a/OpenInvPlugin/src/main/java/com/lishid/openinv/OpenInv.java b/OpenInvPlugin/src/main/java/com/lishid/openinv/OpenInv.java index 4ff541e..37ce3e7 100644 --- a/OpenInvPlugin/src/main/java/com/lishid/openinv/OpenInv.java +++ b/OpenInvPlugin/src/main/java/com/lishid/openinv/OpenInv.java @@ -107,7 +107,7 @@ public class OpenInv extends JavaPlugin { accessor = new InternalAccessor(this); // Version check if (!accessor.initialize(getServer())) { - getLogger().info("Your version of CraftBukkit (" + accessor.getVersion() + ")is not supported."); + getLogger().info("Your version of CraftBukkit (" + accessor.getVersion() + ") is not supported."); getLogger().info("Please look for an updated version of OpenInv."); pm.disablePlugin(this); return; diff --git a/OpenInvPlugin/src/main/resources/plugin.yml b/OpenInvPlugin/src/main/resources/plugin.yml index b59a88a..063bec0 100644 --- a/OpenInvPlugin/src/main/resources/plugin.yml +++ b/OpenInvPlugin/src/main/resources/plugin.yml @@ -10,30 +10,30 @@ commands: aliases: [oi, inv, open] description: Open a player's inventory permission: OpenInv.*;OpenInv.openinv - usage: | + usage: |- / - Open last person's inventory / - Open a player's inventory openender: aliases: [oe] description: Opens the enderchest of a player permission: OpenInv.*;OpenInv.openender - usage: | + usage: |- / - Opens a player's enderchest searchinv: aliases: [si] description: Search and list players having a specific item permission: OpenInv.*;OpenInv.search - usage: | + usage: |- / [MinAmount] - Item can be the Item ID or the CraftBukkit Item Name, MinAmount is the minimum amount to be considered. silentchest: aliases: [sc, silent] description: Toggle silent chest function, which hides the animation of a chest when opened or closed, and suppresses the sound. permission: OpenInv.*;OpenInv.silent - usage: | + usage: |- / [Check] - Checks whether silent chest is enabled anychest: aliases: [ac] description: Toggle anychest function, which allows opening of blocked chests. permission: OpenInv.*;OpenInv.anychest - usage: | + usage: |- / [Check] - Checks whether anychest is enabled