Can't set inventory name after loading inventory player from file

Discussion in 'Plugin Development' started by xX4w3s0m3Xx, Jun 23, 2017.

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

    xX4w3s0m3Xx

    I'm trying to create a plugin where you can have your own "double chest" as your inventory when you type in "/chest". When you type it in for the first time you get a nice chest interface with the name "Player Chest" and when you close it, it gets saved into a file. This is working perfectly fine. The problem occurs when you want to open the chest for the second time, because when you open it for the second time then the contents of the chest gets loaded from the file, but without the name "Player Chest", so when you close the interface, then the chest doesn't get saved, because I'm filtering this personal chest by the name of it:
    Code:
    if (inventory.getType() == InventoryType.CHEST && inventory.getName().equals("Player Chest")) {
                inventoryHandler.saveInventory(inventory);
            }
    These are my full codes:
    Main.java:
    Code:
    package me.Ruud.PlayerChest;
    
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryCloseEvent;
    import org.bukkit.event.inventory.InventoryType;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.plugin.java.JavaPlugin;
    
    /**
    * @author Ruud.
    */
    public class Main extends JavaPlugin implements Listener{
    
        private InventoryHandler inventoryHandler;
    
        @Override
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
        }
    
        @Override
        public void onDisable() {
    
        }
    
        @EventHandler
        public void InventoryClose(InventoryCloseEvent e) {
            Inventory inventory = e.getInventory();
            if (inventory.getType() == InventoryType.CHEST && inventory.getName().equals("Player Chest")) {
                inventoryHandler.saveInventory(inventory);
            }
        }
    
        public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
            Player player = (Player) sender;
    
            if (commandLabel.equalsIgnoreCase("chest")) {
                if (args.length == 1) {
                    Player otherPlayer = Bukkit.getServer().getPlayer(args[0]);
                    inventoryHandler = new InventoryHandler(otherPlayer);
                    if (inventoryHandler.getInventory() != null) {
                        player.openInventory(inventoryHandler.getInventory());
                    }
    
                } else {
                    inventoryHandler = new InventoryHandler(player);
                    Inventory inventory;
                    if (inventoryHandler.getInventory() != null) {
                        inventory = inventoryHandler.getInventory();
                        player.sendMessage("Opening existing Player Chest");
                        player.openInventory(inventory);
                        inventoryHandler.saveInventory(inventory);
                    } else {
                        inventory = Bukkit.createInventory(player, 54, "Player Chest");
                        player.sendMessage("Creating new Player Chest");
                        player.openInventory(inventory);
                        inventoryHandler.createPlayerConfiguration();
                        inventoryHandler.saveInventory(inventory);
                    }
                }
            }
    
            return false;
        }
    
    }
    
    InventoryHandler.java:
    Code:
    package me.Ruud.PlayerChest;
    
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.Inventory;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
    * @author Ruud.
    */
    public class InventoryHandler {
    
        Player player;
        File playerData;
        FileConfiguration playerDataConfiguration;
    
        public FileConfiguration getPlayerConfiguration() {
            return playerDataConfiguration;
        }
    
        public InventoryHandler(Player player) {
            this.player = player;
            File directory = new File("plugins/PlayerChest/Chests");
            try{
                directory.mkdirs();
            } catch (Exception e) {
                e.printStackTrace();
            }
            playerData = new File("plugins/PlayerChest/Chests/" + player.getName() + ".yml");
            playerDataConfiguration = YamlConfiguration.loadConfiguration(playerData);
        }
    
        public void createPlayerConfiguration() {
            try {
                playerData.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public Inventory getInventory() {
            if (!playerData.exists()) {
                return null;
            }
            return InventoryStringDeSerializer.StringToInventory(playerDataConfiguration.getString("InventoryHandler"));
        }
    
        public void saveInventory(Inventory inventory) {
            playerDataConfiguration.set("InventoryHandler", InventoryStringDeSerializer.InventoryToString(inventory).isEmpty() ? "" : InventoryStringDeSerializer.InventoryToString(inventory));
            try {
                playerDataConfiguration.save(playerData);
            } catch (IOException e) {
                e.printStackTrace();
            }
            player.sendMessage("Saved inventory!");
        }
    }
    
    InventoryStringDeSerializer:
    Code:
    package me.Ruud.PlayerChest;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    
    import java.util.Map;
    
    /**
    * @author Ruud.
    */
    public class InventoryStringDeSerializer {
    
        public static String InventoryToString (Inventory invInventory)
        {
            String serialization = invInventory.getSize() + ";";
            for (int i = 0; i < invInventory.getSize(); i++)
            {
                ItemStack is = invInventory.getItem(i);
                if (is != null)
                {
                    String serializedItemStack = new String();
    
                    String isType = String.valueOf(is.getType().getId());
                    serializedItemStack += "t@" + isType;
    
                    if (is.getDurability() != 0)
                    {
                        String isDurability = String.valueOf(is.getDurability());
                        serializedItemStack += ":d@" + isDurability;
                    }
    
                    if (is.getAmount() != 1)
                    {
                        String isAmount = String.valueOf(is.getAmount());
                        serializedItemStack += ":a@" + isAmount;
                    }
    
                    Map<Enchantment,Integer> isEnch = is.getEnchantments();
                    if (isEnch.size() > 0)
                    {
                        for (Map.Entry<Enchantment,Integer> ench : isEnch.entrySet())
                        {
                            serializedItemStack += ":e@" + ench.getKey().getId() + "@" + ench.getValue();
                        }
                    }
    
                    serialization += i + "#" + serializedItemStack + ";";
                }
            }
            return serialization;
        }
    
        public static Inventory StringToInventory (String invString)
        {
            String[] serializedBlocks = invString.split(";");
            String invInfo = serializedBlocks[0];
            Inventory deserializedInventory = Bukkit.getServer().createInventory(null, Integer.valueOf(invInfo));
    
            for (int i = 1; i < serializedBlocks.length; i++)
            {
                String[] serializedBlock = serializedBlocks[i].split("#");
                int stackPosition = Integer.valueOf(serializedBlock[0]);
    
                if (stackPosition >= deserializedInventory.getSize())
                {
                    continue;
                }
    
                ItemStack is = null;
                Boolean createdItemStack = false;
    
                String[] serializedItemStack = serializedBlock[1].split(":");
                for (String itemInfo : serializedItemStack)
                {
                    String[] itemAttribute = itemInfo.split("@");
                    if (itemAttribute[0].equals("t"))
                    {
                        is = new ItemStack(Material.getMaterial(Integer.valueOf(itemAttribute[1])));
                        createdItemStack = true;
                    }
                    else if (itemAttribute[0].equals("d") && createdItemStack)
                    {
                        is.setDurability(Short.valueOf(itemAttribute[1]));
                    }
                    else if (itemAttribute[0].equals("a") && createdItemStack)
                    {
                        is.setAmount(Integer.valueOf(itemAttribute[1]));
                    }
                    else if (itemAttribute[0].equals("e") && createdItemStack)
                    {
                        is.addEnchantment(Enchantment.getById(Integer.valueOf(itemAttribute[1])), Integer.valueOf(itemAttribute[2]));
                    }
                }
                deserializedInventory.setItem(stackPosition, is);
            }
    
            return deserializedInventory;
        }
    
    }
    
     
  2. Try to change
    if (inventory.getType() == InventoryType.CHEST && inventory.getName().equals("Player Chest")) {
    inventoryHandler.saveInventory(inventory);
    }
    To
    if (inventory.getType() == InventoryType.CHEST , inventory.getName().equals("Player Chest")) {
    inventoryHandler.saveInventory(inventory);
    }

    It will maybe work
     
  3. Offline

    xX4w3s0m3Xx

    Thank you for helping me, but that doesn't work.
    This is an if-statement and you can't use comma's there, unless it's between method arguments
     
  4. Offline

    xX4w3s0m3Xx

    Not sure if I can bump a post, because I couldn't find the rules
     
  5. Offline

    Zombie_Striker

    @xX4w3s0m3Xx
    https://bukkit.org/help/terms

    The method StringToInventory (BTW: All method names should start with a lowercase letter by convention) only sets the slots; it does not set the inventories name. Either hard-code the "player chest" into the name, or save and load the name from the config.
     
  6. Offline

    xX4w3s0m3Xx

    What do you mean by : "hard code the "player chest" into the name"?
     
  7. Offline

    InstanceofDeath

    Well the problem is that when you close an Inventory you have no data that shows you if it was the inventory of the player himself or of another.

    So it looks like you are "very pro" in programming, but you didnt find the mistake yourself so I will try to explain it to you (sry for my bad english)

    In your main class you do this

    Code:java
    1.  
    2. private InventoryHandler inventoryHandler;
    3.  


    which creates a new InventoryHandler object for the hole class.

    Now in the chest command you set this value here and here

    Code:java
    1.  
    2. inventoryHandler = new InventoryHandler(player); //You will find the line yourself
    3. inventoryHandler = new InventoryHandler(otherPlayer);
    4.  

    The constructor of the InventoryHandler "transfers" the PlayerObject and saves it in the Object itself. Now it's a fixxed part in the InventoryHandler - Object

    Code:java
    1.  
    2.  
    3. Player player;
    4.  
    5. public InventoryHandler(Player player) {
    6. this.player = player;
    7. }
    8.  
    9.  


    And now you call in the InventoryCloseEvent the Method

    Code:java
    1.  
    2. inventoryHandler.saveInventory(inventory);
    3.  


    which saves this inventory for the player who last got chosen as player or otherPlayer in the Command.
    No wonder why it didn't work :D

    The only necessary question is, can you fix it yourself and do you understand what I explained to you?

    P.S. If its not a stupid codingmistake you should study the OOP unit again :)
    P.S.S there are some other things I would switch in this code to make it more efficient. Just write down if you want to hear them
     
  8. Offline

    xX4w3s0m3Xx

    I read this about 3 times now and I understand what you're saying, but I don't understand what I did wrong. I know there is no data to see if it was the inventory of the player that was closed or the inventory that comes up when you type "/chest". That's one of my biggest problems, because if I can fix that, then I am almost done, I think. To this "The only necessary question is, can you fix it yourself and do you understand what I explained to you?" I would say that I can maybe fix it if you could tell me a little bit more indepth 'No spoonfeeding, if possible' and to the second question, I say yes.
     
  9. Offline

    InstanceofDeath

    Well sure.

    But do you know OOP?
    Otherwise it will end with spoonfeeding
     
  10. Offline

    xX4w3s0m3Xx

    I don't think I know enough of this, recently I dived more into OOP.
     
  11. Offline

    InstanceofDeath

    Okey I will shortly summarize Object Oriented Programming in Java for you so you don't need to google.

    OOP:

    Every Class that hasn't got a abstract, final or static in his classname is a blueprint.

    Such a blueprint contains 2 different things:

    Attributes /State: Variables (named Fields) in this Class (no static modifier)

    Methods: Functions (Things you can do with this class) (no static modifier)

    with the keyword new <ClassName> you will create a Class Object which is normally saved in a variable. We converted the class into a DataType.

    The line InventoryHandler inventoryHandler = new InventoryHandler(player) will create a new InventoryHandler Object from the InventoryClass Blueprint. In this Object you directly save over the constructor (You now what a constructor is?) the Player-Object. When you now do something with inventoryHandler the Player-Object is still saved and when you save the Inventory over it, it still has the PlayerObject you did put in. Understand?
     
    Last edited by a moderator: Jun 26, 2017
  12. Offline

    xX4w3s0m3Xx

    I think I understand now. So the thing I did wrong was overwriting the constructor that was set correctly with another inventory in this line?
    Code:
    inventoryHandler.saveInventory(inventory);
     
  13. Offline

    InstanceofDeath

    Yes. more precise : You saved the Inventory for the Player, who last Inventory got opened, because the inventotyHandler still holds the PlayerName and you didnt define another one in the InventoryCloseEvent
     
Thread Status:
Not open for further replies.

Share This Page