Solved Best way of checking if a player is inside of our custom GUI

Discussion in 'Spigot Plugin Development' started by Lockface77, May 29, 2020.

  1. Hello,

    I am creating a custom GUI for my plugin and I was wondering what is the best way to check if a player is in our GUI or not.

    I had the idea of checking the name but 2 problems come:
    1. It may interfeer with other plugin, if two have the same name then RIP
    2. The name can be changed in the config, so if the user deside to refresh the config, changing the name, if a user have the GUI oppened then it will break.
    So I have been looking in the internet to find a good solution. What I found is this: https://www.spigotmc.org/threads/qu...r-is-interacting-with-your-custom-gui.225871/

    Which I thought was a very good way of doing it, because it is safe.

    Then I tried to know what was the InventoryHolder interface (nobody should use something that he don't undestand I guess ^^).

    So I found this post: https://www.spigotmc.org/threads/what-is-the-inventoryholder-interface.342812/

    Which complety discourage the method told in the first link given.

    So I am a little bit confused about what to do for my GUI.

    Oh and in the tutorial I used: https://www.spigotmc.org/wiki/creating-a-gui-inventory/
    they compare the Inventory object, which is not possible in my case because every player will have a different GUI menu.
     
  2. You are very well on your way! Inventory name checking is the easiest solution, but it is also unsafe (and has been deprecated in later Spigot versions).
    The InventoryHolder class is indeed the solution. In my opinion, the first post explains it very well. You need to implement the InventoryHolder class, and overide the getInventory() method. Then in the inventory event, you can use the instanceof check to make sure it is your inventory!

    The code required is exactly in the first post! :D

    EDIT:
    Oh hold on, I misread the first post a bit. The way they are using is a bit strange in my opnion. It will still work, but I would do this:
    Code (Text):
    public class CoolInventory implements InventoryHolder {

        public Inventory getInventory() {
            Inventory inventory = Bukkit.createInventory(this, [size], [title]);
           
            // Do some cool inventory stuff in here
           
            return inventory;
        }
    }
    Then in the event, you can do the same instanceof check as in the post.
     
    • Like Like x 1
    • Winner Winner x 1
  3. Thank you for your answer. I will do the same thing as in the tutorial so because your code wont work for me because I need to have a parameter to create the inventory depending on the player.

    Do you know more about the InventoryHolder interface? Because in the second post they say that this method of doing it is deprecated :(
     
  4. Thanks for this, I've always had this problem, and you've explained it well. :)
     
  5. It was apparently not supposed to be used like that however nothing happened since they mentioned that they'll remove/deprecate it until now. You should ideally identify by reference but since inventory holders are still working fine i don't see a problem in using them. Note that custom inventory holders won't work for all inventory types.
     
  6. Hmm, that's a good question. It might be true, but I don't know. I just checked, and the Bukkit.createInventory method with InventoryHolders is not deprecated in the latest version, and that post is from 2018. So somehow, the PR did not get through.

    This definately works though! You can add additional information to the inventory via the constructor of the CoolInventory class.
    For example:

    Inventory holder class:
    Code (Text):
    public class CoolInventory implements InventoryHolder {

        private String closeMessage;

        public CoolInventory(String closeMessage) {
            this.closeMessage = closeMessage;
        }
       
        public String getCloseMessage() {
            return closeMessage;
        }

        public Inventory getInventory() {
            Inventory inventory = Bukkit.createInventory(this, [size], [title]);
         
            // Do some cool inventory stuff in here
         
            return inventory;
        }
    }
    Listener class:
    Code (Text):
    public class InventoryListener implements Listener {
       
        public void onClose(InventoryCloseEvent event) {
            if (!(event.getInventory().getHolder() instanceof CoolInventory)) return;
           
            CoolInventory inventory = (CoolInventory) event.getInventory().getHolder();
            event.getPlayer().sendMessage("Close message: " + inventory.getCloseMessage());
        }
       
    }
    Now if you do:
    Code (Text):
    public void openCoolInventory(Player player) {
        CoolInventory inventory = new CoolInventory("Custom: " + player.getName());
        player.openInventory(inventory);
    }
    It will open the inventory with the custom data.
    When the player closes the inventory, it will display the custom close message!
     
    • Useful Useful x 1
  7. Thank you, I have already done it with setting null, but will do this for my next plugin ;)
     
  8. Cool! Please don't forget to mark this thread as solved, for other developers!
     
    • Like Like x 1