1.13.2 Best way to handle InventoryHolder for custom GUI

Discussion in 'Spigot Plugin Development' started by i998979, Jan 20, 2020.

  1. I think this question has been asked by different people many times, but I still didn't get the answer I wanted, so I decided to ask on my own.

    When you create a custom inventory, you have to pass some kind of InventoryHolder to identify what type of inventory it is.
    Some of the tutorials make the custom gui class implements InventoryHolder and pass itself to #createInventory,
    but some people said that passing stuff is a misuse of it, so they pass null instead.
    I decided to read more plugin's source code and I found that some plugin even creates an empty custom InventoryHolder, and some return null (https://github.com/cervinakuy/KitPvP/tree/master/src/com/planetgallium/kitpvp/menu) and some create a new inventory in that and return that.

    I would like to know what is the best way to handle the InventoryHolder so that I can handle InventoryClick easily and update the player's inventory in same type.
     
  2. What I usually do is implement InventotyHolder and pass "this" as the holder. Then in the event listener I use an instanceof check for the holder.
     
  3. I always pass null aswell and then handle the inventory click event by checking if the clicked inventory returns null on .getLocation() - that way i know for 100 % that its a custom GUI. as for the specific identification of the GUI, i compare the GUI's title

    Code (Text):
        @EventHandler
        public void event(InventoryClickEvent ev) {

            Player p = (Player) ev.getWhoClicked();
            int s = ev.getSlot();

            if (ev.getInventory().getLocation() != null) {
                return;
            }
            if (!ev.getView().getTitle().equals(Main.getUiIdentifier())) {
                return;
            }
     
  4. What if another plugin uses an inventory with the same title?
     
  5. Extremely unlikely because i put a hidden sequence of color codes in my titles, for example i use:
    "§a§5§5§7§oASS §7||| §8User Interface§r" in this case

    those are still being compared to, but the UI user cannot see it
     
  6. Isn't just checking if the inventory is an instance of the class 100% assures the inventory is the custom one?
     
  7. You probably mean InventoryHolder
     
  8. yes
     
  9. Passing "this" in InventoryHolder isn't a good idea I think because most of the post are saying it is a misuse.
    Checking the title of custom inventory isn't a good idea too because there can be different custom inventory with same name.
    So what I'm thinking is still custom inventoryholder or something better.

    Edit: Creating an enum of gui type and check it when InventoryClick is a solution too but idk if it is a good idea or not :/
     
  10. It’s super unlikely to have two guis with the same name
     
  11. Maybe yes in some situation, but it is still quite hard to detect something like
    "Room of Player1"
    "Room of Player2"
    especially you have to handle "Player1" and "Player2" separately.
     
  12. That’s why you compare both of the names the check if they are 100% the same
     
  13. Is there a reason why not just use the InventoryHolder way?
     
  14. That's what I'm wondering...

    InventoryHolder is what holds onto the inventory.
    So (going from memory here) a Player has an InventoryHolder (Maybe it's the player's inventory but you get the idea), a Chest, an Anvil, an Enchantment table, etc.
    Anything you can visually look at the inventory for is an InventoryHolder.

    So it depends on what you want to hold onto your inventory, It might be a block in the world, it might be a player, what ever.
    Then if the player dies or block is destroyed some default behavior should occur like drop items on the ground.

    If the InventoryHolder is null, it will quite simply just exist, nothing is holding it.
     
  15. From personal experience here is my opinion on the topic:

    The usage of a custom class that implements InventoryHolder has only one issue and that is that some members of the spigot community believe it is not intended. Now you can judge a lot about what is intended or not but a long discussion about allowing custom InventoryHolder implementation was already held and in the end it seems like they are here to stay. Parker Hawke makes a really good point about their usage.

    They not only allow for a 100% accurate identification of the inventory instance but also allow the developers to attach data to those instances.
    Here are some pages that elaborate this concept:

    This way you also get rid of either hardcoding the title into the inventory check or passing around a single record-like java class to provide the title for you.

    In the end passing a plugin specific implementation of the InventoryHolder interface has a lot of advantages with the only real downside being that it may or may not be intended. And even that argument seems shaky concerning the widely adopted usage of NMS.
     
    • Useful Useful x 2
    • Like Like x 1
  16. Thanks for pointing to that stuff, that's actually super interesting to me
     
    • Agree Agree x 1
  17. Note that setting a custom InventoryHolder doesn't work for all inventory types, don't think that has changed yet.
     
  18. Thanks for the really useful information. That's what I'm thinking about, custom InventoryHolder seems to be the best way to identify different custom guis.
    But I'm still confused about what stuff should I put inside custom InventoryHolder?
    Some of them put an Inventory, some put custom inventory class, some return null directly and some do complicate stuff inside that.
    Also, it is still a problem that what should I do to trigger the overridden InventoryClickEvent in custom inventory classes.

    Edit: In some tutorials, they create the inventory object inside custom InventoryHolder, but it seems that it is a fixed number, how about different inventory size? Does it affect how everything works?
     
    #18 i998979, Jan 21, 2020
    Last edited: Jan 21, 2020