Getting type of inventory when it closes?

Discussion in 'Plugin Development' started by Rhiannon, Jan 25, 2017.

Thread Status:
Not open for further replies.
  1. Offline

    Rhiannon

    Hello! I'm trying to perform some functionality when a player closes a chest. I see there is an InventoryCloseEvent, but I can't figure out how to determine the container type. If I were opening, I found that was simple - (event).getInventory().getTitle(). Is there some way to get that for when it's closed so I know if they closed a chest or an ender chest? Thank you!
     
  2. Offline

    timtower Administrator Administrator Moderator

    Moved to plugin development
     
  3. Offline

    JanTuck

    @Rhiannon

    It is exactly the same to get the title when it closes on the InventoryCloseEvent.

    InventoryEvent#getInventory

    Then you can call all functions you want on that inventory.
     
  4. Offline

    Rhiannon

    Gotcha. I ran into another snag though. I found out that while I can determine if it was a chest or a doublechest, if I try to check for enderchest I get an NPE. Is there a way to tell that the inventory just closed was from an ender chest? This is what I tried:

    Code:
    @EventHandler
    public void onInventoryCloseEvent(InventoryCloseEvent e) {
       System.out.println(e.getInventory().getHolder().getClass().getCanonicalName());
      if (e.getInventory().getHolder() instanceof Chest) log.log(Level.INFO, "A single chest was closed");
       if (e.getInventory().getHolder() instanceof DoubleChest) log.log(Level.INFO, "A double chest was closed");
       if (e.getInventory().getHolder() instanceof EnderChest) log.log(Level.INFO, "An ender chest was closed");
    }
    ...and this is what I got after open/closing chest, then double chest, then ender chest:

    Code:
    [23:15:40 INFO]: org.bukkit.craftbukkit.v1_11_R1.block.CraftChest
    [23:15:40 INFO]: A single chest was closed
    [23:15:41 INFO]: org.bukkit.block.DoubleChest
    [23:15:41 INFO]: A double chest was closed
    [23:15:42 ERROR]: Could not pass event InventoryCloseEvent to Testing v1.0
    org.bukkit.event.EventException
      at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at org.bukkit.craftbukkit.v1_11_R1.event.CraftEventFactory.handleInventoryCloseEvent(CraftEventFactory.java:882) [spigot-1.11.2.jar:
    git-Spigot-b32c8f8-4d3bf20]
      at net.minecraft.server.v1_11_R1.PlayerConnection.a(PlayerConnection.java:1619) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at net.minecraft.server.v1_11_R1.PacketPlayInCloseWindow.a(PacketPlayInCloseWindow.java:18) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d
    3bf20]
      at net.minecraft.server.v1_11_R1.PacketPlayInCloseWindow.a(PacketPlayInCloseWindow.java:1) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3
    bf20]
      at net.minecraft.server.v1_11_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_73]
      at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_73]
      at net.minecraft.server.v1_11_R1.SystemUtils.a(SourceFile:46) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:739) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:675) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:574) [spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      at java.lang.Thread.run(Unknown Source) [?:1.8.0_73]
    Caused by: java.lang.NullPointerException
      at com.sylvcraft.Testing.onInventoryCloseEvent(Testing.java:42) ~[?:?]
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_73]
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_73]
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_73]
      at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_73]
      at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot-1.11.2.jar:git-Spigot-b32c8f8-4d3bf20]
      ... 16 more
    >
     
  5. Offline

    mythbusterma

    @Rhiannon

    Something on line 42 is null. Figure out what it is.
     
  6. Offline

    Rhiannon

    Hmm. 42 was where I printed the canonical name. I changed the function to:

    Code:
    @EventHandler
    public void onInventoryCloseEvent(InventoryCloseEvent e) {
      InventoryHolder YouAreAPainInMyButt = e.getInventory().getHolder();
      if (YouAreAPainInMyButt == null) {
      consoleLog.log(Level.INFO, "It's null");
      } else {
      if (YouAreAPainInMyButt instanceof Chest) consoleLog.log(Level.INFO, "A single chest was closed");
      if (YouAreAPainInMyButt instanceof DoubleChest) consoleLog.log(Level.INFO, "A double chest was closed");
      if (YouAreAPainInMyButt instanceof EnderChest) consoleLog.log(Level.INFO, "An ender chest was closed");
      }
    }
    Now as I open/close a chest, dchest then an echest I get this in the console:

    Code:
    [21:31:06 INFO]: org.bukkit.craftbukkit.v1_11_R1.block.CraftChest
    [21:31:06 INFO]: A single chest was closed
    [21:31:08 INFO]: org.bukkit.block.DoubleChest
    [21:31:08 INFO]: A double chest was closed
    [21:31:11 INFO]: It's null
    So I guess there is no holder for an ender chest. *sigh*

    EDIT: Oh wait a sec.. if the holder is set for all the other container types, then maybe I can use the fact it's null to detect the echest. Of course, that's a horribly hacky way, lol
     
  7. Offline

    JanTuck

    Just get the title of the inventory. For enderchests it should be something like container.enderchest

    Sendt fra min ALE-L21 med Tapatalk
     
  8. Offline

    Drkmaster83

    I suppose your way would work, but something that could help is that you can check the type of the inventory
    Code:
    if(e.getInventory().getType() == InventoryType.ENDER_CHEST)
    if(e.getInventory().getType() == InventoryType.CHEST)
    
    An important note is that this does not provide a distinction between double chest and regular chest, but you can obtain that information by checking the size of the Inventory (54 vs 27). This way, it's a bit more reliable.

    Additionally, a bit more insight as to why the InventoryHolder is null: I believe that an InventoryHolder must be tied to the physical block, so a chest and double chest are the only blocks created in their location with that inventory, however the enderchest draws from saved nbt data in the player's save file and just opens it as an inventory that can be modified and saved again, so there cannot be one specific block with the same inventory data in two separate locations).
     
  9. Offline

    Rhiannon

    Great, thanks a lot!
     
  10. Offline

    Zombie_Striker

    @Rhiannon
    If your problem has been solved, mark this thread a solved.
     
Thread Status:
Not open for further replies.

Share This Page