Solved InventoryClickEvent - How do I get inventory after the event?

Discussion in 'Plugin Development' started by BaddCamden, May 10, 2022.

  1. Offline

    BaddCamden

    Now, I have seen other forums talking about this same problem but afaik they all end with either
    - I ended up using a different event OR
    - "Manually change the inventory like the event would" and no more posts after

    I am unsure how to manually change the inventory like the event would because most of the solutions I came up with cause issues with other code.
    Here is my code if it is needed for this problem:

    EDIT: I edited the code so the variables are slightly more readable and some of the unpolished code was fixed.

    Code:
        @EventHandler
        public void onInventoryInteract(InventoryClickEvent event) {
          
            for(String key : database.getConfigurationSection("Storage").getKeys(false)) {
                boolean brek = false;
                for(String p : database.getConfigurationSection("Storage."+key+".players").getKeys(false)) {
                    Player pa = ((Player)event.getWhoClicked());
                    if(p.equalsIgnoreCase(pa.getDisplayName())) {
                        if(event.getCurrentItem() != null && event.getCurrentItem().getType().equals(Material.RED_STAINED_GLASS_PANE)) {
                            for(String pl : database.getConfigurationSection("Storage."+key+".players").getKeys(false)) {
                                Player player = Bukkit.getPlayer(pl);
                                player.closeInventory();
                              
                            }
                            Entity e = Bukkit.getEntity(UUID.fromString(key));
                            Location newLoc = e.getLocation();
                            newLoc.setY(newLoc.getY() + 1.42);
                            for(String item : database.getConfigurationSection("Storage."+key+".inventory").getKeys(false)) {
                                if(database.getItemStack("Storage."+key+".inventory."+item) == null || database.getItemStack("Storage."+key+".inventory."+item).getItemMeta().getLocalizedName().equalsIgnoreCase("noPickUp")) {
                                    continue;
                                }
                                newLoc.getWorld().dropItem(newLoc, database.getItemStack("Storage."+key+".inventory."+item));
                            }
                            ItemStack i = database.getItemStack("Storage."+key+".item");
                            i.setAmount(1);
                            if(i != null) {
                                newLoc.getWorld().dropItem(newLoc, i);
                            }
                          
                            e.remove();
                            break;
                        }
                        else {
                            int i = 0;
                            ArrayList<Integer> items = new ArrayList<Integer>();
                            int slot = 0;
                          
                            for(String row : config.getConfigurationSection("Inventories."+database.getString("Storage."+key+".type")).getKeys(false)) {
                                for(String l : config.getStringList("Inventories."+database.getString("Storage."+key+".type")+"."+row)) {
                                  
                                    if(l.equalsIgnoreCase("L")) {
                                        slot = i;
                                    } else if(l.equalsIgnoreCase("A")) {
                                        items.add(i);
                                    }
                                    i++;
                                }
                            }
                          
                            ItemStack returnedItem = null;
                            ArrayList<ItemStack> is = new ArrayList<ItemStack>();
                            for(int ai : items) is.add(pa.getOpenInventory().getTopInventory().getItem(ai)); //AI stands for additional index
                            if(event.getSlot() != slot) {
                                int aai = 0; //AAI stands for Additional Additional Index
                                for(String itemN : config.getConfigurationSection("Recipes.Loom").getKeys(false)) {
                                    boolean itemToReturn = true;
                                    for(String iN : config.getStringList("Recipes.Loom."+itemN)) { //itemN, itemName, and iN are literally all the same names for different things. So annoying. I lack creativity I know XD
                                        String itemName = "";
                                        ItemStack isItem = is.get(aai);
                                        if(isItem != null ) {
                                            if(!isItem.getItemMeta().getLocalizedName().isBlank()) {
                                                itemName = isItem.getItemMeta().getLocalizedName();
                                            } else {
                                                itemName = isItem.getType().name();
                                            }
                                          
                                      
                                          
                                        } else {
                                            itemName = "AIR";
                                        }
                                        if(!iN.equalsIgnoreCase(itemName)) {
                                            itemToReturn = false;
                                            break;
                                        }
                                          
                                      
                                        aai++;
                                    }
                                    if(itemToReturn) {
                                      
                                        returnedItem = getItemstackFromConfig(itemN);
                                        break;
                                    }
                                    aai = 0;
                                }
                                if(returnedItem != null) {
                                    event.getInventory().setItem(slot, returnedItem);
                                }
                            } else {
                              
                            }
                            Interface.saveInventory(event.getInventory(), database.getConfigurationSection("Storage."+key+".inventory"));
                            for(String pl : database.getConfigurationSection("Storage."+key+".players").getKeys(false)) {
                                Player player = Bukkit.getPlayer(pl);
                                if(player != (Player)event.getWhoClicked()) {
                                    ItemStack ia = player.getOpenInventory().getCursor();
                                    player.openInventory(player.getOpenInventory().getTopInventory());
                                    player.getOpenInventory().setCursor(ia);
                                    database.set("Storage."+key+".players."+player.getDisplayName(), "sus"); //ignore the SUS, it is an acronym my friend came up with that I am not going to explain for obvious reasons
                                    brek = true;
                                }
                            }
                            mainPlugin.saveDataBase();
                            //if(event.getCurrentItem() != null && event.getCurrentItem().getType().equals(Material.GREEN_STAINED_GLASS_PANE)) {
                              
                              
                              
                            //}
                        }
                    } else {
                        event.setCancelled(true);
                    }
                    if(brek) break;
                  
                }
              
            }
            if(event.getCurrentItem() != null && event.getCurrentItem().getItemMeta() != null && event.getCurrentItem().getItemMeta().getLocalizedName().equals("noPickUp")) {
                event.setCancelled(true);
            }
            if(event.getCursor() != null && event.getCursor().getItemMeta() != null && event.getCursor().getItemMeta().getLocalizedName().equals("noPickUp")) {
                event.setCancelled(true);
            }
        }
        @EventHandler
        public void onInventoryInteract(InventoryDragEvent event) {
            for(String key : database.getConfigurationSection("Storage").getKeys(false)) {
                boolean brek = false;
                for(String p : database.getConfigurationSection("Storage."+key+".players").getKeys(false)) {
                    Player pa = ((Player)event.getWhoClicked());
                    if(p.equalsIgnoreCase(pa.getDisplayName())) {
                            int i = 0;
                            ArrayList<Integer> items = new ArrayList<Integer>();
                            int slot = 0;
                            for(String row : config.getConfigurationSection("Inventories."+database.getString("Storage."+key+".type")).getKeys(false)) {
                                for(String l : config.getStringList("Inventories."+database.getString("Storage."+key+".type")+"."+row)) {
                                  
                                    if(l.equalsIgnoreCase("L")) {
                                        slot = i;
                                    } else if(l.equalsIgnoreCase("A")) {
                                        items.add(i);
                                    }
                                    i++;
                                }
                            }
                            ItemStack returnedItem = null;
                            ArrayList<ItemStack> is = new ArrayList<ItemStack>();
                            for(int ai : items) is.add(pa.getOpenInventory().getTopInventory().getItem(ai));
                            int aai = 0;
                            for(String itemN : config.getConfigurationSection("Recipes.Loom").getKeys(false)) {
                                boolean itemToReturn = true;
                                for(String iN : config.getStringList("Recipes.Loom."+itemN)) {
                                    String itemName = "";
                                    ItemStack isItem = is.get(aai);
                                    if(isItem != null ) {
                                        if(!isItem.getItemMeta().getLocalizedName().isBlank()) {
                                            itemName = isItem.getItemMeta().getLocalizedName();
                                        } else {
                                            itemName = isItem.getType().name();
                                        }
                                      
                                  
                                      
                                    } else {
                                        itemName = "AIR";
                                    }
                                    if(!iN.equalsIgnoreCase(itemName)) {
                                        itemToReturn = false;
                                        onLog.info("NOOOOO: "+(aai)+" itemName: "+itemName+" iN: "+iN);
                                        break;
                                    }
                                      
                                  
                                    aai++;
                                }
                                if(itemToReturn) {
                                  
                                    returnedItem = getItemstackFromConfig(itemN);
                                    break;
                                }
                                aai = 0;
                            }
                            if(returnedItem != null) {
                                event.getInventory().setItem(slot, returnedItem);
                            }
                            Interface.saveInventory(pa.getOpenInventory().getTopInventory(), database.getConfigurationSection("Storage."+key+".inventory"));
                            for(String pl : database.getConfigurationSection("Storage."+key+".players").getKeys(false)) {
                                Player player = Bukkit.getPlayer(pl);
                                if(player != (Player)event.getWhoClicked()) {
                                    ItemStack ia = player.getOpenInventory().getCursor();
                                    player.openInventory(player.getOpenInventory().getTopInventory());
                                    player.getOpenInventory().setCursor(ia);
                                    database.set("Storage."+key+".players."+player.getDisplayName(), "sus");  //ignore the SUS, it is an acronym my friend came up with that I am not going to explain for obvious reasons
                                    brek = true;
                                }
                            }
                            mainPlugin.saveDataBase();
                            //if(event.getCurrentItem() != null && event.getCurrentItem().getType().equals(Material.GREEN_STAINED_GLASS_PANE)) {
                              
                              
                              
                            //}
                        }
                    }
                    if(brek) break;
                  
                }
              
          
            if(event.getCursor() != null && event.getCursor().getItemMeta() != null && event.getCursor().getItemMeta().getLocalizedName().equals("noPickUp")) {
                event.setCancelled(true);
            }
      
        }
                  
    
     
    Last edited: May 11, 2022
  2. Offline

    Strahan

    What are you trying to do? Your code is a headache to read over. I see you are iterating your config and looping through everything on every single click/drag. That's terrible inefficient. You should just target the relevant section of your config rather than waste resources cycling everything every time. Also abstraction would save you a lot of typing and clean this up.

    Please clarify what your end goal is; what are you wanting to do here? What task is the code doing against the inventory? Also I noticed a breaking boolean. You don't need to do that. Just set a label and break to the label.
     
  3. Offline

    BaddCamden

    A few things that are just answering your other questions, you can skip if you are not interested in these answers.
    1) Sorry about the variable names, I kinda rushed them during debugging because I tried quite a few things to get it working. I really should've cleaned up the names if I was gonna put it on a forum however, I didn't think my code would help much in the first place.
    2) Looping through everything on every single click/drag is important because the inventory is similar to how the regular crafting menu works. In the regular Minecraft crafting menu, it updates when you put an item. Also, I know I can give the inventory data values to where the crafting menu slot (AKA "L" for Light_Gray_Stained_Glass) but again, this is debugging. That is for polishing and I planned to fix that.
    3) I also give the player data values just some random word instead of making a list. That was just because I was debugging a different problem.
    4) Abstraction would help but I found that it would make making a readable config for my inexperienced friends quite difficult. Like I had a similar problem where I had to give items types and subtype values instead of there being a parent root called the types/subtypes because of the complicated way of looping through them and how it increased the size of my custom items space too much. It would definitely prove to be more efficient, but until it becomes a problem/I am at the polishing stage of this section of code, I will probably let it be.

    The main question:
    As I explained in the previous answers, I am trying to create a custom crafting menu for separate objects other than a crafting bench which I can control in the config. The problem I am having is the crafting menu and the other viewing player's inventory does not update on the specific click, only the click after, because the event is before the inventory changes takes place. Manually setting the inventory (not the literal inventory but a clone so it doesn't bug out) before I have to do those computations could fix that issue.

    Updated the code, no more headaches hopefully XD
     
    Last edited: May 11, 2022
  4. Offline

    BaddCamden

  5. Offline

    Tim_M

    I mean is there any reason not to schedule a function to run 1 tick later? It's not very good to have so much code in the event listener anyway. (Sorry if the reason you can't do this is obvious in the code but I'm not reading that xD)
     
  6. Offline

    BaddCamden

    That does work, but I am scared it will end up in dupe glitches being more viable/breaking the GUI. Setting it 0 ticks still works, and I assume it does because it finishes the event but separates my code into a separate thread which takes place after it has finished. Hopefully, that will prevent issues, though it still doesn't seem like a stable solution.

    Also, again sorry about the code. A bit lengthy but I really didn't think it would provide any help with solving the problem. I still put it in though, just so I can be safe, cause I am usually wrong when I assume lol.

    Also also, what do you mean by too much code in the listener? I really am lost on how other people write bukkit code, and I have just written in whatever was convenient and readable for myself. Is there a common way to reduce the amount of code in one place that everyone does?


    For anybody wondering, this is what I put in

    Code:
            BukkitScheduler scheduler = mainPlugin.getServer().getScheduler();
            scheduler.scheduleSyncDelayedTask(mainPlugin, new Runnable() {
                public void run() {
                           //code
                        }
                },0);
     
    Last edited: May 17, 2022

Share This Page