playerinventory to string and string to playerinventory

Discussion in 'Plugin Development' started by BimKurzAfk, Jun 21, 2020.

  1. Offline

    BimKurzAfk

    I want to save an inventory to a string and then turn the string back into an inventory, but this doesn't work, when I set the inventory for the player, the player gets nothing. I dont get any errors in the console.

    Code:
    package net.bimkurzafk.ffa.utils;
    
    import java.util.ArrayList;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    public class InventorySaver {
       
        @SuppressWarnings("deprecation")
        public 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;
                 }
    
                 if (is.hasItemMeta()) {
                   String isMeta = String.valueOf(is.getItemMeta()
                       .getDisplayName());
                   serializedItemStack += ":m@" + isMeta;
                 }
    
                 if (is.hasItemMeta()) {
                   String isLore = String.valueOf(is.getItemMeta().getLore());
                   if (!(isLore == null)) {
                     serializedItemStack += ":l@" + isLore;
                   }
                 }
    
                 Map<Enchantment, Integer> isEnch = is.getEnchantments();
                 if (isEnch.size() > 0) {
                   for (Entry<Enchantment, Integer> ench : isEnch.entrySet()) {
                     serializedItemStack += ":e@" + ench.getKey().getId()
                         + "@" + ench.getValue();
                   }
                 }
    
                 serialization += i + "#" + serializedItemStack + ";";
               }
             }
             return serialization;
           }
    
           @SuppressWarnings("deprecation")
        public 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("m") && createdItemStack) {
                        ItemMeta isM = is.getItemMeta();
                        isM.setDisplayName(itemAttribute[1]);
                        is.setItemMeta(isM);
                    } else if (itemAttribute[0].equals("l") && createdItemStack) {
                        ItemMeta isM = is.getItemMeta();
                        String removeBuckle = itemAttribute[1].substring(1, itemAttribute[1].length() - 1);
                        ArrayList<String> l = new ArrayList<String>();
                        for (String podpis : removeBuckle.split(", ")) {
                            l.add(podpis);
                        }
                        isM.setLore(l);
                        is.setItemMeta(isM);
                    } 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;
        }
    }
    
    Code:
    Inventory inv = null;
    inv = new InventorySaver().StringToInventory(inventory);
    player.getInventory().setContents(inv.getContents());
     
  2. Online

    timtower Moderator Moderator

  3. Offline

    BimKurzAfk

    I want to save it in MySQL and I can save there a string, if u know another better way tell me :D
     
  4. Offline

    Legendary_zotar

    @BimKurzAfk
    As your probably know telling by your code, Inventories arent serializable, so instead we save The inventory contents.
    the way i do it is by converting the ItemStack to base64 to save it as String, and load from Base64 to load it from string, Though the downside to it is that it is humanly unreadable.
    ItemArray to base64 method:
    ItemArray to base64 method: (open)
    Code:
    String itemStackArrayToBase64(ItemStack[] itemArray) throws IllegalStateException {
            try {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
    
                dataOutput.writeObject(itemArray);
    
                dataOutput.close();
    
                return Base64Coder.encodeLines(outputStream.toByteArray());
            } catch (Exception e) {
                throw new IllegalStateException("Error whilst saving items, Please contact the developer", e);
            }
        }


    ItemArray from base64 method:
    ItemArray from base64 method (open)
    Code:
    ItemStack[] itemStackArrayFromBase64(String data) throws IOException {
            try {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
                BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
    
                ItemStack[] itemArray = (ItemStack[]) dataInput.readObject();
    
                dataInput.close();
                return itemArray;
            } catch (ClassNotFoundException e) {
                throw new IOException("Error whilst loading items, Please contact the developer", e);
            }
    
        }
     
  5. Offline

    BimKurzAfk

    @Legendary_zotar
    When I try to give the player the ItemStackArray I get a NullPointerException and I dont know why...

    code for loading:

    Code:
    try {
            player.getInventory().setContents(new InventorySaver().itemStackArrayFromBase64(inventory));
     } catch (IllegalArgumentException | IOException e) {
            e.printStackTrace();
     }
    
    Code:
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:310) ~[spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:270) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.PacketPlayInFlying.a(SourceFile:126) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.PacketPlayInFlying$PacketPlayInPosition.a(SourceFile:57) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:13) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_251]
            at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_251]
            at net.minecraft.server.v1_8_R3.SystemUtils.a(SystemUtils.java:19) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:714) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:653) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:556) [spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_251]
    Caused by: java.lang.NullPointerException
            at org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder.decodeLines(Base64Coder.java:211) ~[spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            at net.bimkurzafk.ffa.utils.InventorySaver.itemStackArrayFromBase64(InventorySaver.java:30) ~[?:?]
            at net.bimkurzafk.ffa.main.Main.playerInArena(Main.java:94) ~[?:?]
            at net.bimkurzafk.ffa.listeners.MoveEvent.onMove(MoveEvent.java:22) ~[?:?]
            at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source) ~[?:?]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_251]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_251]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot.jar:git-Spigot-f94fe8f-d27e6d0]
            ... 15 more
     
  6. Online

    timtower Moderator Moderator

  7. Offline

    BimKurzAfk

    @timtower
    I tried to check if the ItemStack is null but I still get the NullPointerException

    Code:
    for(ItemStack is: itemStackArray) {
                    if(is != null) {
                        player.getInventory().addItem(is);
                    }
                }
    Oh my god, I made a really stupid mistake... Everything works fine, thanks!

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 22, 2020
    Legendary_zotar likes this.
  8. Offline

    Machine Maker

    If your problem/question has been resolved/answered, please mark this thread as Solved.
     

Share This Page