See if inventories are the same?

Discussion in 'Plugin Development' started by Kepler_, Oct 18, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Kepler_

    How can I check if two inventory objects are holding the same inventory?

    I tried the .equals method...
    player1.getInventory.equals(player2.getInventory);

    but even if the two players are looking at the same inventory, this returns false. Any idea how to do this?
     
  2. Offline

    _Filip

    try player1.getInventory() == player2.getInventory();
    getInventory() is a method.
     
  3. Offline

    Jogy34

    That does pretty much the same thing that he's already doing.

    You can't compare bukkit inventories like that, it isn't supported correctly. I use this:
    Code:java
    1.  
    2. public static boolean isSameInventory(Inventory first, Inventory second)
    3. {
    4. return ((CraftInventory) first).getInventory().equals(((CraftInventory) second).getInventory());
    5. }
    6.  

    You do have to be sure that you're using the Craftbukkit.jar, not just he Bukkit.jar though and the package name for CraftInventory will change on most bukkit updates
     
  4. Offline

    drtshock

    Just check the inventory title

    Inventory#getTitle() then .equalsIgnoreCase to check if the titles are the same.
     
  5. Offline

    Kepler_

    Jogy's method seems to be the best. Just checking the inventory title won't work because two different inventories can have the same title.
     
  6. Offline

    drtshock

    No it's not because it requires you to go around the API and use nms :(

    Use getTitle is a great way to check if the inventory is a custom inventory you created or something. If you need to check if the contents are equals then get the inventory as an ItemStack[] and check it with that.

    Suggesting NMS when there is an easy way to do this with the API is bad practice and should not be done. Teach people to do things the proper way, not the hacky way that will break between each minecraft version.
     
  7. Offline

    Jogy34


    Your method won't work if you're not checking for a custom inventory and even if you are, it isn't a guarantee. For instance, if there is a plugin out there that renames chest inventories then someone may rename the inventory to the exact same name as your custom one and then that would probably screw everything up. My method is a lot more reliable as long as you don't mind updating a few numbers every update. And if you really don't want to NMS then I would suggest doing something much more accurate like this:
    Code:java
    1.  
    2. public static boolean isSimmilarInventory(Inventory first, Inventory second)
    3. {
    4. if(first == null && second == null) return true;
    5. if((first == null && second != null) || (first != null && second == null)) return false;
    6. if(!first.getTitle().equals(second.getTitle())) return false;
    7. if(first.getType() != second.getType()) return false;
    8. ItemStack[] firstContents = first.getContents();
    9. ItemStack[] secondContents = second.getContents();
    10. if(firstContents.length != secondContents.length) return false;
    11. for(int i = 0; i < firstContents.length; i++)
    12. {
    13. if(firstContents == null && secondContents == null) continue;
    14. else if(firstContents == null && secondContents != null) return false;
    15. else if(secondContents == null && firstContents != null) return false;
    16. else if(!firstContents.isSimilar(secondContents)) return false;
    17. }
    18. return true;
    19. }
    20.  


    Also, the Bukkit API should really have some way of checking the equality of inventories.

    As a side note, messing with NMS/Craftbukkit code is a lot more fun than just using the Bukkit API.
     
  8. Offline

    drtshock

    If you enjoy mesing with NMS then go look through leaky and make some pull requests :3

    Yes, checking the contents by comparing an array of itemstacks is great. But telling people that are just getting in to making plugins to use NMS when there is a way to do it with the API is silly.
     
  9. Offline

    Jogy34

    I meant that I like using NMS code in my plugins as you can do quite a bit more with it.

    And from the looks of it, Kepler_ isn't just getting into plugin making. He has 2, not too bad, plugins on bukkit dev. And even still, the isSimmilarInventory() method I posted still isn't 100% foolproof (although I don't exactly know about the NMS way being 100% foolproof either) so I would still feel safer with the NMS way, not to mention, it's probably more efficient as well.
     
  10. Offline

    Kepler_

    Checking the title isn't going to be a good way for me to check for inventory equality because it can be changed in my plugin's config, and can be easily changed to something like "Chest," in which case all chest inventories would be considered the same as my inventory. Using NMS seems like it would work, but I don't want to have to update my code just to make my plugin compatible with a newer version of bukkit.
    I wound up writing this method that checks all the values in two inventories to determine if they're the same. Let me know if you think there is a more efficient way to do this without using NMS code.
    Code:
    public static boolean compareInvs(Inventory inv0, Inventory inv1){
    if (!inv0.getHolder().equals(inv1.getHolder())) return false;
    if (!inv0.getName().equals(inv1.getName())) return false;
    if (inv0.getSize() != inv1.getSize()) return false;
    if (!inv0.getTitle().equals(inv1.getTitle())) return false;
    if (!inv0.getType().equals(inv1.getType())) return false;
    if (inv0.getSize() != inv1.getSize()) return false;
    if (inv0.getViewers().size() != inv1.getViewers().size()) return false;
    for (int index = 0; index < inv0.getSize(); index++){
    ItemStack a = inv0.getItem(index);
    ItemStack b = inv1.getItem(index);
    if (!((a == null && b == null) || a.equals(b))) return false;
    }
    for (int index = 0; index < inv0.getViewers().size(); index++){
    HumanEntity a = inv0.getViewers().get(index);
    HumanEntity b = inv1.getViewers().get(index);
    if (!((a == null && b == null) || a.equals(b))) return false;
    }
    return true;
    }
     
Thread Status:
Not open for further replies.

Share This Page