First slot of NBT Inventories won't save

Discussion in 'Spigot Plugin Development' started by Creeoer, May 13, 2016.

  1. Creeoer

    Supporter

    So I've been making a "backpack" plugin for the ranks on my server and am using NBT Compounds to save the data. While it works fine for the most part, I'm not sure why the first slot of the inventories refuse to save. Here's my packhandler class, hopefully I've made a blunt mistake:
    Code (Text):
    package creeoer.net.eagletowny.main;

    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.zip.GZIPInputStream;

    import net.minecraft.server.v1_9_R1.ItemStack;
    import net.minecraft.server.v1_9_R1.NBTCompressedStreamTools;
    import net.minecraft.server.v1_9_R1.NBTTagCompound;
    import net.minecraft.server.v1_9_R1.NBTTagList;

    import org.bukkit.Bukkit;
    import org.bukkit.craftbukkit.v1_9_R1.inventory.CraftItemStack;
    import org.bukkit.inventory.Inventory;

    import creeoer.net.eagletowny.utils.BackUtils;
    import creeoer.net.eagletowny.objects.BackType;

    public class PackHandler {
        /*
         * The scope of this class is save and load inventories from NBT Files
         */
        EagleTowny main;

        protected PackHandler(EagleTowny instance) {
            main = instance;
           
            File dir = new File(main.getDataFolder() + File.separator + "playerdata");
           
            if(!dir.exists())
                dir.mkdirs();
        }

        public void saveInventory(String fileName, Inventory inv)
                throws IOException {
            File file = new File(main.getDataFolder() + File.separator
                    + "playerdata" + File.separator + fileName + ".nbt");

            if (!file.exists())
                file.createNewFile();

            OutputStream os = new FileOutputStream(file);
            NBTTagList items = new NBTTagList();

            int invSize = inv.getSize();

            for (int slot = 0; slot < invSize; slot++) {
                org.bukkit.inventory.ItemStack stack = inv.getItem(slot);
                if (stack != null) {
                    // It loops through the entire ivnetory, and creates a new nbt
                    // tag compund for each itemstack
                    // It then adds these compounds to the compound list
                    NBTTagCompound item = new NBTTagCompound();
                    item.setByte("Slot", (byte) slot);
                    CraftItemStack.asNMSCopy(stack).save(item);
                    items.add(item);
                }
            }

            NBTTagCompound nbt = new NBTTagCompound();
            nbt.set("Items", items);
            NBTCompressedStreamTools.a(nbt, os);
            os.close();
           
        }

        public Inventory getInventory(String fileName) throws IOException {
            // Filename: creeoer-trainee-1.nbt
            File file = new File(main.getDataFolder() + File.separator
                    + "playerdata" + File.separator + fileName + ".nbt");
            if (!file.exists())
                throw new FileNotFoundException();

            String[] split = fileName.split("-");

            BackType type = BackUtils.getTypeFromString(split[1]);

            Inventory inv = Bukkit.createInventory(null, type.getSlots(),
                    "Your Pack");
            DataInputStream in = new DataInputStream(new GZIPInputStream(
                    new FileInputStream(file)));
            NBTTagCompound nbt = NBTCompressedStreamTools.a(in);
            NBTTagList items = nbt.getList("Items", 10);
           
            if (items == null)
                return null;
           
            for (int i = 0; i < inv.getSize(); i++) {
       
                NBTTagCompound item =(NBTTagCompound) items.get(i);
                if(item == null){
                    return null;
                }
                byte slot = item.getByte("Slot");
                if (slot >= 0 && slot < inv.getSize()) {
                    org.bukkit.inventory.ItemStack itemStack = CraftItemStack
                            .asCraftMirror(ItemStack.createStack(item));
                    inv.setItem(slot, itemStack);
                }
            }
            in.close();
            return inv;
        }
    }
     
     
  2. I don't know why its not saving the first item but they way you are saving and loading your inventory appears to return null if the inventory isn't full when you save it.

    In this method:
    Code (Text):
    Inventory getInventory(String fileName) throws IOException {
    You only add items to the list if they exist in the inventory (this is logical, I would continue to do this) but when you are loading them you are still expecting "inv.getSize()" items in your list.

    Code (Text):
    NBTTagCompound item =(NBTTagCompound) items.get(i);
                if(item == null){
                    return null;
                }
    Side note: The get method in NBTTagList instantiates a new NBTTagCompound if the list doesn't contain contain the index or doesn't store NBTTagCompounds so it won't return null. (
    Edit: Speaking of which, I just found a bug in one of my libs, thanks!)

    This line here is the issue
    Code (Text):
    for (int i = 0; i < inv.getSize(); i++) {
    as you should be iterating over the size of the list, not the size of the inventory.
     
    #2 MrBlobman, May 13, 2016
    Last edited: May 13, 2016