Help with saving/load Inventory

Discussion in 'Spigot Plugin Development' started by Dantesudante, Jun 9, 2017.

  1. Hi, how can I save an Inventory of Not Player ( Like Vauts/Chest/EnderChest) in a YAML? I have to create a Yaml with uuid of Player and then, when player close his inventory I have to save every item inside the Inventory, converting it to string, in a yaml? Or there are other ways?
     
    #1 Dantesudante, Jun 9, 2017
    Last edited: Jun 9, 2017
  2. To save an inventory you can use:
    Code (Text):
    private ItemStack[] invcontent = p.getInventory().getContents();
    config.set("inventory", invcontent);
    To load this inventory it is a bit more complicated, because this is saved as a list. So you have to convert this list back to an array of ItemStacks:
    Code (Text):
    ArrayList<ItemStack> content = (ArrayList<ItemStack>) config.getList("inventory");
    ItemStack[] items = new ItemStack[content.size()];
    for (int i = 0; i < content.size(); i++) {
        ItemStack item = content.get(i);
        if (item != null) {
            items[i] = item;
        } else {
            items[i] = null;
        }
    }

    p.getInventory().setContents(items);
     
    • Agree Agree x 2
  3. ScarabCoder

    ScarabCoder Retired Resource Staff
    Retired

    I believe you could also do something like:

    Code (Text):
    ItemStack[] contents = new ItemStack[0];
    contents = configItemList.toArray(contents);
     
     
  4. If you're going to make the entire array yourself, you can at least make it the size of configItemList so #toArray doesn't have to resize for you.

    Keep in mind the various inventory types (e.g. PlayerInventory) which store extra items, like armor.
     
  5. Every slot of the inventory is getting saved (also the armor slots).
     
  6. What about a general Inventory? ( Like Vaults or Chest)
     
  7. No, it doesn't. That's why #getArmorContents exists. #getContents is defined once in Inventory, implemented once in CraftInventory, and not touched again.

    Same story, if you want to support them you need to serialize the extra items associated with it. A chest/standard inventory is the exception here, there's no extra items!
     
  8. I tried and it does!

    In the following I'm talking about the PlayerInventory
    #getStorageContents returns only the real inventory to store items in.
    #getExtraContents returns the Offhand
    #getArmorContents returns the four armor slots
    #getContents returns all slots

    https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/Inventory.html#getContents--
     
  9. MC version?

    Code (Java):
        public ItemStack[] getContents() {
            ItemStack[] items = new ItemStack[getSize()];
            net.minecraft.server.ItemStack[] mcItems = getInventory().getContents();

            int size = Math.min(items.length, mcItems.length);
            for (int i = 0; i < size; i++) {
                items[i] = mcItems[i] == null ? null : CraftItemStack.asCraftMirror(mcItems[i]);
            }

            return items;
        }
    It's very possible this is a more recent change, you won't see it compatibly work in earlier versions (1.8 and below). If this was a change, it wasn't on the craftbukkit end (entirely) but nms (the return of #getContents from the IInventory from nms).
     
  10. Code (Text):
        public void yamlCreate(Player player) {
            Inventory player_inv = PlayerInventory.inv.get(player.getUniqueId());
            File directoryinv = new File(Bukkit.getServer().getPluginManager().getPlugin("PluginTest").getDataFolder(),  "PlayersInventory");
            File playerFile = new File (directoryinv , player.getUniqueId().toString()+".yml");
            FileConfiguration playerData = YamlConfiguration.loadConfiguration(playerFile);
         
            if (!directoryinv.exists()) {
                directoryinv.mkdirs();
            }
         
            if (!(playerFile.exists())) {
                try {
                    playerFile.getParentFile().mkdirs();
                    playerFile.createNewFile();
                } catch (IOException e) {
                }
            }
          else {
                  yamlSave(playerData, player_inv);
                  }
        }
     
        public void yamlSave(FileConfiguration a, Inventory b) {
         
            a.set("Inventory", b.getContents());
        }
    Something like that should work? (save Inv)
     
  11. Newest 1.12 Spigot Version but it's in spigot since at least 1.11. Further behind i didn't check
     
  12. Yeah, that would be an NMS change then. the craftbukkit code makes no attempt to get anything but the return of #getContents from NMS.
     
  13. I would suggest that you store these inventories in Base64 rather than in a list form, it makes handling much easier. Serializing inventories allows you to access them in a much more performance friendly way than looping through lists to save and load
     
    • Like Like x 1
  14. Base64 encoding actually requires more operations, and more work to keep it updated with the new versions, whereas the default serialisation provided by Bukkit is updated for you.
     
  15. Oh any kind is fine, I was more pointing him in that direction rather than storing whole inventories in individual itemstacks in a file :p
     
  16. How can I save in String (inside a yml) Enchants of a ItemStack?
    I tried with:
    Code (Text):
                   
                    Map<Enchantment,Integer> isEnch = is.getEnchantments();
                   
                    if (isEnch.size() > 0)
                    {
                        for (Entry<Enchantment,Integer> ench : isEnch.entrySet())
                        {
                            serializedItemStack += ":[email protected]" + ench.getKey().getId() + "@" + ench.getValue();
                            conf.set("Slot "+ i_string +".Enchant", isEnch);
                        }
                    }
                   
                    serialization += i + "#" + serializedItemStack + ";";
                }
     
  17. Can someone help me?
     
  18. Enchants should save with the default itemstack serialization that was shown above.