Serialize Inventory to single string and vice versa

Discussion in 'Resources' started by Phil2812, Aug 9, 2012.

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


    It's a good idea to look up the source code in these cases, and it appears that
    asNMSCopy() returns NULL if the item stack contains AIR (like the armor slots in your case).

    So - you should be able to fix this by checking that the return type of asNMSCopy() is not NULL as well.
  2. Offline


    if((craft != null) || (CraftItemStack.asNMSCopy(itemStack) != null))

    Sorry if I'm mistaken on doing this, but I figured this would be able to check if asNMSCopy() is not null and then if it isn't, continue to save the object. However I'm still receiving an NPE, am I doing something wrong?
  3. Offline


    Hm - in the if-statement itself? Or inside the CraftItemStack.asNMSCopy() method?

    Perhaps you could post your stack trace.
  4. Offline


  5. Offline


    You should use "&&" (short-circuit and) instead of "||" in this if-statement. In addition, it's probably best to only execute asNMSCopy() once.

    But if you're trying to serialize a player inventory, you'll probably need more than just the armor content. What about the held item index and player name? With some, err, heavy modifications, you can add that information to the output format (only supports 1.7.9):

    Which would allow you to do the following:
    1. String serialized = ItemSerialization.toBase64(((Player) sender).getInventory());
    2. System.out.println(serialized);
    4. Inventory inventory = ItemSerialization.fromBase64(serialized);
    5. System.out.println(
    6. "Armor: " + Arrays.asList(((PlayerInventory) inventory).getArmorContents())
    7. );
    Toni likes this.
  6. Offline


    I give u all my money with love <3 Thank you so much. This is so much more I can't even thank you enough!

    Quick edit:

    I see you said it works for 1.7.9 only :/ I'm still waiting on 1.7.5 before I update to 1.7.9 until I'm finished preparing for the UUID updates. Is there anyway things inside the serialization class such as the NBTReadLimiter to be excluded unless it's mandatory for it to function?
  7. Offline


    You could simply remove it:
    1. private static NBTBase readNbt(DataInput input, int level) {
    2. if (READ_NBT == null) {
    3. try {
    4. // NBTReadLimiter is new in 1.7.9
    5. READ_NBT = NBTCompressedStreamTools.class.getDeclaredMethod("a", DataInput.class, int.class);
    6. READ_NBT.setAccessible(true);
    7. } catch (Exception e) {
    8. throw new IllegalStateException("Unable to find private read method.", e);
    9. }
    10. }
    12. try {
    13. return (NBTBase) READ_NBT.invoke(null, input, level);
    14. } catch (Exception e) {
    15. throw new IllegalArgumentException("Unable to read from " + input, e);
    16. }
    17. }

    That should work with 1.7.5, if you also remember to update the package version.
  8. Offline


    So those are my current classes - however when I try to give myself a kit I get the stacktrace reported in that gist. Would you have any ideas?
  9. Offline


    Ah, yeah, I forgot to restrict the size of getContents():
    1. @Override
    2. public ItemStack[] getContents() {
    3. return Arrays.copyOf(super.getContents(), getSize());
    4. }

    Seeing how I store both the inventory content and the armor in a slightly larger custom inventory (which is similar to how PlayerInventory is actually implemented in Minecraft).

    I've updated my Gist with this method.
    Toni likes this.
  10. Offline


    Thank you so much for your help. Saving inventories and loading them again (including armor!) works flawlessly, color, lore, etc, everything is included. I'm so happy :D and this is 1.7.9 ready so when I do update I'll still have this working *tears* thank you so much again.
    Comphenix likes this.
  11. Offline


    @Comphenix i've been looking for something like this to save users inv to a file... since i am learning all of this, how would i use this and an example to save and then load at my leasure?
    i already know how to replace the inv.. just saving it and loading it with this... is wherei be stucks
    Thank you for any help :)
  12. Offline


    Is there an easy way of adding items to a serialised inventory. I basically want to add items when a player is offline!
  13. Offline


    Scullyking Deserialise it, then add the items and serialise it again. I don't think there's another way to do that.
  14. Offline


  15. Offline


    I'm not sure where is my mistake.
    I get this error:

    On line 308 I have:
    1. Arrays.asList(((PlayerInventory) inventory).getArmorContents());
  16. Offline


    I think you've imported the wrong PlayerInventory. It should be org.bukkit.inventory.PlayerInventory, not NMS.inventory:
    1. import org.bukkit.inventory.PlayerInventory;
    Pr07o7yp3 likes this.
  17. Offline


    Yup, I'm so stupid... That was the probem. Ty :)
    I have to look more carefully when Eclipse ask me what to import.
    Comphenix likes this.
  18. I added saving name item and lore ;)

    import java.util.ArrayList;
    import java.util.Map;
    import java.util.Map.Entry;
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    public class ParkourInv {
       public static String InventoryToString(Inventory invInventory) {
         String serialization = invInventory.getSize() + ";";
         for (int i = 0; i < invInventory.getSize(); i++) {
           ItemStack is = invInventory.getItem(i);
           if (is != null) {
             String serializedItemStack = new String();
             String isType = String.valueOf(is.getType().getId());
             serializedItemStack += "[email protected]" + isType;
             if (is.getDurability() != 0) {
               String isDurability = String.valueOf(is.getDurability());
               serializedItemStack += ":[email protected]" + isDurability;
             if (is.getAmount() != 1) {
               String isAmount = String.valueOf(is.getAmount());
               serializedItemStack += ":[email protected]" + isAmount;
             if (is.hasItemMeta()) {
               String isMeta = String.valueOf(is.getItemMeta()
               serializedItemStack += ":[email protected]" + isMeta;
             if (is.hasItemMeta()) {
               String isLore = String.valueOf(is.getItemMeta().getLore());
               if (!(isLore == null)) {
                 serializedItemStack += ":[email protected]" + isLore;
             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();
             serialization += i + "#" + serializedItemStack + ";";
         return serialization;
       public static Inventory StringToInventory(String invString) {
         String[] serializedBlocks = invString.split(";");
         String invInfo = serializedBlocks[0];
         Inventory deserializedInventory = Bukkit.getServer().createInventory(
             null, Integer.valueOf(invInfo));
         for (int i = 1; i < serializedBlocks.length; i++) {
           String[] serializedBlock = serializedBlocks[i].split("#");
           int stackPosition = Integer.valueOf(serializedBlock[0]);
           if (stackPosition >= deserializedInventory.getSize()) {
           ItemStack is = null;
           Boolean createdItemStack = false;
           String[] serializedItemStack = serializedBlock[1].split(":");
           for (String itemInfo : serializedItemStack) {
             String[] itemAttribute = itemInfo.split("@");
             if (itemAttribute[0].equals("t")) {
               is = new ItemStack(Material.getMaterial(Integer
               createdItemStack = true;
             } else if (itemAttribute[0].equals("d") && createdItemStack) {
             } else if (itemAttribute[0].equals("a") && createdItemStack) {
             } else if (itemAttribute[0].equals("m") && createdItemStack) {
               ItemMeta isM = is.getItemMeta();
             } else if (itemAttribute[0].equals("l") && createdItemStack) {
               ItemMeta isM = is.getItemMeta();
               String removeBuckle = itemAttribute[1].substring(1,
                   itemAttribute[1].length() - 1);
               ArrayList<String> l = new ArrayList<String>();
               for (String podpis : removeBuckle.split(", ")) {
             } else if (itemAttribute[0].equals("e") && createdItemStack) {
                   .valueOf(itemAttribute[1])), Integer
           deserializedInventory.setItem(stackPosition, is);
         return deserializedInventory;
  19. Offline


    <insert something witty about necromancy and thread locking>
Thread Status:
Not open for further replies.

Share This Page