1.15.2 IllegalArgumentException on Player.openInventory?

Discussion in 'Spigot Plugin Development' started by Emilius123, Feb 9, 2020.

  1. Hi. Currently, I am developing a plugin that uses inventories as user interface. I don't want any of these inventories to be just "skipable" by closing them. So I implemented a Listener for the InventoryCloseEvent.
    Code (Java):
        //Prevents the inventory from being closed
        @EventHandler
        public void onInventoryClosed(InventoryCloseEvent e) {
            e.getPlayer().openInventory(e.getInventory());
        }
    When trying that out, I get very strange results. The first time, I get a huge StackOverflowError.
    Stack too long. Check it here: https://pastebin.com/raw/szwnjRAE
    After some "flashing" of the inventory, it opens then.

    The second time though, things run different. When rejoining (to open the inventory again) and doing the same, I get a IllegalArgumentException with the note "Can't open a CRAFTING inventory!"

    What did I do wrong? How can I fix that behaviour?
     
  2. As far as I know, you can't open some inventories via openInventory. For workbench use openWorkbench.
     

  3. Edit: In addition to that you need to filter the inventories that your mechanic only applies to your custom inventories and not to every container.
     
    • Like Like x 1
  4. The InventoryCloseEvent is fired every time an inventory is closed, including when it is closed because another inventory is opened. That's what happened in your first case - you had an inventory open, your new one opened, the close of the previous tripped another opening, and so on.
    The second attempted to reopen what I believe is the player's default inventory, which you cannot do.

    Don't blindly attempt to open an inventory on inventory close, ensure that inventory being closed is actually your "unskippable" inventory and whatever goal you have for the player inside of it has is not not yet accomplished.
    It may be a good idea to track players who are supposed to be opening the inventory and ignore close events until the InventoryOpenEvent completes to prevent the risk of future StackOverflowErrors.
     
  5. Try just doing e.setCanceled(true) or use a task to open the inventory a tick later, I think you are opening an inventory while an inventory is trying to close but not yet closed which forces the inventory closed which creates a loop of infinitely closing inventories
     
  6. Not cancellable
     
    • Informative Informative x 1
  7. Ok so not cancellable(thanks @robertlit ) So your best bet is 1 make sure its the proper inventory then 2 use a task to call openInventory a tick later
    Code (Java):
                    new BukkitRunnable() {
                        @Override
                        public void run() {
                           e.getPlayer().openInventory(e.getInventory);
                           cancel();
                        }
                    }.runTaskLater(this, 1);
     
    Boom Bobs your uncle.
     
    • Agree Agree x 1
  8. Strahan

    Benefactor

    This isn't a repeating task, cancel() is not necessary.
     
    • Agree Agree x 1
  9. Yea I'm a lil OCD when it comes to runnables... that cancel() prolly isnt needed but it hurts my brain not to cancel a runnable :p
     
    • Funny Funny x 1