Help with serialized NBTTagCompounds?

Discussion in 'Plugin Development' started by caseif, Dec 16, 2012.

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

    caseif

    I'm trying to add a feature to my plugin which allows a virtual inventory to retain NBT tags via SQLite, but it's not working properly at all. For some reason, it a) disallows stacking for other material not run through the chest, and b) seemingly doesn't retain any NBT tags. Here's my code for serialization:
    Code:java
    1. CraftItemStack craftItemStack = ((CraftItemStack)itemStack);
    2. NBTTagCompound tc = craftItemStack.getHandle().tag;
    3. net.minecraft.server.ItemStack is = craftItemStack.getHandle();
    4. NBTTagCompound itemCompound = new NBTTagCompound();
    5. itemCompound = is.save(itemCompound);
    6. itemCompound.remove("slot");
    7. itemCompound.remove("damage");
    8. itemCompound.remove("count");
    9. itemCompound.remove("id");
    10. String serial = new String(NBTCompressedStreamTools.a(itemCompound), "ISO-8859-1");
    11. conn = null;
    12. st = null;
    13. try {
    14. Class.forName("org.sqlite.JDBC");
    15. String dbPath = "jdbc:sqlite:" + plugin.getDataFolder() + File.separator + "chestdata.db";
    16. conn = DriverManager.getConnection(dbPath);
    17. st = conn.createStatement();
    18. st.executeUpdate("INSERT INTO nbt (owner, itemid, serial, slot) VALUES ('" +
    19. player.getName() +
    20. "', '" +
    21. itemStack.getTypeId() +
    22. "', '" +
    23. escape(serial) +
    24. "', '" +
    25. i +
    26. "')");
    27. }

    And my code for deserialization:
    Code:java
    1. res = sta.executeQuery("SELECT * FROM nbt WHERE owner = '" + p + "' AND slot = '" + i + "'");
    2. String serial = res.getString("serial");
    3. NBTTagCompound c = NBTCompressedStreamTools.a(serial.getBytes("ISO-8859-1"));
    4. c.remove("slot");
    5. c.remove("damage");
    6. c.remove("count");
    7. c.remove("id");
    8. CraftItemStack cis = null;
    9. if (invI[I] instanceof CraftItemStack){[/I]
    10. [I]cis = ((CraftItemStack)invI[I]);[/I][/I]
    11. [I]}[/I]
    12. [I]else if (invI[I] instanceof ItemStack){[/I][/I]
    13. [I]cis = new CraftItemStack(invI[I]);[/I][/I]
    14. [I]}[/I]
    15. [I]cis.getHandle().tag = c;[/I]
    16. [I]invI[I] = cis;[/I][/I]

    Ignore the "[ /i ]"s on the end. :)
     
  2. Offline

    fireblast709

    cis.setTag(NBTTagCompound)? cis.c(NBTTagCompound)?
     
  3. Offline

    netherfoam

    You should be able to store everything in just the serial, to save from stripping NBT tags and reapplying them. E.g. Stack size is stored in the NBT tag.. So why would you strip it and store it normally?

    This is pretty much exactly the same as my post.. So I'll repost my solution edited a little:


    To save a blank inventory:
    Code:java
    1.  
    2. //Creating.. Blank inventory.. any size...
    3. public void create(){
    4. NBTTagCompound c = new NBTTagCompound();
    5. NBTTagList list = new NBTTagList();
    6. c.set("inventory", list);
    7. byte[] data = NBTCompressedStreamTools.a(c);
    8. String inventory = database.escape(new String(data, "ISO-8859-1"));
    9. //Database query goes here... INSERT INTO thingy (otherThingy, inv) VALUES ('6', '"+inventory+"');
    10. }
    11.  




    Code:java
    1.  
    2.  
    3. //Saving... the given inventory.. any size...
    4. public void save(Inventory inv){
    5. NBTTagCompound c = new NBTTagCompound();
    6. NBTTagList list = new NBTTagList();
    7. for(int index = 0; index < inv.getContents().length; index++){
    8. CraftItemStack cis = (CraftItemStack) inv.getItem(index);
    9. if(cis != null){
    10. net.minecraft.server.v1_4_5.ItemStack is = cis.getHandle();
    11. NBTTagCompound itemCompound = new NBTTagCompound();
    12. itemCompound = is.save(itemCompound);
    13. itemCompound.set("index", new NBTTagInt("index", index));
    14. list.add(itemCompound);
    15. }
    16. }
    17. c.set("inventory", list);
    18.  
    19. byte[] bytes = NBTCompressedStreamTools.a(c);
    20. String str = escape(new String(bytes, "ISO-8859-1"));
    21. //Database query goes here
    22. }
    23.  



    Code:java
    1.  
    2. //Loading... The given inventory serialized... inv must be big enough to hold the serialized version.
    3. /** Puts the given serialized inventory into the given inventory. */
    4. public void load(String s, Inventory inv) throws EncodingNotSupportedException{
    5. NBTTagCompound c = NBTCompressedStreamTools.a(s.getBytes("ISO-8859-1"));
    6. NBTTagList list = c.getList("inventory");
    7.  
    8. for(int i = 0; i < list.size(); i++){
    9. NBTTagCompound item = (NBTTagCompound) list.get(i);
    10. int index = item.getInt("index");
    11. net.minecraft.server.v1_4_5.ItemStack is = net.minecraft.server.v1_4_5.ItemStack.a(item);
    12. CraftItemStack cis = new CraftItemStack(is);
    13. inv.setItem(index, cis);
    14. }
    15. }
    16.  


    How it works:
    This code doesn't save individual items. It saves whole inventories. [Won't save armour. You'll need to add in a little workaround for that because armour isnt technically... inventory.]

    It clumps every item in the inventory into a list, and gives the item the property "index" AKA slot ID. The list is then stored in the compound NBT tag. NBTCompressedTools allows you to convert this into a byte array, which you can then convert to a string and store somewhere easily.

    You can convert the string back to a byte[], and use NBTCompressedTools to convert a byte[] to an NBT tag again.. you can fetch the slot ID using the "index" previously stored.. then you use net.minceraft.server to convert the NBT tag to a NMS itemstack... and craftbukkit to convert the NMS to a craftitemstack.. AKA a normal item stack.
     
  4. Offline

    caseif

    OH MY GOD I LOVE YOU RIGHT NOW. It took quite a bit of tweaking of my old code, but I finally got it working properly. I honestly feel like I'm speaking a foreign language when I'm working with NBT. Thanks a ton for all the help.
     
Thread Status:
Not open for further replies.

Share This Page