Resource BetterItemStackAPI: Easy Data Storage on ItemStacks and Simple Custom Enchantment handler

Discussion in 'Spigot Plugin Development' started by Yugikid1, May 6, 2017.

  1. I have created a easy to use API to easily store data on ItemStacks. This API also allows easy management of Custom Enchants.
    check out the class on GitHub here

    Code (Text):
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ThreadLocalRandom;
    import java.util.logging.Level;

    import org.bukkit.ChatColor;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.scheduler.BukkitRunnable;
    import org.bukkit.util.io.BukkitObjectInputStream;
    import org.bukkit.util.io.BukkitObjectOutputStream;

    public class BetterItemStack implements Serializable {
        /**
         *
         */
        private static final long serialVersionUID = -1521142095310355897L;
        private static Map<String, String> RegisteredEnchants = new HashMap<String, String>();
        private static Map<Integer, BetterItemStack> ListI = new HashMap<Integer, BetterItemStack>();
        ItemStack is;
        List<String> Data = new ArrayList<String>();
        int ID;

        /**
         * Returns the BetterItemStack verson of the given ItemStack.
         *
         */
        public static BetterItemStack fromItemStack(ItemStack i) {
            if (i.hasItemMeta()) {
                if (i.getItemMeta().hasLore()) {
                    String a = ChatColor.stripColor(i.getItemMeta().getLore().get(0));
                    if (a.startsWith("ID: ")) {
                        String[] aarr = a.split(" ");
                        int ID = Integer.parseInt(aarr[1]);
                        if (ListI.get(ID) != null)
                            return ListI.get(ID);
                    }
                }
            }

            return new BetterItemStack(i);
        }

        /**
         * Private constructor
         *
         */
        private BetterItemStack(ItemStack i) {
            if (i.hasItemMeta()) {
                // YES META
                if (i.getItemMeta().hasLore()) {
                    // YES LORE
                    if (i.getItemMeta().getLore().get(0).startsWith(ChatColor.BLACK + "ID: "))
                        return;
                    List<String> Lore = i.getItemMeta().getLore();
                    int length = Lore.size();
                    for (int p = (length - 1); p >= 0; p--) {
                        String toset = Lore.get(p);
                        int p1 = p + 1;
                        Lore.set(p1, toset);
                    }
                    i.getItemMeta().setLore(Lore);
                }
                boolean didntgetRandom = true;
                int random = 0;
                while (didntgetRandom) {
                    random = ThreadLocalRandom.current().nextInt();
                    if (ListI.containsKey(random)) {
                        continue;
                    }

                    didntgetRandom = false;
                }
                List<String> Lore = i.getItemMeta().getLore();
                String tosetLore = ChatColor.BLACK + "ID: " + random;
                Lore.set(0, tosetLore.replaceAll("ยง", ""));
                ItemMeta im = i.getItemMeta();
                im.setLore(Lore);
                i.setItemMeta(im);
                ListI.put(random, this);
            } else {
                // NO META
                boolean didntgetRandom = true;
                int random = 0;
                while (didntgetRandom) {
                    random = ThreadLocalRandom.current().nextInt();
                    if (ListI.containsKey(random)) {
                        continue;
                    }

                    didntgetRandom = false;
                }
                List<String> Lore = new ArrayList<String>();
                String tosetLore = ChatColor.BLACK + "ID: " + random;
                Lore.add(tosetLore);

                ItemMeta im = i.getItemMeta();
                im.setLore(Lore);
                i.setItemMeta(im);
                ListI.put(random, this);
            }
            is = i;
        }

        /**
         * Registers Custom Enchantment to CustomEnchantment list
         *
         */
        public static void registerCustomEnchantment(String enchantID, String LoreName) {
            if (!RegisteredEnchants.containsKey(enchantID))
                RegisteredEnchants.put(enchantID, LoreName);
        }
        /**
         * Un-Registers Custom Enchantment from CustomEnchantment list
         *
         */
        public static void unregisterCustomEnchantment(String enchantID) {
            if (RegisteredEnchants.containsKey(enchantID))
                RegisteredEnchants.remove(enchantID);
        }
        /**
         * Add custom enchantment with given enchantmentID and level to item
         *
         */
        public boolean addEnchantment(String enchantID, int level) {
            List<String> Lore;
            if (is.hasItemMeta()) {
                if (is.getItemMeta().hasLore()) {
                    Lore = is.getItemMeta().getLore();
                } else {
                    Lore = new ArrayList<String>();
                }

            } else {
                Lore = new ArrayList<String>();
            }

            if (RegisteredEnchants.containsKey(enchantID)) {
                Lore.add(RegisteredEnchants.get(enchantID) + " " + level);
                return true;
            }

            return false;
        }
        /**
         * Removes custom enchantment with given enchantmentID and level from item
         *
         */
        public boolean removeEnchantment(String enchantID) {
            List<String> Lore = is.getItemMeta().getLore();
            if (RegisteredEnchants.containsKey(enchantID)) {
                if (Lore.contains(RegisteredEnchants.get(enchantID))) {
                    Lore.remove(RegisteredEnchants.get(enchantID));
                    return true;
                }
            }
            return false;
        }
        /**
         * Returns a List<String> representing saved data
         *
         */
        public List<String> getData() {
            return Data;
        }
        /**
         * Lets you set a List<String> as data to be saved
         *
         */
        public void setData(List<String> l) {
            Data = l;
        }
        /**
         * Checks if the Data has the specific data value string
         *
         */
        public boolean hasData(String s) {
            return Data.contains(s) ? true : false;
        }
        /**
         * Checks if the item has ANY custom enchantment
         *
         */
        public boolean hasCustomEnchant() {
            List<String> l = is.getItemMeta().getLore();
            for (String lore : l) {
                String check = ChatColor.stripColor(lore);
                for (String s : RegisteredEnchants.values()) {
                    String checks = ChatColor.stripColor(s);
                    if (check.startsWith(checks))
                        return true;
                }
            }

            return false;
        }
        /**
         * Returns a Map with all custom enchantments and its level on the item
         *
         */
        public Map<String, Integer> getAllCustomEnchantsWithLevels() {
            Map<String, Integer> res = new HashMap<String, Integer>();
            ArrayList<String> check = new ArrayList<String>();
            for (String s : is.getItemMeta().getLore()) {
                String sc = ChatColor.stripColor(s);
                for (String re : RegisteredEnchants.values()) {
                    String checks = ChatColor.stripColor(re);
                    if (sc.startsWith(checks))
                        check.add(sc);
                }
            }
            if (check.size() != 0) {
                for (String s : check) {
                    String sc = ChatColor.stripColor(s);
                    if (sc.startsWith("ID: "))
                        continue;
                    String[] list = sc.split(" ");
                    int level = Integer.valueOf(list[list.length - 1]);
                    res.put(sc, level);
                }
            }
            return res;
        }
        /**
         * Checks if the item has the specific custom enchantment with the specific level on the item
         *
         */
        public boolean hasCustomEnchant( String enchantID,int level) {
            List<String> l = is.getItemMeta().getLore();
            for (String lore : l) {
                String check = ChatColor.stripColor(lore);
                if (check.startsWith("ID: "))
                    continue;
                if (!RegisteredEnchants.containsKey(enchantID))
                    return false;
                if (lore.startsWith(RegisteredEnchants.get(enchantID)) && lore.endsWith(String.valueOf(level))) {
                    return true;
                }

            }

            return false;
        }
        /**
         * Checks if the item has ANY custom enchantment with teh specified level
         *
         */
        public boolean hasCustomEnchant( int level) {
            List<String> l = is.getItemMeta().getLore();
            for (String lore : l) {
                String check = ChatColor.stripColor(lore);
                for (String s : RegisteredEnchants.values()) {
                    String checks = ChatColor.stripColor(s) + " " + level;
                    if (checks.equalsIgnoreCase(check))
                        return true;
                }
            }

            return false;
        }
        /**
         * Saves All Data from this class in .dat files. Save it whenever needed and make sure you save it in the onDisable().
         *
         */
        public static void saveAllData(Plugin p) {

            if (!p.getDataFolder().exists())
                p.getDataFolder().mkdir();
            new BukkitRunnable() {
                public void run() {

                    // SAVING BETTER-ITEMSTACK INSTANCES
                    try {
                        BukkitObjectOutputStream out = new BukkitObjectOutputStream(
                                new FileOutputStream(new File(p.getDataFolder(), "ItemStackDATA.dat")));
                        out.writeObject(ListI);
                        out.flush();
                        out.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                        p.getLogger().log(Level.WARNING, "Error saving itemstackDATA. Please contact developer for help.");
                    }
                    // SAVING REGISTERED ENCAHNTMENTS
                    try {
                        BukkitObjectOutputStream out = new BukkitObjectOutputStream(
                                new FileOutputStream(new File(p.getDataFolder(), "registeredEnchantDATA.dat")));
                        out.writeObject(RegisteredEnchants);
                        out.flush();
                        out.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                        p.getLogger().log(Level.WARNING,
                                "Error saving RegisteredEnchantmentDATA. Please contact developer for help.");
                    }
                }
            }.runTaskAsynchronously(p);

        }
        /**
         * Loads all data from datafolder if available. returns false if no data file is found.
         *
         */
        @SuppressWarnings("unchecked")
        public static boolean loadAllData(Plugin p) {
            if (!p.getDataFolder().exists()) {
                p.getDataFolder().mkdirs();
                return false;
            }

            if (!(new File(p.getDataFolder(), "registeredEnchantDATA.dat").exists()))
                return false;
            if (!(new File(p.getDataFolder(), "ItemStackDATA.dat").exists()))
                return false;

            try {
                BukkitObjectInputStream in = new BukkitObjectInputStream(
                        new FileInputStream(new File(p.getDataFolder(), "ItemStackDATA.dat")));
                Object res = in.readObject();
                in.close();
                ListI = (Map<Integer, BetterItemStack>) res;
            } catch (Exception e) {
                e.printStackTrace();
                p.getLogger().log(Level.WARNING, "Error loading itemstackDATA. Please contact developer for help.");
                return false;
            }
            try {
                BukkitObjectInputStream in = new BukkitObjectInputStream(
                        new FileInputStream(new File(p.getDataFolder(), "registeredEnchantDATA.dat")));
                Object res = in.readObject();
                in.close();
                RegisteredEnchants = (Map<String, String>) res;
            } catch (Exception e) {
                e.printStackTrace();
                p.getLogger().log(Level.WARNING,
                        "Error loading RegisteredEnchantmentDATA. Please contact developer for help.");
                return false;
            }
            return true;
        }

     

    }

    Im sure you guys can make use of this. Thid is the first API that I made. Hopefully it is helpfull to you guys.
    To use the API simply create a new class in your project named "BetterItemStack" and paste the given code there. Then you can access the methods of the class. The methods shouod be self explanative. But if any of you need help, dont be worried to contact me or ask below.
     
  2. Does this allow players to combine custom enchants? If you added that, it would be VERY useful.
     
    • Funny Funny x 1
  3. Currently it is not in it. But ill surely add it as soon as possible. Although the API already makes it easier for you to work with anvil events to get the BIS object and get data/existing enchants and their levels.
     
  4. Bump. Any suggestion?
     
  5. Allow players to combine custom enchants? Use the anvil event to detect if they have matching lores and if the enchant has a higher tier to it.
     
  6. Just out of curiosity... why is it better than the Bukkit API?

    I also got a suggestion: Add NBT formatted JSON serialization & deserialization. So users of this API easily can access all tags supported by vanilla MC just like they're listed at MC wiki.
     
    • Agree Agree x 2