Backpacks

Discussion in 'Plugin Development' started by toxiccoke, Apr 7, 2015.

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

    toxiccoke

    I am working on a backpack plugin and was trying to make it so that each individual backpack had a unique inventory if anyone could help me out with this or guide me in the right way on how to do this
    thanks
    toxiccoke
     
  2. @toxiccoke
    Don't try to code stuff out of your comfort zone. Research and get some specific questions before asking for help. People won't help you unless you show you've made an effort.
     
    mine-care likes this.
  3. Offline

    nj2miami

    I'll throw you some ideas for you to think about.

    1. Persistence. You have to decide whether or not you want those inventories to survive restarts. If so, then you need to store everything in those individual backpacks to a file, like a YAML file.

    2. Temporary storage. You will have to temporarily store those individual inventories while the server is active. So, perhaps something like a HashMap<UUID, Inventory> where you use each player UUID to save those inventories.

    3. Retrieval. Now that you have those inventories stored, you will need a method for a player to open the inventory. For instance, create a command /backpack which sends the stored inventory to the player.

    #2 and #3 are fairly simple. On PlayerJoin, simply create a blank inventory (if there is not a previously stored one) for the player. When they execute the command, Player.OpenInventory(StoredInventory).

    The real complexity will be in serializing/de-serializing the inventory to/from a file, which should be done on server shutdown and startup.

    Hope that helped you some :)
     
    Last edited: Apr 8, 2015
    mine-care likes this.
  4. Offline

    pie_flavor

  5. Offline

    nj2miami

  6. Offline

    mine-care

    @nj2miami he wants to point out that after OP has figured how to make the backpack invs, he may use the resource provided to save the backpacks. although i would strongly recomend pure java serialization.
    Nice guidance over there =)
     
  7. Offline

    nj2miami

    I just don't really see how that resource really helps at saving an inventory at all. Use the resource to serialize the inventory into a map to store into a YAML?
     
  8. Offline

    mine-care

    @nj2miami thats right, it will turn out to be a litle... -or mabe- too much of an inefficient method. I would still recomend Java Serialization of the map, or in case of a ton of players where OP wants to save Resources on the server, Seperate serialized files per player loaded on join.
     
  9. Offline

    nj2miami

    @mine-care

    What about this? (I only post this because I have never had to save an inventory and this might be something I would use in the future if needed.)

    Also found this resource: https://bukkit.org/threads/util-saving-getting-inventories-from-a-file.164145/

    Code:
        public void save(Player p) throws IOException {
            YamlConfiguration c = new YamlConfiguration();
            c.set("inventory.armor", p.getInventory().getArmorContents());
            c.set("inventory.content", p.getInventory().getContents());
            c.save(new File(path, p.getName()+".yml"));
        }
    
    
        public void restore(Player p) throws IOException {
            YamlConfiguration c = YamlConfiguration.loadConfiguration(new File(path, p.getName()+".yml"));
            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);
        }
     
    Last edited: Apr 8, 2015
  10. Offline

    pie_flavor

    @nj2miami You can literally just set a vaue in YML to my class. Then, you can just use get() with the same path and cast it to SerializableInventory. Such is the purpose of ConfigurationSerializable. You can save and load it from the config like a String or an int, but you have to cast it when getting it.
    ItemStacks can also be handled this way.
     
  11. Offline

    nj2miami

    I'm sorry, maybe I am missing something but can you not just directly store ItemStack's to a YamlConfig?
     
  12. Offline

    mine-care

    @nj2miami i dont think so, although i never had to because im using pure Java serialization of objects
     
  13. Offline

    pie_flavor

    @nj2miami @mine-care Yes you can. You can directly save and load anything that implements ConfigurationSerializable. For crying out loud, it even has a getItemStack() method!
     
  14. Offline

    toxiccoke

    thanks for all the comments back this will help me alot thanks
     
  15. you can directly set the items to config and use config.getItemStack
    EDIT: Oops @pie_flavor already said this I didn't see it before ^^
     
  16. Offline

    CheesyFreezy

    Here's a great tutorial for the kind of section you want to do.
     
  17. Offline

    nj2miami

    I figured you could, I never developed a plugin which needed this functionality so I never looked for a .getItemStack method for config's. So I guess I am trying to figure out where your resource comes in handy?

    What benefits does it offer over simply storing an inventory to a config?

    Code:
        public void save(Player p) throws IOException {
            YamlConfiguration c = new YamlConfiguration();
            c.set("inventory.armor", p.getInventory().getArmorContents());
            c.set("inventory.content", p.getInventory().getContents());
            c.save(new File(path, p.getUUID()+".yml"));
        }
     
  18. @nj2miami
    AFAIK when you store a inventory in a yaml for some reason ! Are used, this will end in an error when you try to get the inv back.
     
  19. Offline

    pie_flavor

    @DoppelRR !!<type> just means force it as a type. for example !!double 4
    @nj2miami Inventory does not implement ConfigurationSerializable. Possibly one of the most annoying missing Bukkit features, you cannot store an inventory directly to a config. It will error you into next week. You can only directly store classes that implement ConfigurationSerializable in your config.
    By the way, if you decide to use my class, remember to call ConfigurationSerialization.registerClass(SerializableInventory.class) in your onEnable() before you load the config.
     
  20. Offline

    nj2miami

    FYI: I am using a 1.8 build on Bukkit so I am not sure if it was not ConfigSerializable pre 1.8 as I did not test it against that build.

    I decided to test out my theory and found nothing wrong with it. I was able to store my entire inventory, even my custom enchants from my other plugin I have written saved perfectly. Item durability, custom lore, custom display names, everything 100% accurate.

    Saved with this:

    Code:
    YamlConfiguration c = new YamlConfiguration();
    c.set("inventory.content", p.getInventory().getContents());
    try {
      c.save(new File(main.getDataFolder(), p.getUniqueId() + ".yml"));
      main.getLogger().log(Level.INFO, "{0} inventory saved.", p.getName());
    } catch (IOException ex) {
      // error logging
    }
    Then simply restored and delivered in a custom inventory (which could easily have been my actual player inventory)

    Code:
    //create a blank 54 space inventory
    Inventory inv = Bukkit.createInventory(null, 54, "Loaded Inventory");
    // loads YML based on player UUID
    YamlConfiguration c = YamlConfiguration.loadConfiguration(new File(main.getDataFolder(), p.getUniqueId() + ".yml"));
    // loads contents into ItemStack array
    ItemStack[] content = ((List<ItemStack>) c.get("inventory.content")).toArray(new ItemStack[0]);
    
    int loc = 0;  // counter to determine location to place item in inventory
    for(ItemStack i : content) {
          // removed code to parse for my custom enchants as it was not on topic
          if(i != null) inv.setItem(loc++, i);
          else loc++;
    }
    // opens saved inventory (you could easily make this just overwrite player inventory on login)
    p.openInventory(inv);
     
Thread Status:
Not open for further replies.

Share This Page