Saving Inventory

Discussion in 'Spigot Plugin Development' started by MakingTheMagic, Jun 1, 2016.

  1. Hello all!

    I am trying to save an inventory on player leave, and restore it on join/command. For some reason this method isn't creating a file/folder when ran, and it just sends a NullPointerException to console.

    Any ideas?

    Code (Text):
      public static void saveInventory(Player p) throws IOException {
                 File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
                 FileConfiguration c = YamlConfiguration.loadConfiguration(f);
                 c.set("inventory.armor", p.getInventory().getArmorContents());
                 c.set("inventory.content", p.getInventory().getContents());
                 c.save(f);
             }

             @SuppressWarnings("unchecked")
             public static void restoreInventory(Player p) throws IOException {
                 File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
                 FileConfiguration c = YamlConfiguration.loadConfiguration(f);
                 ItemStack[] content = ((List<ItemStack>) c.get("inventory.armor")).toArray(new ItemStack[0]);
                 p.getInventory().setArmorContents(content);
                 content = ((List<ItemStack>) c.get("inventory.content")).toArray(new ItemStack[0]);
                 p.getInventory().setContents(content);
             }
    Thanks,
    Any advice will be highly appreciated! :D
     
  2. Can you post the error so we can see what line the NPE is happening on?
     
  3. Code (Text):
    org.bukkit.command.CommandException: Unhandled exception executing command 'invreset' in plugin MyPlugin v2.8
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.CommandBlockListenerAbstract.executeCommand(CommandBlockListenerAbstract.java:218) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.CommandBlockListenerAbstract.a(CommandBlockListenerAbstract.java:103) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.BlockCommand.b(BlockCommand.java:77) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.WorldServer.a(WorldServer.java:733) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.WorldServer.doTick(WorldServer.java:245) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.MinecraftServer.D(MinecraftServer.java:776) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.DedicatedServer.D(DedicatedServer.java:400) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.MinecraftServer.C(MinecraftServer.java:660) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:559) [spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
        at java.lang.Thread.run(Thread.java:745) [?:1.8.0_72]
    Caused by: java.lang.NullPointerException
        at net.mini.mcd.main.MainClass.restoreInventory(MainClass.java:190) ~[?:?]
        at net.mini.mcd.commands.InvReset.onCommand(InvReset.java:54) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot-1.9.jar:git-Spigot-104c8c8-00d3334]
     
    I tried restoring the inventory on command, so that's why its "unhandled exception"

    Line 190 is
    Code (Text):
      ItemStack[] content = ((List<ItemStack>) c.get("inventory.armor")).toArray(new ItemStack[0]);
     
  4. So the NPE is happening on line 190 of your Main.class inside your restoreInventory method. Can you highlight which line is 190, since the code snippet doesn't have line numbers :p
     
  5. Line 190:
    ItemStack[] content = ((List<ItemStack>) c.get("inventory.armor")).toArray(new ItemStack[0]);

    Also, there must be an issue with the save method as it would've created the file, right?
     
  6. Ok so it looks like c.get("inventory.armor") is coming back as null. So when you try to call toArray() on it, it throws a NPE. You're right. The problem is with your save method. You need to call f.createNewFile() to actually make the file.
     
  7. Thanks, I will try this now!
     
  8. Also be mindful of what you want to do if that File already exists. I truthfully don't know what happens if you call createNewFile() on a file that already exists.

    Could do something like:
    Code (Text):
    File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");

    if(!f.exists()){
      f.createNewFile();
    }
     
  9. Code (Text):
      public static void saveInventory(Player p) throws IOException {
                 File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
                 FileConfiguration c = YamlConfiguration.loadConfiguration(f);
                 if(f.exists())
                 {
                 c.set("inventory.armor", p.getInventory().getArmorContents());
                 c.set("inventory.content", p.getInventory().getContents());
                 c.save(f);
                 }else{
                     f.createNewFile();
                 }
             }

             @SuppressWarnings("unchecked")
             public static void restoreInventory(Player p) throws IOException {
                 File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
                 FileConfiguration c = YamlConfiguration.loadConfiguration(f);
                 if(f.exists())
                 {
                 ItemStack[] content = ((List<ItemStack>) c.get("inventory.armor")).toArray(new ItemStack[0]);
                 p.getInventory().setArmorContents(content);
                 content = ((List<ItemStack>) c.get("inventory.content")).toArray(new ItemStack[0]);
                 p.getInventory().setContents(content);
                 }else{
                     f.createNewFile();
                 }
             }
    Ok, this is my code now. It creates the file but nothing is put into the file.
     
  10. Becauuse you never called it again..
    Within the else block, call "saveInventory(p);"
     
  11. Just ran a quick test. This worked for me:
    Code (Text):
    File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
                 YamlConfiguration yaml = new YamlConfiguration();

    yaml.set("test", "123");//write something to the yaml

    yaml.save(f);
    Just modify it to suit your needs
     
  12. Where do I put that?
     

  13. Code (Text):
                 ItemStack[] content = ((List<ItemStack>) c.get("inventory.armor")).toArray(new ItemStack[0]);
    that still causes an error and stops it from restoring? How would I fix this?

    Also, I tried your save method and it didn't work for me.
     
  14. It would go in your saveInv so like this:
    Code (Text):
    public static void saveInventory(Player p) throws IOException {
                 File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
                 YamlConfiguration yaml = newYamlConfiguration();
                 yaml.set("inventory.armor", p.getInventory().getArmorContents());
                 yaml.set("inventory.content", p.getInventory().getContents());
                 yaml.save(f);
             }
     
  15. That does not work, I tried it.
     
  16. For it to work your restore method has to look something like this:
    Code (Text):
    File f = new File("plugins/Testing/test.yml");
                if(f.exists())
                {
                    YamlConfiguration yaml = YamlConfiguration.loadConfiguration(f);
                   
                    List<ItemStack> armor = (List<ItemStack>) yaml.getList("inventory.armor");
                    List<ItemStack> inventory = (List<ItemStack>) yaml.getList("inventory.content");

                }
    This works for me. Loads the inventory back. Lemmi know if you have questions about what it's doing
     
  17. How would I set it to the player? Because its not the other way?
     
  18. Just replace:
    File f = new File("plugins/Testing/test.yml");//This was just my testing file

    with:
    File f = new File(plugin.getDataFolder() + "/inventories/", p.getUniqueId().toString() + ".yml");
     
  19. I mean like set the contents of the inventory because its using a different method, how do it do it? :)