Solved Wrong output in the InventoryClickEvent?!

Discussion in 'Spigot Plugin Development' started by JackkGC, May 18, 2016.

  1. Hey Spigot community.

    I created a custom Inventory (normal chest inv.) and filled it with a "List<ItemStack>" which I saved in the config file.
    Code (Text):
    List<ItemStack> stacks = (List<ItemStack>) getConfig().getList(("itemlist"));
    I put all stacks in the custom inventory (for loop).
    In the Inventory click event I'm asking for the clicked item with
    Code (Text):
    e.getCurrentItem()
    In my example I clicked a stack of 64 Redstone and the method returned a stack of 15 Redstone. The List in the config file says that 2 Restone stacks with 64 size are existing. In the inventory I create are these two stacks. When I click on them the method returns that I clicked a stack of 15 Redstone...
    Does ANYONE know what I am doing wrong? The strange this is that it only happens sometimes. When I regenerate the config and do the whole thing again it's often working correctly. Without changing anything in the code...
    Thx already :D
     
  2. Can you show your event method? Just want to see how you are getting the clicked item and the stack size exactly.
     
  3. Send some code and your config.yml please.
     
  4. Code (Text):

    @EventHandler
        public void adw(InventoryClickEvent e){
            if(e.getCurrentItem() != null && e.getCurrentItem().getType() != null && e.getCurrentItem().getType() != Material.AIR){
                e.setCancelled(true);
                if(e.getClickedInventory().getType() == InventoryType.PLAYER){
                    return;
                }
                List<ItemStack> stacks = (List<ItemStack>) getConfig().getList(("itempath"));
                if(stacks.contains(e.getCurrentItem())){
                    if(e.getWhoClicked().getInventory().firstEmpty() == -1){
                        e.getWhoClicked().getWorld().dropItemNaturally(e.getWhoClicked().getLocation(), e.getCurrentItem());
                    } else {
                        e.getWhoClicked().getInventory().addItem(e.getCurrentItem());
                    }



                    if(stacks.remove(e.getCurrentItem())){
                        if(debug == true){
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage("Item was deleted!");
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage(" ");
                        }
                    } else {
                        if(debug == true){
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage("Item WAS NOT deleted!");
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage("List of the ItemStacks: " + stacks);
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage("Item which should have been removed: " + e.getCurrentItem());
                            getServer().broadcastMessage(" ");
                            getServer().broadcastMessage(" ");
                        }
                    }
                    if(stacks.isEmpty()){
                        getConfig().set("systems." + lastopened.get((Player)e.getWhoClicked()) + ".items", null);
                    } else {
                        getConfig().set("systems." + lastopened.get((Player)e.getWhoClicked()) + ".items", stacks);
                    }
                }
                saveConfig();
                reloadConfig();

                openinv((Player)e.getWhoClicked(), lastsearched.get((Player) e.getWhoClicked()));
            }
         
        }
     
    That's my whole event. Everything works fine only sometimes I get the result that the item wasn't deleted and that the clicked item was a stack of 15 Redstone. But I clicked a stack of 64...

    The config is correct I think...
    Code (Text):
        itempath:
        - ==: org.bukkit.inventory.ItemStack
          type: REDSTONE
          amount: 64
        - ==: org.bukkit.inventory.ItemStack
          type: REDSTONE
          amount: 64
     
     
  5. @Hunky524

    Code (Text):
        @EventHandler
        public void chestfill(PlayerInteractEvent e){
            if(e.getClickedBlock() != null && e.getClickedBlock().getType() == Material.getMaterial(getConfig().getInt("materialpath")) && e.getAction() == Action.RIGHT_CLICK_BLOCK && e.getPlayer().getItemInHand() != null && e.getPlayer().getItemInHand().getType() != Material.AIR){
                        e.setCancelled(true);

                        List<ItemStack> stacks;
                        if(getConfig().getList(("path")) == null){
                            stacks = new ArrayList<ItemStack>();
                        } else {
                            stacks = (ArrayList<ItemStack>) getConfig().getList(("path"));
                        }

                        //this is for stacking items (supporting custom names)
                        if(e.getPlayer().getItemInHand() != null && e.getPlayer().getItemInHand().getType() != Material.AIR){
                            ItemStack stack = e.getPlayer().getItemInHand();
                            boolean donenothing = false;
                            if(!(stacks.isEmpty())){
                                while(stack.getAmount() > 0){
                                    for(ItemStack istack : stacks){

                                        if(istack.getDurability() == stack.getDurability()
                                                && istack.getEnchantments().equals(stack.getEnchantments())
                                                && istack.getItemMeta().equals(stack.getItemMeta())
                                                && istack.getType().equals(stack.getType())
                                                && istack.getMaxStackSize() > istack.getAmount()){

                                            stack.setAmount(stack.getAmount() - 1 );
                                            istack.setAmount(istack.getAmount() + 1);
                                            donenothing = false;
                                        } else {
                                            donenothing = true;
                                        }



                                    }

                                    if(donenothing){
                                        stacks.add(stack);
                                        break;
                                    }


                                }
                            } else {
                                stacks.add(stack);
                            }

                        }
                        getConfig().set(("path"), stacks);
                        saveConfig();

                        e.getPlayer().setItemInHand(null);

                     

                 
             
            }
        }    
     
  6. So, just to make sure I have a clear understanding of what is going on:
    1) Each of the red stone ItemStacks show that they have 64 correct?
    2) When you click on it, does it give you the items? (Not necessarily the right amount)
    3) Have you tried adding ItemStacks to your list directly (hard-coded), rather than with a config?

    If you can say yes or no to these questions and post the code you currently have (in case it's changed), because I want to figure this thing out.

    When you post the code can you make sure it is formatted correctly and doesn't have big blank spaces (makes is easier to read) :)
     
  7. I did a video for explaining :D
     
  8. Ok, that is quite strange. Could you try creating new ItemStack which equals the current item, then use that ItemStack variable in all the spots where you use e.getCurrentItem(); this way, we know for certain all your code that you showed is working off the same ItemStack. I know it's not ideal because it will make a new ItemStack each time you click, but this point it's just trial and error until we find what is going on.
     
  9. I did. "item" is now a stack of 64 Redstone. And I also added some MORE debugging and got a result! My code:

    Code (Text):

    if(debug == true){
                    getServer().broadcastMessage("4: " + item);
                }

                if(true){
                    if(debug == true){
                        getServer().broadcastMessage("List contains clicked Item!");
                    }
                    if(e.getWhoClicked().getInventory().firstEmpty() == -1){
                        if(debug == true){
                            getServer().broadcastMessage("Inventory is full!");
                        }
                        e.getWhoClicked().getWorld().dropItemNaturally(e.getWhoClicked().getLocation(), item);
                    } else {
                        if(debug == true){
                            getServer().broadcastMessage("Inventory got space!");
                            getServer().broadcastMessage("Current item: " + item);
                        }
                        e.getWhoClicked().getInventory().addItem(item);
                    }
               
                    if(debug == true){
                        getServer().broadcastMessage("5: " + item);
                    }
     
    My output:
    4:ItemStack{REDSTONE x 64}
    List contains clicked Item!
    Inventory got space!
    Current item: ItemStack{REDSTONE x 64}
    5: ItemStack{REDSTONE x 10}

    WTF?! What the hell is this?!

    The line which changes the amount of the stack is:
    Code (Text):
    e.getWhoClicked().getInventory().addItem(item);
    But why? This isn't a line to edit an ItemStack?!
     
  10. Ok, well this narrows down the only possibility I can see that could be causing issues. This is a very strange issue you are having and I have never seen anything like it before. I could be entirely wrong on my reasoning here, but it's the only thing I can see. Ok here goes:



    When you broadcast the message: "Current item " + item, it correctly says that there is 64 redstone. You used the item variable meaning we know for sure that the variable contains 64 redstone.
    Later on after broadcasting the message: "5: " + item, it says that there is only 10 redstone. This is where things seem odd.
    In your video you had a stack of 10 redstone in your inventory, and the message was saying that 10 redstone was suppose to be removed. This seems waaaay too coincidental and I don't know why, I bet if you made that smaller stack a different size, the message would incorrectly display that size. The only thing I can see that could be changing the variable is when you add the item, because addItem() returns any items that could not be added while also trying to fill any previous item stacks first. I don't see how that could possibly be changing the variable, but it is the only line of code between the two broadcast messages. I have two things you can try:

    1) Makes the item variable final. This will make sure that it cannot be changed once it is initially made.
    2) In the line where you add the item to their inventory, instead of using the item variable. Just for that line replace:
    Code (Text):
    e.getWhoClicked().getInventory().addItem(item);
    with:
    Code (Text):
    e.getWhoClicked().getInventory().addItem(e.getCurrentItem());
     
  11. When I try to assign the current item to a final variable it gives out a "may not have been intialized" error.

    But anyway it's working now. Don't ask me why, but it's working...

    I don't just remove the stack now, I do this:

    Code (Text):
    Boolean deleted = false;
                 
                    for(ItemStack stack : stacks){
                     
                        if(stack.isSimilar(e.getCurrentItem())){
                            deleted = true;
                            stacks.remove(stack);
                            break;
                        } else {
                            if(debug){
                                getServer().broadcastMessage("System is broken!");
                            }
                        }
                     
                    }
                   
    Again: thanks for your help and sorry that I wasted your time :rolleyes:
     
  12. The point of desperation. :)
     
    • Funny Funny x 1