Resource Make plugin compatible for multiple versions

Discussion in 'Spigot Plugin Development' started by SkillCode, Jul 8, 2021.

  1. Hey, for me the hardest part used to be making a plugin compatible for multiple versions. In this post I would like to show you how I made my biggest project written for 1.8 compatible for all versions up to 1.17.

    Enums/Entities/PotionEffects...
    For enums I use the library XSeries, which allows us to use enums like Material, Enchantment... version independent.
    Example:
    Code (Java):
    itemStack.setType(XMaterial.STONE.parseMaterial());
    Inventories
    Since you can't access the title of an inventory in higher versions, you need an alternative. I have found a simple solution for this: Store the name of the inventory in a map during creation, with the player as key and the inventory name as value. In the InventoryCloseListener you then remove the player from the map. If you now want to know which inventory the player has opened, you can proceed as follows:

    Code (Java):
    @EventHandler
        public void onClick(final @NotNull InventoryClickEvent event) {
            final Player player = (Player) event.getWhoClicked();
            if (... .inventoryMap.containsKey(player)
                    && inventoryMap.get(player).equals(inventoryName)){
                //your code
            }
        }
    Packets
    If you can't do without packets, I recommend ProtocolLib

    That's it! Please write a comment if I have forgotten something.
     
    • Like Like x 3
    • Informative Informative x 1
  2. XSeries definitely will help me, thx
     
  3. There is no need to post facts that someone knows.
     
    • Funny Funny x 3
  4. They were just saying that the posted resource would help them, don't really see that as an issue.

    On a side note, nice resource. I'm sure a lot of people will find this extremely useful.
     
  5. Exactly, I would like to help people with this post who have the same problems I had before :)
     
    • Like Like x 1
  6. This sounds dum af id recomend doing it this way:
    Create a simple interface like this:

    Code (Java):
    public interface GUI extends InventoryHolder {
        void onInventoryClick(InventoryClickEvent event);
    }
    Then create your inventoryClick

    Code (Java):
    @EventHandler
        public void onInventoryClick(InventoryClickEvent event) {
            if (event.getClickedInventory() != null && event.getInventory().getHolder() != null && event.getInventory().getHolder() instanceof GUI) {
                event.setCancelled(true);
                if(event.getClickedInventory() == event.getInventory()) {
                    ((GUI) event.getInventory().getHolder()).onInventoryClick(event);
                }
            }
        }
    Then you can just create your GUI class

    Code (Java):
    public class MyCustomInventory extends GUI {
        @Override
        public Inventory getInventory() {
            Inventory inventory = Bukkit.createInventory(this, 27, "Inventory Title");


            //Add stuff to Inventory Here
           

            return inventory;
        }

        @Override
        public void onInventoryClick(InventoryClickEvent event) {
                //Do stuff here
        }


    }
    Seems way easier imo
     
  7. Why should that be dumb? There are many ways to solve this.
     
  8. You are so funny. I didn't know about XSeries, someone probably didn't know about ProtocolLib. If you know something and you see it, just ignore it and go away. You are like LeGuernic but slightly more adequate
     
    • Agree Agree x 2
  9. I mean first of all comparing inventory names by their titles is really dum since its easier to get errors, and throwing player's and inventory titles in a hashmap just seems really hacky to me
     
    • Like Like x 1
  10. Just compare the holder. Create a class that implements InventoryHolder:
    Code (Java):

    public class MyHolder implements InventoryHolder {
        @Override
        public void getInventory() { return null; }
    }
     
    Use it as the holder, and just compare it when necessary..
     
    • Like Like x 1
  11. That was only meant as an example, you can also e.g. directly save the inventory in the map but yes you're right, saving the name is not so useful
     
  12. In my private plugins I do it like this:
    Code (Java):
    public void register(final @NotNull Player player, final @NotNull Class<? extends AbstractInventory> inventoryClass) {
            inventoryMap.put(player, inventoryClass);
        }
     
    • Creative Creative x 1
  13. Ye thats litrally what I did in my example above?
     
  14. Nah, your approach is slightly different, plus my post was just made to tell everyone the replacement of title comparison :)