How to save and load itemstacks to files!

Discussion in 'Plugin Development' started by EvilPeanut, Apr 8, 2013.

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

    EvilPeanut

    Hey all, I have written a very useful class for you all to use!
    This is a 'itemStack' which can be serialized, saved to a file, then loaded and turned back into an itemStack and keeps all its properties (Enchantments, lores, meta display name, data, typeID ect...)!!!!!

    First put this code into a class named SerializableItemStack
    Code:
    import java.io.Serializable;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.material.MaterialData;
     
    @SuppressWarnings("serial")
    public class SerializableItemStack implements Serializable {
        public int amount, typeID;
        public byte data;
        public short durability;
        public String displayName;
        public Map<Enchantment, Integer> enchantmentList = new HashMap<Enchantment, Integer>();
        public List<String> lore;
       
        public SerializableItemStack(ItemStack itemStack) {
            amount = itemStack.getAmount();
            durability = itemStack.getDurability();
            enchantmentList = itemStack.getEnchantments();
            typeID = itemStack.getTypeId();
            data = itemStack.getData().getData();
            displayName = itemStack.getItemMeta().getDisplayName();
            lore = itemStack.getItemMeta().getLore();
        }
       
        public ItemStack toItemStack() {
            ItemStack newStack = new ItemStack(typeID, amount);
            newStack.setData(new MaterialData(typeID, data));
            newStack.setDurability(durability);
            newStack.addEnchantments(enchantmentList);
            ItemMeta newMeta = newStack.getItemMeta();
            newMeta.setLore(lore);
            newMeta.setDisplayName(displayName);
            newStack.setItemMeta(newMeta);
            return newStack;
        }
    }
    You can then load and save this class to a file using
    Code:
        //
        // Save Object Into A File
        //
        public void saveObject(Object obj, String path) throws Exception {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
            oos.writeObject(obj);
            oos.flush();
            oos.close();
        }
     
        //
        // Load Object From A File
        //
        public Object loadObject(String path) throws Exception {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
            Object result = ois.readObject();
            ois.close();
            return result;
        }
    Example of saving an itemStack to a file
    Code:
    // Save the itemStack of the player boots to the file 'boots.inv'
    saveObject(new SerializableItemStack(player.getInventory().getBoots()), "boots.inv");
    Example of loading an itemStack from a file
    Code:
    // Load the itemStack of the player boots from the file 'boots.inv'
    SerializableItemStack boots = (SerializableItemStack) loadObject("boots.inv");
    player.getInventory().setBoots(boots.toItemStack());
     
    Maulss and justcool393 like this.
  2. Offline

    Nitnelave

    ItemStack is already ConfigurationSerializable, which is ok for most uses.
     
  3. Offline

    EvilPeanut

    Its not, is it? When i tried to use it in its serialized form i got errors that it cant be serialized.
     
  4. Offline

    Nitnelave

    I don't know the details of how it works, but it implements ConfigurationSerializable. It probably means that you can save it and load it from the config without doing any serialization yourself.
     
  5. Offline

    evilmidget38

    EvilPeanut ItemStacks are already ConfigurationSerializable so you can use the Bukkit Configuration API to easily save and load them.
    Code:java
    1.  
    2. ItemStack item = getConfig().getItemStack("somePath");
    3. ...
    4. getConfig().set("somePath", item);
    5.  


    If you're determined to use an OOS and not use Bukkit's configuration API, I wrote a tutorial on how to properly serialize and deserialize an ItemStack here.
     
    Zen3515 likes this.
  6. Offline

    Zen3515

    if have randomly create this code will this code can generate New YML file?
    Code:
                File SaveArmordotyml = new File(getDataFolder(),"//" + player.getName() + ".yml");
                FileConfiguration SaveArmordotymlasCon = YamlConfiguration.loadConfiguration(SaveArmordotyml);
     
  7. Offline

    RedmanCometh

    Hey I made a slight change to add lore and display name, so as not to cause issues with custom items.
    I wasn't sure how to directly de-serialize strings from yaml though, so I just did it manually. There might be a better way.
    Anyways here is the code
    Code:java
    1. package Util;
    2. import java.util.ArrayList;
    3. import java.util.Arrays;
    4. import java.util.List;
    5. import java.util.Map;
    6. import java.util.Map.Entry;
    7.  
    8. import org.bukkit.Bukkit;
    9. import org.bukkit.Material;
    10. import org.bukkit.enchantments.Enchantment;
    11. import org.bukkit.inventory.Inventory;
    12. import org.bukkit.inventory.ItemStack;
    13. import org.bukkit.inventory.meta.ItemMeta;
    14. public class InventorySerializer
    15. {
    16. @SuppressWarnings("deprecation")
    17. public static String InventoryToString(Inventory invInventory)
    18. {
    19. String serialization = invInventory.getSize() + ";";
    20. for (int i = 0; i < invInventory.getSize(); i++)
    21. {
    22. ItemStack is = invInventory.getItem(i);
    23. if (is != null)
    24. {
    25. String serializedItemStack = new String();
    26. String isType = String.valueOf(is.getType().getId());
    27. serializedItemStack += "t@" + isType;
    28.  
    29. if (is.getDurability() != 0)
    30. {
    31. String isDurability = String.valueOf(is.getDurability());
    32. serializedItemStack += ":d@" + isDurability;
    33. }
    34.  
    35. if (is.getAmount() != 1)
    36. {
    37. String isAmount = String.valueOf(is.getAmount());
    38. serializedItemStack += ":a@" + isAmount;
    39. }
    40.  
    41. Map<Enchantment, Integer> isEnch = is.getEnchantments();
    42. if (isEnch.size() > 0)
    43. {
    44. for (Entry<Enchantment, Integer> ench : isEnch.entrySet())
    45. {
    46. serializedItemStack += ":e@" + ench.getKey().getId() + "@" + ench.getValue();
    47. }
    48. }
    49. if(is.hasItemMeta())
    50. {
    51. ItemMeta imeta = is.getItemMeta();
    52. if(imeta.hasDisplayName())
    53. {
    54. serializedItemStack += ":dn@"+imeta.getDisplayName();
    55. }
    56. if(imeta.hasLore())
    57. {
    58. serializedItemStack += ":l@"+imeta.getLore();
    59. }
    60. }
    61. serialization += i + "#" + serializedItemStack + ";";
    62. }
    63. }
    64. return serialization;
    65. }
    66.  
    67. @SuppressWarnings({ "deprecation"})
    68. public static Inventory StringToInventory(String invString)
    69. {
    70. String[] serializedBlocks = invString.split(";");
    71. String invInfo = serializedBlocks[0];
    72. Inventory deserializedInventory = Bukkit.getServer().createInventory(null, Integer.valueOf(invInfo));
    73.  
    74. for (int i = 1; i < serializedBlocks.length; i++)
    75. {
    76. String[] serializedBlock = serializedBlocks[i].split("#");
    77. int stackPosition = Integer.valueOf(serializedBlock[0]);
    78.  
    79. if (stackPosition >= deserializedInventory.getSize())
    80. {
    81. continue;
    82. }
    83.  
    84. ItemStack is = null;
    85. Boolean createdItemStack = false;
    86. ItemMeta im = null;
    87. String[] serializedItemStack = serializedBlock[1].split(":");
    88. for (String itemInfo : serializedItemStack)
    89. {
    90. String[] itemAttribute = itemInfo.split("@");
    91. if (itemAttribute[0].equals("t"))
    92. {
    93. is = new ItemStack(Material.getMaterial(Integer.valueOf(itemAttribute[1])));
    94. createdItemStack = true;
    95. im=is.getItemMeta();
    96. }
    97. else if (itemAttribute[0].equals("d") && createdItemStack)
    98. {
    99. is.setDurability(Short.valueOf(itemAttribute[1]));
    100. }
    101. else if (itemAttribute[0].equals("a") && createdItemStack)
    102. {
    103. is.setAmount(Integer.valueOf(itemAttribute[1]));
    104. }
    105. else if (itemAttribute[0].equals("e") && createdItemStack)
    106. {
    107. is.addEnchantment(Enchantment.getById(Integer.valueOf(itemAttribute[1])), Integer.valueOf(itemAttribute[2]));
    108. }
    109. else if (itemAttribute[0].equalsIgnoreCase("dn"))
    110. {
    111. im.setDisplayName(itemAttribute[1]);
    112. }
    113. else if (itemAttribute[0].equalsIgnoreCase("l"))
    114. {
    115. List<String> lore = new ArrayList<String>();
    116. itemAttribute[1]=itemAttribute[1].replace("[", "");
    117. itemAttribute[1]=itemAttribute[1].replace("]", "");
    118. lore=Arrays.asList(itemAttribute[1].split(","));
    119. for(int x = 0; x<lore.size(); x++)
    120. {
    121. String s = lore.get(x);
    122. if(s.charAt(0)==' ')
    123. {
    124. s=s.replaceFirst(" ", "");
    125. }
    126. lore.set(x, s);
    127. }
    128. im.setLore(lore);
    129. }
    130. }
    131. if(im.hasDisplayName()||im.hasLore())
    132. {
    133. is.setItemMeta(im);
    134. }
    135. deserializedInventory.setItem(stackPosition, is);
    136. }
    137. return deserializedInventory;
    138. }
    139. }[/i]
     
  8. Online

    CraftCreeper6

  9. Offline

    RedmanCometh

    It may be a year old, but it's also rather useful. Extending it's usefulness is purely constructive, and making a new thread with someone else's code (albeit with minor tweaks) is kind of lame.
     
  10. Offline

    ChipDev

    This should be in resources, but this has already been created.
    Reported. (Not for a bad reason :p) so it gets moved!
     
Thread Status:
Not open for further replies.

Share This Page