Saving/Loading Inventory To A File

Discussion in 'Plugin Development' started by sharp237, Mar 8, 2013.

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

    sharp237

    How can I save a player's whole inventory (including armour) to a file which I can then load again in order to give it to a player. It must be able to work with everything, such as:
    • Potions.
    • Enchanted Items (including renamed items using anvil).
    • Written Books.
    • Maps.
    • Item Damage.
     
  2. Offline

    JavaGuava

    I'm not sure that this is possible
     
  3. Offline

    sharp237

    Really?
     
  4. Offline

    -_Husky_-

    JavaGuava sharp237

    This is possible, I will prepare some code later on, if Digi doesn't beat me.

    I am currently on iPad, bit hard.

    Good luck.
     
    sharp237 likes this.
  5. Offline

    sharp237

    Ok, thanks :)
     
  6. Offline

    JavaGuava

    Oh, I didn't realise :/
     
  7. It can be very easy achieved with configs.
    You should use a diferent config but I'm gonna show an example with default one for simplicity's sake.
    Not sure if you really must loop through the contents but here's a quick way:
    Code:
    getConfig().set(player.getName() + ".inventory", player.getInventory().getContents());
    getConfig().set(player.getName() + ".armor", player.getInventory().getArmorContents());
    In any case, you can just use config.set() to set an itemstack then retrieve them by using get(), cast to ItemStack[] (that is an ItemStack array) and give them back to player.

    This will work just fine because ItemStack is serializable in config, you can use that system for your custom objects too, read here: http://wiki.bukkit.org/Configuration_API_Reference#Serializing_and_Deserializing_Objects
     
    sharp237 likes this.
  8. Offline

    sharp237

    Digi -_Husky_-

    Thanks! :)

    I made a TestPlugin in order to try this out, but I had a few problems :/ Can see whats wrong? It seems to work fine until I restart the server, then it gives an error (shown below). I think the problem is that it doesn't like casting to the ItemStack[].

    TestPlugin:

    Code:JAVA
    1. package me.sharp237.testplugin;
    2.  
    3. import java.io.File;
    4. import java.io.IOException;
    5. import java.io.InputStream;
    6. import java.util.logging.Level;
    7. import java.util.logging.Logger;
    8. import org.bukkit.command.Command;
    9. import org.bukkit.command.CommandSender;
    10. import org.bukkit.configuration.file.FileConfiguration;
    11. import org.bukkit.configuration.file.YamlConfiguration;
    12. import org.bukkit.entity.Player;
    13. import org.bukkit.event.Listener;
    14. import org.bukkit.inventory.ItemStack;
    15. import org.bukkit.plugin.PluginDescriptionFile;
    16. import org.bukkit.plugin.PluginManager;
    17. import org.bukkit.plugin.java.JavaPlugin;
    18.  
    19. public class TestPlugin extends JavaPlugin implements Listener{
    20. public final Logger logger = Logger.getLogger("Minecraft");
    21. private FileConfiguration customConfig = null;
    22. private File customConfigFile = null;
    23.  
    24. //Plugin to test saving/loading Inventories
    25.  
    26. public void onEnable()
    27. {
    28. PluginDescriptionFile pdfFile = getDescription();
    29. logger.info(pdfFile.getName() + " Version " + pdfFile.getVersion() + " Has Been Enabled");
    30. PluginManager reg = getServer().getPluginManager();
    31. reg.registerEvents(this, this);
    32. reloadCustomConfig();
    33. }
    34.  
    35. public void onDisable()
    36. {
    37. PluginDescriptionFile pdfFile = getDescription();
    38. logger.info(pdfFile.getName() + " Has Been Disabled");
    39. saveCustomConfig();
    40. }
    41.  
    42. //Method from [url]http://wiki.bukkit.org/Configuration_API_Reference[/url]
    43. public void reloadCustomConfig() {
    44. if (customConfigFile == null) {
    45. customConfigFile = new File(getDataFolder(), "customConfig.yml");
    46. }
    47. customConfig = YamlConfiguration.loadConfiguration(customConfigFile);
    48.  
    49. // Look for defaults in the jar
    50. InputStream defConfigStream = this.getResource("customConfig.yml");
    51. if (defConfigStream != null) {
    52. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    53. customConfig.setDefaults(defConfig);
    54. }
    55. }
    56.  
    57. //Method from [url]http://wiki.bukkit.org/Configuration_API_Reference[/url]
    58. public FileConfiguration getCustomConfig() {
    59. if (customConfig == null) {
    60. this.reloadCustomConfig();
    61. }
    62. return customConfig;
    63. }
    64.  
    65. //Method from [url]http://wiki.bukkit.org/Configuration_API_Reference[/url]
    66. public void saveCustomConfig() {
    67. if (customConfig == null || customConfigFile == null) {
    68. return;
    69. }
    70. try {
    71. getCustomConfig().save(customConfigFile);
    72. } catch (IOException ex) {
    73. this.getLogger().log(Level.SEVERE, "Could not save config to " + customConfigFile, ex);
    74. }
    75. }
    76.  
    77. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    78. if (cmd.getName().equalsIgnoreCase("save")){
    79. if ((sender instanceof Player)) {
    80. Player player = (Player) sender;
    81. getCustomConfig().set(player.getName() + ".inventory", player.getInventory().getContents());
    82. getCustomConfig().set(player.getName() + ".armor", player.getInventory().getArmorContents());
    83. player.getInventory().clear();
    84. }
    85. } else if (cmd.getName().equalsIgnoreCase("load")){
    86. if ((sender instanceof Player)) {
    87. Player player = (Player) sender;
    88. ItemStack[] inventory = (ItemStack[]) getCustomConfig().get(player.getName() + ".inventory");
    89. ItemStack[] armor = (ItemStack[]) getCustomConfig().get(player.getName() + ".armor");
    90. if(armor == null || inventory == null){
    91. player.sendMessage("No saved inventory to load");
    92. return true;
    93. }
    94. player.getInventory().clear();
    95. player.getInventory().setContents(inventory);
    96. player.getInventory().setArmorContents(armor);
    97. }
    98. }
    99. return true;
    100. }
    101. }
    102.  


    EDIT: For some reason the indentations havn't worked :(

    Error:

    Code:
    C:\Users\Admin\Desktop\MainPlugin\Testing>java -Xmx1G -Xms1G -jar craftbukkit.ja
    r
    210 recipes
    27 achievements
    14:00:21 [INFO] Starting minecraft server version 1.4.7
    14:00:21 [INFO] Loading properties
    14:00:21 [INFO] Default game type: SURVIVAL
    14:00:21 [INFO] Generating keypair
    14:00:21 [INFO] Starting Minecraft server on *:25565
    14:00:22 [INFO] This server is running CraftBukkit version git-Bukkit-1.4.7-R1.0
    -b2624jnks (MC: 1.4.7) (Implementing API version 1.4.7-R1.0)
    14:00:22 [INFO] [PermissionsEx] sql backend registered!
    14:00:22 [INFO] [PermissionsEx] file backend registered!
    14:00:22 [INFO] [PermissionsEx] PermissionEx plugin initialized.
    14:00:22 [INFO] [Vault] Loading Vault v1.2.23-b301
    14:00:22 [INFO] [WorldEdit] Loading WorldEdit v5.5.1
    14:00:22 [INFO] [PermissionsEx] Loading PermissionsEx v1.19.5
    14:00:22 [INFO] [PermissionsEx] Initializing file backend
    14:00:22 [INFO] Permissions file successfully reloaded
    14:00:22 [INFO] [TestPlugin] Loading TestPlugin v1.0
    14:00:22 [INFO] [Vault] Enabling Vault v1.2.23-b301
    14:00:23 [INFO] [Vault][Permission] PermissionsEx found: Waiting
    14:00:23 [INFO] [Vault][Permission] SuperPermissions loaded as backup permission
    system.
    14:00:23 [INFO] [Vault][Chat] PermissionsEx found: Waiting
    14:00:23 [INFO] [Vault] Enabled Version 1.2.23-b301
    14:00:23 [INFO] [Vault][Permission] PermissionsEx hooked.
    14:00:23 [WARNING] **** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!
    14:00:23 [WARNING] The server will make no attempt to authenticate usernames. Be
    ware.
    14:00:23 [WARNING] While this makes the game possible to play without internet a
    ccess, it also opens up the ability for hackers to connect with any username the
    y choose.
    14:00:23 [WARNING] To change this, set "online-mode" to "true" in the server.pro
    perties file.
    14:00:23 [INFO] Preparing level "world"
    14:00:23 [INFO] Preparing start region for level 0 (Seed: 1402030108942544482)
    14:00:24 [INFO] Preparing spawn area: 65%
    14:00:24 [INFO] Preparing start region for level 1 (Seed: 1402030108942544482)
    14:00:25 [INFO] Preparing spawn area: 69%
    14:00:25 [INFO] Preparing start region for level 2 (Seed: 1402030108942544482)
    14:00:26 [INFO] [WorldEdit] Enabling WorldEdit v5.5.1
    14:00:26 [INFO] WEPIF: Using the Bukkit Permissions API.
    14:00:26 [INFO] [PermissionsEx] Enabling PermissionsEx v1.19.5
    14:00:26 [INFO] [PermissionsEx] Superperms support enabled.
    14:00:26 [INFO] [PermissionsEx] v1.19.5 enabled
    14:00:26 [INFO] WEPIF: PermissionsEx detected! Using PermissionsEx for permissio
    ns.
    14:00:26 [INFO] [Vault][Chat] PermissionsEx_Chat hooked.
    14:00:26 [INFO] [TestPlugin] Enabling TestPlugin v1.0
    14:00:26 [INFO] TestPlugin Version 1.0 Has Been Enabled
    14:00:26 [INFO] Server permissions file permissions.yml is empty, ignoring it
    14:00:26 [INFO] Done (3.566s)! For help, type "help" or "?"
    14:00:32 [INFO] /127.0.0.1:60095 lost connection
    14:00:38 [INFO] sharp237[/127.0.0.1:60102] logged in with entity id 313 at ([wor
    ld] -94.71686220055156, 96.0, 319.4503425944968)
    14:00:46 [INFO] sharp237 issued server command: /load
    14:00:46 [SEVERE] null
    org.bukkit.command.CommandException: Unhandled exception executing command 'load
    ' in plugin TestPlugin v1.0
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46)
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:18
    6)
            at org.bukkit.craftbukkit.v1_4_R1.CraftServer.dispatchCommand(CraftServe
    r.java:514)
            at net.minecraft.server.v1_4_R1.PlayerConnection.handleCommand(PlayerCon
    nection.java:980)
            at net.minecraft.server.v1_4_R1.PlayerConnection.chat(PlayerConnection.j
    ava:898)
            at net.minecraft.server.v1_4_R1.PlayerConnection.a(PlayerConnection.java
    :853)
            at net.minecraft.server.v1_4_R1.Packet3Chat.handle(Packet3Chat.java:44)
            at net.minecraft.server.v1_4_R1.NetworkManager.b(NetworkManager.java:290
    )
            at net.minecraft.server.v1_4_R1.PlayerConnection.d(PlayerConnection.java
    :113)
            at net.minecraft.server.v1_4_R1.ServerConnection.b(SourceFile:39)
            at net.minecraft.server.v1_4_R1.DedicatedServerConnection.b(SourceFile:3
    0)
            at net.minecraft.server.v1_4_R1.MinecraftServer.r(MinecraftServer.java:5
    98)
            at net.minecraft.server.v1_4_R1.DedicatedServer.r(DedicatedServer.java:2
    24)
            at net.minecraft.server.v1_4_R1.MinecraftServer.q(MinecraftServer.java:4
    94)
            at net.minecraft.server.v1_4_R1.MinecraftServer.run(MinecraftServer.java
    :427)
            at net.minecraft.server.v1_4_R1.ThreadServerApplication.run(SourceFile:8
    49)
    Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to [
    Lorg.bukkit.inventory.ItemStack;
            at me.sharp237.testplugin.TestPlugin.onCommand(TestPlugin.java:88)
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
            ... 15 more
    >
     
  9. Offline

    JavaGuava

    Yea... dunno why that happens :/

    Maybe you have to use a "try{ }catch{ }" ?
     
  10. Offline

    TomTheDeveloper

    If anyone knows what is wrong about that, say it, because i also want to know what is wrong, because i am going to make a plugin where i need something of this
     
    sharp237 likes this.
  11. Offline

    sharp237

    Ok I used this and it seems to work (still testing):

    TomTheDeveloper

    Code:
    package me.sharp237.testplugin;
     
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.event.Listener;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class TestPlugin extends JavaPlugin implements Listener{
        public final Logger logger = Logger.getLogger("Minecraft");
        private FileConfiguration customConfig = null;
        private File customConfigFile = null;
     
        //Plugin to test saving/loading Inventories
     
        public void onEnable()
        {
            PluginDescriptionFile pdfFile = getDescription();
            logger.info(pdfFile.getName() + " Version " + pdfFile.getVersion() + " Has Been Enabled");
            PluginManager reg = getServer().getPluginManager();
            reg.registerEvents(this, this);
            reloadCustomConfig();
        }
     
        public void onDisable()
        {
            PluginDescriptionFile pdfFile = getDescription();
            logger.info(pdfFile.getName() + " Has Been Disabled");
            saveCustomConfig();
        }
     
        //Method from http://wiki.bukkit.org/Configuration_API_Reference
        public void reloadCustomConfig() {
            if (customConfigFile == null) {
            customConfigFile = new File(getDataFolder(), "customConfig.yml");
            }
            customConfig = YamlConfiguration.loadConfiguration(customConfigFile);
     
            // Look for defaults in the jar
            InputStream defConfigStream = this.getResource("customConfig.yml");
            if (defConfigStream != null) {
                YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
                customConfig.setDefaults(defConfig);
            }
        }
     
        //Method from http://wiki.bukkit.org/Configuration_API_Reference
        public FileConfiguration getCustomConfig() {
            if (customConfig == null) {
                this.reloadCustomConfig();
            }
            return customConfig;
        }
     
        //Method from http://wiki.bukkit.org/Configuration_API_Reference
        public void saveCustomConfig() {
            if (customConfig == null || customConfigFile == null) {
            return;
            }
            try {
                getCustomConfig().save(customConfigFile);
            } catch (IOException ex) {
                this.getLogger().log(Level.SEVERE, "Could not save config to " + customConfigFile, ex);
            }
        }
     
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (cmd.getName().equalsIgnoreCase("save")){
                if ((sender instanceof Player)) {
                    Player player = (Player) sender;
                    getCustomConfig().set(player.getName() + ".inventory", player.getInventory().getContents());
                    getCustomConfig().set(player.getName() + ".armor", player.getInventory().getArmorContents());
                    player.getInventory().clear();
                }
            } else if (cmd.getName().equalsIgnoreCase("load")){
                if ((sender instanceof Player)) {
                    Player player = (Player) sender;
                    Object a = getCustomConfig().get(player.getName() + ".inventory");
                    Object b = getCustomConfig().get(player.getName() + ".armor");
                    if(a == null || b == null){
                        player.sendMessage("No saved inventory to load");
                        return true;
                    }
                    ItemStack[] inventory = null;
                    ItemStack[] armor = null;
                    if (a instanceof ItemStack[]){
                          inventory = (ItemStack[]) a;
                    } else if (a instanceof List){
                            List lista = (List) a;
                            inventory = (ItemStack[]) lista.toArray(new ItemStack[0]);
                    }
                    if (b instanceof ItemStack[]){
                            armor = (ItemStack[]) b;
                      } else if (b instanceof List){
                          List listb = (List) b;
                          armor = (ItemStack[]) listb.toArray(new ItemStack[0]);
                      }
                    player.getInventory().clear();
                    player.getInventory().setContents(inventory);
                    player.getInventory().setArmorContents(armor);
                }
            }
            return true;
        }
    }
    
     
    JimsHD likes this.
  12. Offline

    TomTheDeveloper

    sharp237, do you already know which the a, and b are, is it a Itemstack[] or a List?
     
  13. Offline

    sharp237

    I'm sorry, I don't quite understand your question :/
     
  14. It's obivous what the problem is... the parsed value returns an ArrayList, you're casting it to an ItemStack array and that can't happen :p
    So just store it as List<ItemStack> and convert it to an array (or maybe setContents() accepts lists too, look for methods... or just loop through the player's inventory and set each slot to the list's slots).

    Also, you should avoid using try-catch at all until you get a better understanding of it... by reading its meaning and recommended uses which should written by actual experts, not youtube videos!
     
Thread Status:
Not open for further replies.

Share This Page