1.15.2 Problems with setting player inventory

Discussion in 'Spigot Plugin Development' started by scorpion50, Jan 23, 2020.

  1. Hello, I am making a plugin for my server that saves the player's inventory for each different area they enter. It saves each inventory.getContents() in a YAML file and reads it successfully. But when I use player.getInventory().setContents(newContents) no error is produced but nothing happens. I even add player.updateInventory() but nothing happens. inventory.clear() doesn't do anything either. I really don't know what's happening, so any help is appretiated. Thank you!
     
  2. Code please. From what you have explained, the error could be virtually anything.
     
  3. Debug your code. If everything looks like it works correctly on the surface but doesn’t actually work, then what you’re thinking is happening probably isn’t what really is. Use System.out.println to show the contents you are setting into the player; which player the inventory is being set to, the contents of the player inventory before and after being set.
     
  4. Agree, we need to see code to figure anything.
    I was going to guess you were not serializing the contents of the inventory properly, and when you read it back you got an array full of null items.
    That couldn't be it then, because the players inventory would get blanked instead of nothing happening...
     
  5. Sorry, here is the code:
    Code (Text):
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.GameMode;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    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.inventory.InventoryType;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.PlayerInventory;
    import org.bukkit.plugin.java.JavaPlugin;

    import java.io.File;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;

    public class ModeToggleUtility implements CommandExecutor {

        private File playerfile;
        private FileConfiguration config;

        private File dataFolder;

        ModeToggleUtility(JavaPlugin plugin) {
            dataFolder = plugin.getDataFolder();
        }

        @Override
        public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) {
            Player target = commandSender.getServer().getPlayer(args[0]);
            if (target == null) {
                return false;
            }

            if (!((args[1].equals("survival") || args[1].equals("creative") || args[1].equals("normal")) && (args[2].equals("survival") || args[2].equals("creative") || args[2].equals("normal")))) {
                commandSender.sendMessage("Incorrect gamemode");
                return false;
            }

            playerfile = new File(dataFolder, target.getName()+".yml");
            if (!playerfile.exists()) {
                try {
                    playerfile.createNewFile();
                    YamlConfiguration conf = YamlConfiguration.loadConfiguration(playerfile);
                    conf.set("normalInvContents", Bukkit.createInventory(null, InventoryType.PLAYER).getContents());
                    conf.set("survivalInvContents", Bukkit.createInventory(null, InventoryType.PLAYER).getContents());
                    conf.set("creativeInvContents", Bukkit.createInventory(null, InventoryType.PLAYER).getContents());
                    conf.save(playerfile);
                } catch (IOException e) {
                    target.sendMessage(target.getDisplayName() + ChatColor.RED+": Couldn't create player's config at " + dataFolder);
                    e.printStackTrace();
                    return false;
                }
            }
            config = YamlConfiguration.loadConfiguration(playerfile);

            PlayerInventory inv = target.getInventory();
            List<ItemStack> currentInvContents = Arrays.asList(inv.getContents());

            System.out.println(currentInvContents.toString());

            List<ItemStack> newInvContents = null;

            config.set(args[2] + "InvContents", currentInvContents);
            newInvContents = (List<ItemStack>) config.getList(args[1] + "InvContents");

            try {
                config.save(playerfile);
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }

            ItemStack[] invContents;
            System.out.println(newInvContents.toString());
            invContents = (ItemStack[]) newInvContents.toArray();
            System.out.println(Arrays.toString(invContents));

            target.getInventory().clear();
            target.getInventory().setContents(invContents);
            System.out.println(Arrays.toString(target.getInventory().getContents()));
            target.updateInventory();

            if (args[1].equals("survival") || args[1].equals("normal")) {
                target.setGameMode(GameMode.SURVIVAL);
            } else if (args[1].equals("creative")) {
                target.setGameMode(GameMode.CREATIVE);
            }

            return true;
        }
    }
     
    Also, I have tried printing out the contents of the inventory before I put it in the playerFile and contents that are read out of the file after serializing, and everything seems correct.
     
  6. Ah, don‘t use that toArray() method, instead use toArray(T[])
    Code (Java):
    invContents = newInvContents.toArray(new ItemStack[0]);
     
  7. Thank you for the response, but I still don't understand why that would prevent inventory.clear() from working. I changed it in the code and I will try it out but I feel like it can't be the only problem because the rest of the code still executes properly (the gamemode is changed but nothing happens to the inventory)
     
  8. Using
    Code (Text):
    .toArray(new ItemStack[0])
    didn't work any more than it was already. There has to be a problem with the actual inventory commands. I haven't found anything useful and I am really confused by this because there isn't really any reason it shouldn't be working.
     
  9. Try separating your code in different classes with unique purpose.
     
  10. Thank you, but I still don't see how separating my code into classes will help fix an issue I am having with the Spigot/Bukkit API. None of the commands on the player inventory work (clear, setInventoryContents, setArmorContents) but the target player is correct because setting the GameMode works.
     
  11. From what I can tell, everything is working correctly.
    The only thing I can think of, is that somehow you are saving the inventory and then loading the same one back in again.
    It does not appear like that but maybe in
    Code (Text):
    config.set(args[2] + "InvContents", currentInvContents);
    newInvContents = (List<ItemStack>) config.getList(args[1] + "InvContents");
    args[2] and args[1] are the same?

    Maybe it happens somewhere else, but if it seems like nothing is happening there, and you are getting correct debug information like you claim, somehow you must just be giving them the exact same inventory back...

    In this block:
    Code (Java):
    target.getInventory().clear();
    target.getInventory().setContents(invContents);
    System.out.println(Arrays.toString(target.getInventory().getContents()));
    target.updateInventory();
    You might want to output what the player's inventory actually is, before and after you updateInventory(), and see if it ever matches invContents.