1.14.4 Check gui items

Discussion in 'Spigot Plugin Development' started by Franchiccosd, Feb 8, 2020.

  1. I have to make a GUI where you will put items that will be saved to a config by clicking on a Confirm button in the gui, but for some reasons when i try to get the gui items all the items are null.
     
  2. Could you post your code? It'll be hard to help you without it.
     
  3. private void saveItems(Player player) {

    for (ItemStack item : inv.getContents()) {
    if (item != null) {
    // Save item
    }
    }
    }
     
  4. This still doesn't explain what's wrong with the saving. Are you serializing the inventory then saving it to a file? How are you doing it. Post the whole code.
     
  5. the problem is not with the saving system, it works fine, the only thing is that when i use the method i sent you, all the items get from gui are null and idk why
     
  6. if i remove the != null check it will spam lot of NullPointerException errors in console
     
  7. We are going to need to see some more code:
    • How are you getting the inventory?
      • If it is a player inventory, can we see a picture of it?
      • If you created it, did you fill it?
    • Where is this method being called?
    • You will probably want to check for that confirm "button"
     
  8. You prolly need to loop thru the slots when saving so that you can put items back in the same slot.

    Oh and save the slots when you save the items ;) I usually use the slot # as the index for a map
     
  9. this is the method that i used:

    Code (Java):
        private void saveItems(Player player) {
            for (int row = 1; row <= 4; row++) {
                for (int column = 1; column <= 7; column++) {
                    int slot = 9 * row + column;
                    if (inv.getItem(slot) != null && !Objects.requireNonNull(inv.getItem(slot)).getType().equals(Material.AIR)) {
                        ItemStack item = inv.getItem(slot);
                        if (item != null) {
                            XItemStack.saveItemStack(item, ChatListener.skullData.get(player), column + row);
                        }
                    }
                }
            }
        }
    note that the items i want to save are sorrounded by glasses
     
  10. you dont need Objects.requireNonNull(inv.getItem(slot)) because you just did a check for null

    if (item != null) { another redundant null check

    XItemStack.saveItemStack(item, ChatListener.skullData.get(player), column + row);

    column 3 row 2 = 5
    column 2 row 3 = 5

    maybe use slot instead?
     
  11. I have been working on a plugin with a mobile Inventory and used these 2 functions. May not be the most elegant way but you can try saving the Hashmap data in your config.

    Code (Text):

        HashMap<Player, ItemStack[]> savedInventory = new HashMap<Player, ItemStack[]>();

        /**
         * Saves the inventory inv of p in the HashMap savedInventory
         */
        public void saveInv(Player p, Inventory inv) {

            ItemStack[] invtosave = new ItemStack[inv.getSize()];

            for (int i = 0; i < inv.getSize(); i++) {

                invtosave[i] = inv.getItem(i);
                savedInventory.put(p, invtosave);
            }
        }

        /**
         * Loads the inventory of p from HashMap
         */
        public void loadInv(Player p, Inventory inv) {

            ItemStack[] empty = new ItemStack[inv.getSize()];

              //Checks for HM entry
            if (savedInventory.get(p) == null) {

                for (int i = 0; i < inv.getSize(); i++) {
                    empty[i] = null;
                }
                inv.setContents(empty);
            } else {
                for (int i = 0; i < inv.getSize(); i++) {

                    inv.setContents(savedInventory.get(p));

                }
            }
        }
     
     
  12. it's better to use UUID instead of Player, as a key in hashmaps, 1. less memory usage, u can not compare 2 players object, (only inside properties as UUID).
    in the save method u can just clone the inv's contents.
    for your save method did not could understand why you using void and not opening the inventory, so I just return it, and changing it's contents if there is already saved one.
    it will not save item's order tho.
     
    • Like Like x 1
  13. 1. No
    2. You can

    Even thou your point is valid, the reasoning is not. Please stop spreading wrong information
     
    • Agree Agree x 2
  14. It's code from a project a few months ago which i abandoned. This was mostly written in theory without proper testing and focus on efficiency. Even though i can't think of a reason why uuid would use up more memory (maybe you could explain that), thank you for pointing out those improvements. Definitely more elegant that way (y)
     
  15. The whole more memory thing is fake news (really) but you should use the uuid, storing the player object in a hash map requires you to make extra code to get it out of there if they log off or loose connection. player object in a map causes a hard reference, any object with a hard reference will not get cleaned up by garbage collection. So player logs out its in a map so player doesnt get removed and wont because they arent actually on to meet any of your action requirements so now you have memory that cant be freed up, thats called a memory leak. Its just less code to use the uuid and safer.
     
    • Agree Agree x 2
  16. Code (Java):
        private void saveItems(Player player) {

            for (int i = 0; i <= inv.getSize() - 1; i++) {
                ItemStack item = inv.getItem(i);
                if (item != null) {
                    if (!item.getItemMeta().getDisplayName().equals("§3Grind§bSkulls") && !item.getItemMeta().getDisplayName().equals("§aDone")) {
                        XItemStack.saveItemStack(item, ChatListener.skullData.get(player), i);
                    }
                }
            }
        }
    i tried this but its still not working
     
  17. https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/ItemStack.html#hasItemMeta--

    if(item != null && item.hasItemMeta()) // check the item has meta before you blindly try to get info from meta that could be null

    for (int i = 0; i <= inv.getSize() - 1; i++) should be for (int i = 0; i < inv.getSize(); i++)

    I never use the special color character, instead use https://hub.spigotmc.org/javadocs/s...ateAlternateColorCodes-char-java.lang.String-

    It could be the color thing but I am unsure. It gave me problems years ago and I stopped using it.

    you could alos use https://hub.spigotmc.org/javadocs/spigot/org/bukkit/ChatColor.html#stripColor-java.lang.String-
    to strip the colors out of the string before you check
     
    • Agree Agree x 1
  18. i had to add inv.getSize() - 1 otherwise it have get me an ArrayOutOfBounds exception. And i don't think that the problem is with colors because when i click on done button i don't get any error in console
     
  19. the <= let it go out of bounds just < keeps it in bounds in this instance

    if you are getting null errors, you need to check that the item has meta and that the it has the key you want before you try to use .equals
     
  20. Code (Java):
        private void saveItems(Player player) {

            for (int i = 0; i < inv.getSize(); i++) {
                ItemStack item = inv.getItem(i);
                if (item != null && item.hasItemMeta()) {
                    if (!item.getItemMeta().getDisplayName().equals("§3Grind§bSkulls") && !item.getItemMeta().getDisplayName().equals("§aDone")) {
                        XItemStack.saveItemStack(item, ChatListener.skullData.get(player), i);
                    }
                }
            }
        }
    i tried this but the problem is that like the plugin won't recognise the item that i add to the gui in game and when i click on done button nothing happens and any of the items in the gui aren't saved