for some reason the items are being saved into the data.yml however when the player opens the gui after closing it the items are gone. I am still new to plugin dev so please lend a helping hand that I could under stand thank you. Best regards - shablombi P.S I would like to add a feature to where you cannot put the backpack into the backpack. here is a clip of the two problems I am encountering: https://youtu.be/0T98mYOprDA Code: package org.stick.ugh; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.ShulkerBox; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.bukkit.Bukkit.getServer; public class backpack implements Listener { private Inventory gui; Ugh plugin; public backpack(Ugh instance) { plugin = instance; dataFile = new File("plugins/Ugh", "data.yml"); data = YamlConfiguration.loadConfiguration(dataFile); } private File dataFile; private YamlConfiguration data; public void update() { dataFile = new File(plugin.getDataFolder(), "data.yml"); data = YamlConfiguration.loadConfiguration(dataFile); } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { Player player = event.getPlayer(); if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { ItemStack itemInHand = player.getInventory().getItemInMainHand(); if (itemInHand.getType() == Material.PLAYER_HEAD) { if (event.getItem().getItemMeta().getDisplayName().equals("Backpack")) { gui = Bukkit.createInventory(player, 9, "Backpack"); // player.openInventory(gui); createGUI(player); event.setCancelled(true); } } } } private void createGUI(Player player) { Inventory inventory = getServer().createInventory(player, 9, "Backpack"); // Load data from file List<Map<?, ?>> items = data.getMapList(player.getUniqueId().toString()); if (items != null) { for (Map<?, ?> item : items) { Integer slot = (Integer) item.get("slot"); ItemStack stack = (ItemStack) item.get("item"); if (slot != null && stack != null) { inventory.setItem(slot, stack); } } } player.openInventory(inventory); } private void saveInventory(Inventory inventory, String playerName) { FileConfiguration config = plugin.getConfig(); List<Map<?, ?>> items = new ArrayList<>(); ItemStack[] contents = inventory.getContents(); for (int i = 0; i < contents.length; i++) { ItemStack item = contents[i]; if (item != null && item.getType() != Material.AIR && item.getType() != null) { // Check if item and material are not null Map<String, Object> map = new HashMap<>(); map.put("slot", i); map.put("item", item); items.add(map); } } config.set(playerName, items); plugin.saveConfig(); } @EventHandler public void onInventoryClick(InventoryClickEvent event) { Player player = (Player) event.getWhoClicked(); Inventory clickedInventory = event.getClickedInventory(); ItemStack clickedItem = event.getCurrentItem(); if (clickedInventory != null && clickedInventory.getHolder() instanceof Player && player.getOpenInventory().getTopInventory().equals(clickedInventory) && clickedItem != null) { // Save inventory when an item is clicked saveInventory(clickedInventory, player.getUniqueId().toString()); } } @EventHandler public void onInventoryClose(InventoryCloseEvent event) { Player player = (Player) event.getPlayer(); Inventory inventory = event.getInventory(); if (inventory != null && inventory.getHolder() instanceof Player && player.getOpenInventory().getTopInventory().equals(inventory)) { // Save inventory when the GUI is closed saveInventory(inventory, player.getUniqueId().toString()); } } }
Hello! Instead of saving the inventory items from the GUI every single time it is closed, I would simply hold an instance of the inventory and only save them to data.yml when the plugin is disabled. This will be more efficient for you and will save your server some stress from looping through multiple inventories every time a backpack is opened and closed. Create a hashmap<Player, Inventory> Add the entire inventory to it mapped with the player (hashmap#put(e.getPlayer(), inventory) Upon opening the inventory grab the hashmap#get(e.getPlayer()) which will return the entire inventory and its contents. onDisable loop through the hashmap and save the inventories to the data.yml onEnable load the inventories back into the hashmap. It would look something like this psuedo code here, which is only intended to give you an idea of how to do it, rather than copy and pasting. Code: import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.plugin.java.JavaPlugin; import java.util.HashMap; import java.util.Map; public class MyBackpackPlugin extends JavaPlugin { private Map<Player, Inventory> backpacks; @Override public void onEnable() { backpacks = new HashMap<>(); // Register an event listener to handle inventory open and close events getServer().getPluginManager().registerEvents(new BackpackListener(), this); loadBackpacks(); } @Override public void onDisable() { // Save the backpacks to data.yml or any other persistent storage saveBackpacks(); } private void loadBackpacks() { // Load the backpacks from data.yml or any other persistent storage } private void saveBackpacks() { // Save the backpacks to data.yml or any other persistent storage } private class BackpackListener implements Listener { @EventHandler public void onInventoryOpen(InventoryOpenEvent event) { Player player = (Player) event.getPlayer(); Inventory inventory = event.getInventory(); // Check if the inventory is the player's own inventory and is not a backpack if (inventory.getType() == InventoryType.PLAYER && !backpacks.containsValue(inventory)) { // Get the player's backpack inventory from the map, or create a new one if it doesn't exist Inventory backpack = backpacks.getOrDefault(player, Bukkit.createInventory(player, 27, "Backpack")); // Set the inventory for the event to the backpack inventory event.setInventory(backpack); // Put the backpack inventory into the map if it wasn't already there backpacks.putIfAbsent(player, backpack); } } @EventHandler public void onInventoryClose(InventoryCloseEvent event) { Player player = (Player) event.getPlayer(); Inventory inventory = event.getInventory(); // Check if the inventory is a backpack if (backpacks.containsValue(inventory)) { // Store the backpack inventory in the map backpacks.put(player, inventory); } } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { Player player = event.getPlayer(); // Check if the player right-clicked with an empty hand if (event.getAction() == Action.RIGHT_CLICK_AIR && player.getInventory().getItemInMainHand().getType() == Material.PLAYER_HEAD) { // Get the player's backpack inventory from the map, or create a new one if it doesn't exist Inventory backpack = backpacks.getOrDefault(player, Bukkit.createInventory(player, 27, "Backpack")); // Set the player's open inventory to the backpack inventory player.openInventory(backpack); } } } } As far as not allowing a backpack to be put inside a backpack, you would simply check if the item is being moved into a backpack inventory && if the item being moved IS a backpack. You can check out this thread here for more info on how to do it using InventoryDragEvent and InventoryClickEvent: https://www.spigotmc.org/threads/enderchest-item-blacklist.592939/#post-4550816 This thread here shows the basic principles that should definitely point you in the correct direction as it did for me when I had a similar question.
Perfect this worked amazingly, however im having another issue that I just can seam to figure out. when I move the backpack within my inventory and then move it back to my hotbar and try to open it nothing happens, its almost like it turns into a player head again. please any help with this would be great! Here is a video of the issue: This is my main class code: Code: package org.stick.ugh; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.ShulkerBox; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import java.util.HashMap; import java.util.Map; public final class Ugh extends JavaPlugin { public static Plugin instance; private Map<Player, Inventory> backpacks = new HashMap<>(); @Override public void onEnable() { instance = this; PluginManager pm = getServer().getPluginManager(); pm.registerEvents(new InventorySaveLoad(this), this); pm.registerEvents(new backpack(this), this); } @Override public void onDisable() { // Plugin shutdown logic } } and this is my backpack code: Code: package org.stick.ugh; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.ShulkerBox; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; import java.io.StringReader; import java.util.*; import static org.bukkit.Bukkit.getServer; public class backpack implements Listener { private Map<Player, Inventory> backpacks; private Inventory gui; Ugh plugin; public backpack(Ugh instance) { plugin = instance; dataFile = new File("plugins/Ugh", "data.yml"); data = YamlConfiguration.loadConfiguration(dataFile); backpacks = new HashMap<>(); // loads backpacks from data.yml loadbackpacks(); } private void loadbackpacks() { FileConfiguration config = plugin.getConfig(); if (!config.contains("Backpacks")) { return; } ConfigurationSection backpacksSection = config.getConfigurationSection("Backpacks"); Set<String> backpackKeys = backpacksSection.getKeys(false); for (String backpackKey : backpackKeys) { ConfigurationSection backpackSection = backpacksSection.getConfigurationSection(backpackKey); Player player = Bukkit.getPlayerExact(backpackKey); if (player == null) { continue; } List<?> itemList = backpackSection.getList("items"); ItemStack[] items = new ItemStack[itemList.size()]; for (int i = 0; i < itemList.size(); i++) { Map<?, ?> map = (Map<?, ?>) itemList.get(i); items[i] = ItemStack.deserialize((Map<String, Object>) map); } Inventory backpack = Bukkit.createInventory(player, 27, "Backpack"); backpack.setContents(items); backpacks.put(player, backpack); } } private void savebackpacks() { if (backpacks == null || backpacks.isEmpty()) { return; } FileConfiguration config = plugin.getConfig(); ConfigurationSection backpacksSection = config.createSection("Backpacks"); for (Player uuid : backpacks.keySet()) { String uuidString = uuid.toString(); backpacksSection.set(uuidString, backpacks.get(uuid)); } plugin.saveConfig(); } private File dataFile; private YamlConfiguration data; public void update() { dataFile = new File(plugin.getDataFolder(), "data.yml"); data = YamlConfiguration.loadConfiguration(dataFile); } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { Player player = event.getPlayer(); if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { ItemStack itemInHand = player.getInventory().getItemInMainHand(); if (itemInHand.getType() == Material.PLAYER_HEAD && itemInHand.getItemMeta().getDisplayName().equals("Backpack")) { // Check if the player right-clicked with an empty hand // Get the player's backpack inventory from the map, or create a new one if it doesn't exist if (player != null && backpacks != null) { Inventory backpack = backpacks.getOrDefault(player, Bukkit.createInventory(player, 27, "Backpack")); if (backpack.getType() != InventoryType.PLAYER) { // Add or remove items from the backpack inventory // ... // Open the backpack inventory for the player openBackpack(player); } } // Set the player's open inventory to the backpack inventory event.setCancelled(true); } else { // Check if the player has a backpack item in their inventory Inventory playerInventory = player.getInventory(); for (int i = 0; i < playerInventory.getSize(); i++) { ItemStack itemInInventory = playerInventory.getItem(i); if (itemInInventory != null && itemInInventory.getType() == Material.PLAYER_HEAD && itemInInventory.getItemMeta().getDisplayName().equals("Backpack")) { // Get the player's backpack inventory from the map, or create a new one if it doesn't exist if (player != null && backpacks != null) { Inventory backpack = backpacks.getOrDefault(player, Bukkit.createInventory(player, 27, "Backpack")); if (backpack.getType() != InventoryType.PLAYER) { // Add or remove items from the backpack inventory // ... // Open the backpack inventory for the player openBackpack(player); } } // Set the player's open inventory to the backpack inventory event.setCancelled(true); break; } } } } } private ItemStack createBackpack() { ItemStack backpack = new ItemStack(Material.PLAYER_HEAD); SkullMeta meta = (SkullMeta) backpack.getItemMeta(); meta.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString("8667ba71-b85a-4004-af54-457a9734eed7"))); // set the texture to the backpack texture meta.setDisplayName("Backpack"); meta.setLore(Arrays.asList("A convenient way to carry extra items!")); backpack.setItemMeta(meta); return backpack; } // Open the backpack inventory public void openBackpack(Player player) { Inventory backpack = backpacks.getOrDefault(player, Bukkit.createInventory(player, 27, "Backpack")); // Add an inventory click listener to update the backpacks map plugin.getServer().getPluginManager().registerEvents(new InventoryClickEventListener(player, backpack, backpacks), plugin); player.openInventory(backpack); } private void createGUI(Player player) { Inventory inventory = getServer().createInventory(player, 27, "Backpack"); // Load data from file List<Map<?, ?>> items = data.getMapList(player.getUniqueId().toString()); if (items != null) { for (Map<?, ?> item : items) { Integer slot = (Integer) item.get("slot"); ItemStack stack = (ItemStack) item.get("item"); if (slot != null && stack != null) { inventory.setItem(slot, stack); } } } player.openInventory(inventory); } private void saveInventory(Inventory inventory, String playerName) { FileConfiguration config = plugin.getConfig(); List<Map<?, ?>> items = new ArrayList<>(); ItemStack[] contents = inventory.getContents(); for (int i = 0; i < contents.length; i++) { ItemStack item = contents[i]; if (item != null && item.getType() != Material.AIR && item.getType() != null) { // Check if item and material are not null Map<String, Object> map = new HashMap<>(); map.put("slot", i); map.put("item", item); items.add(map); } } config.set(playerName, items); plugin.saveConfig(); } @EventHandler public void onInventoryClick(InventoryClickEvent event) { Player player = (Player) event.getWhoClicked(); Inventory clickedInventory = event.getClickedInventory(); ItemStack clickedItem = event.getCurrentItem(); if (clickedInventory != null && clickedInventory.getHolder() instanceof Player && player.getOpenInventory().getTopInventory().equals(clickedInventory) && clickedItem != null) { // Save inventory when an item is clicked saveInventory(clickedInventory, player.getUniqueId().toString()); } } @EventHandler public void onInventoryClose(InventoryCloseEvent event) { Player player = (Player) event.getPlayer(); Inventory inventory = event.getInventory(); if (inventory != null && inventory.getHolder() instanceof Player && player.getOpenInventory().getTopInventory().equals(inventory)) { saveInventory(inventory, player.getUniqueId().toString()); backpacks.put(player, inventory); } } @EventHandler public void onInventoryOpen(InventoryOpenEvent event) { Player player = (Player) event.getPlayer(); Inventory inventory = event.getInventory(); // Initialize the backpacks map if it is null if (backpacks == null) { backpacks = new HashMap<>(); } // Check if the inventory is the player's own inventory and is not a backpack if (player.getInventory().getItemInMainHand().getType() == Material.AIR) { // Get the player's backpack inventory from the map, or create a new one if it doesn't exist Inventory backpack = backpacks.getOrDefault(player, Bukkit.createInventory(player, 27, "Backpack")); // Debug statement to verify that items are being added to the backpack inventory // player.sendMessage("Added item to backpack: " + player.getInventory().getItemInMainHand().getType().name()); // Add the item to the backpack inventory backpack.addItem(player.getInventory().getItemInMainHand()); // Update the backpack inventory in the map backpacks.put(player, backpack); } } }
Well, what have you done to try and solve the issue? Have you ran any debug code to see what is stopping the code?