1.16.5 backpacks?

Discussion in 'Spigot Plugin Development' started by CrossedLivid, Jun 10, 2021.

  1. Like some other posts ive made: ive got the logic to do it, but i never have the code.

    Im trying to make a backpack. Ive fot the recipe and things working, but i cant have a persistent data storage.

    My first thought is a hashmap eith uuid and list inventory, but once server restart it wont stay.

    Any good storage options?
     
  2. Save yor Map to an file or database and load the data for a player when he's joining the server.
     
    • Agree Agree x 1
  3. Any1 got an idea so I could have 2 backpacks for 1 player? I can only seem to have 1 uuid as identifier
     
  4. Shaggy67

    Benefactor

    The way I did mine is the player has to name their chest on an anvil with any name that contains the word "Backpack". The player can create as many unique backpacks as they want Then every time they open/close the chest, if the name contains "Backpack" it loads/saves the chest inventory to a yaml config file. The config path is basically uuid.chestName and then the contents as either an ArrayList or ItemStack[]. For some reason, I've found that you need to check for both. Probably something in how it serializes the inventory.
     
    #4 Shaggy67, Jun 11, 2021 at 2:23 AM
    Last edited: Jun 11, 2021 at 2:33 AM


  5. This video should work great for you.
     
  6. Im now using that per persistent thingy (hesvy struggles) to store backpacks. It works, but to support multiple backpacks ill have to add some slimey stuff to my util class
     
  7. Thats persistent thingy its the way to go btw.. its as simple as either creating your own persistentdatatype or convert the items into strings(some people use base64) then just handle the inventory management and ur done,real backpacks
     
  8. you can create your own Backpack object to store every page backpacks for instance:

    Code (Java):
    public class Backpack {
     
        // add your equals or comparable if you want to sort it later.

        private final static HashMap<UUID, Backpack> backpackMap = new HashMap<>();
        public static Backpack get(Player player) {
            if(backpackMap.containsKey(player.getUniqueId()) {
                 return backpackMap.get(player.getUniqueId();
            }
            Backpack backpack = new Backpack(player);
            backpackMap.put(player.getUniqueId(), backpack);
            return backpack;
        }
     
        private final UUID uuid;
        private final HashMap<Integer, ItemStack[]> pageMap = new HashMap<>();
        private final int hash;
        private Backpack(Player player) {
           this.uuid = player.getUniqueId();
           this.pageMap = new HashMap<>();
           this.hash = uuid.hashCode();
        }

        public Inventory getPage(int page) {
             Inventory inventory = // create Inventory
             if(pageMap.containsKey(page)) {
                inventory.setContents(pageMap.get(page));
             }
             return inventory;
        }

       @Override
       public int hashCode() {
            return hash;
       }

       public UUID getOwner() {
          return uuid;
        }

       public void setContents(int page, ItemStack[] contents) {
           pageMap.put(page, contents);
       }
    }
    Usage:

    Code (Java):
    @EventHandler
    public void onJoin(PlayerJoinEvent e) {
          Backpack backpack = Backpack.get(e.getPlayer());
         // do your thing
    }
     
    #8 Lifeonblack, Jun 12, 2021 at 3:58 AM
    Last edited: Jun 12, 2021 at 4:05 AM
  9. I've figured it out now, and I'm going to have the code here in case any1 needs it. (sorry if im spoonfeed)

    Code (Java):
    if (player.getInventory().getItemInMainHand().equals(recipes.portableVaultRecipe().getResult())) {
                    ArrayList<ItemStack> items = VaultUtils.getItems(player);
                    Inventory vault = Bukkit.createInventory(player, 54, "Portable Vault");
                    if (items != null) {
                        items.stream().forEach(itemStack -> vault.addItem(itemStack));
                    }
                    player.playSound(player.getLocation(), Sound.BLOCK_CHEST_OPEN, 1.0f, 1.0f);
                    player.openInventory(vault);
                }
    Code (Java):
    package net.wardensmp.plugins.apis;

    import net.wardensmp.plugins.WardenSMP;
    import org.bukkit.NamespacedKey;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.persistence.PersistentDataContainer;
    import org.bukkit.persistence.PersistentDataType;
    import org.bukkit.util.io.BukkitObjectInputStream;
    import org.bukkit.util.io.BukkitObjectOutputStream;

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Base64;
    import java.util.List;

    public class VaultUtils {

        public static void storeItems(List<ItemStack> items, Player p){

            PersistentDataContainer data = p.getPersistentDataContainer();

            if (items.size() == 0){
                data.set(new NamespacedKey(WardenSMP.getPlugin(), "vault"), PersistentDataType.STRING, "");
            }else{

                try{

                    ByteArrayOutputStream io = new ByteArrayOutputStream();
                    BukkitObjectOutputStream os = new BukkitObjectOutputStream(io);

                    os.writeInt(items.size());

                    for (int i = 0; i < items.size(); i++){
                        os.writeObject(items.get(i));
                    }

                    os.flush();

                    byte[] rawData = io.toByteArray();

                    String encodedData = Base64.getEncoder().encodeToString(rawData);

                    data.set(new NamespacedKey(WardenSMP.getPlugin(), "vault"), PersistentDataType.STRING, encodedData);

                    os.close();

                }catch (IOException ex){
                    System.out.println(ex);
                }

            }

        }

        public static ArrayList<ItemStack> getItems(Player p){

            PersistentDataContainer data = p.getPersistentDataContainer();

            ArrayList<ItemStack> items = new ArrayList<>();

            String encodedItems = data.get(new NamespacedKey(WardenSMP.getPlugin(), "vault"), PersistentDataType.STRING);

            if (encodedItems != null) {
                if (!encodedItems.isEmpty()){

                    byte[] rawData = Base64.getDecoder().decode(encodedItems);

                    try{

                        ByteArrayInputStream io = new ByteArrayInputStream(rawData);
                        BukkitObjectInputStream in = new BukkitObjectInputStream(io);

                        int itemsCount = in.readInt();

                        for (int i = 0; i < itemsCount; i++){
                            items.add((ItemStack) in.readObject());
                        }

                        in.close();

                    }catch (IOException | ClassNotFoundException ex){
                        System.out.println(ex);
                    }

                }

                return items;
            }

            return null;
        }

    }
     
    Code (Java):
    if (e.getView().getTitle().equalsIgnoreCase("Portable Vault")) {
                ArrayList<ItemStack> storedItems = new ArrayList<>();
                Arrays.stream(e.getInventory().getContents())
                        .filter(itemStack -> {
                            if (itemStack == null) {
                                return false;
                            }
                            return true;
                        })
                        .forEach(itemStack -> storedItems.add(itemStack));

                System.out.println("Size of portable vault of " + player.getName() + ": " + storedItems.size());

                VaultUtils.storeItems(storedItems, player);
                player.playSound(player.getLocation(), Sound.BLOCK_CHEST_CLOSE, 1.0f, 1.0f);
            }