Search code examples
javaminecraftbukkit

How do I deserialize a Player's inventory?


Here's my serialization method. How would I go about deserializing/loading it later on?

invs is my inventories.yml FileConfiguration variable.

public void action(Player p){
    PlayerInventory i = p.getInventory();
    int slot = 0;
    for(ItemStack item : i){
        Map<String, Object> itemS = item.serialize();
        if(Main.invs.get(p.getName() + ".inventory.slot." + slot) == null){
            Main.invs.createSection(p.getName()+ ".inventory.slot." + slot);
        }
        Main.invs.set(p.getName() + ".inventory.slot." + slot, itemS);
        slot = slot + 1;
    }
    slot = 0;
}

Solution

  • Try this:

    public PlayerInventory deserializeInventory(Player p) {
        PlayerInventory inv = p.getInventory();
        for(int slot = 0; slot < 36 /*Size of inventory */; slot++){
            //Removes any existing item from the inventory.
            inv.clear(slot);
    
            Object itemTemp = Main.invs.get(p.getName() + ".inventory.slot." + slot);
            if (itemTemp == null) { //Skip null values.
                continue;
            }
            if (!(itemTemp instanceof ItemStack)) {
                //Might want to do an error message, but for now just ignore this.
                continue;
            }
            ItemStack item = (ItemStack) itemTemp;
            inv.setItem(slot, item);
        }
        return inv;
    }
    

    As a side note, I strongly recommend changing your serialization method to this:

    public void action(Player p){
        PlayerInventory i = p.getInventory();
        for(int slot = 0; slot < 36 /*Size of inventory */; slot++){
            ItemStack item = i.getItem(slot);
            if (item == null || item.getType() == Material.AIR) { //Do nothing.
                continue;
            }
            Map<String, Object> itemS = item.serialize();
            if(Main.invs.get(p.getName() + ".inventory.slot." + slot) == null){
                Main.invs.createSection(p.getName()+ ".inventory.slot." + slot);
            }
            Main.invs.set(p.getName() + ".inventory.slot." + slot, itemS);
        }
    }
    

    Doing this will preserve the location of the items, and also adds a few error checking things.