diff --git a/resource/plugin.yml b/resource/plugin.yml
index bb85135..e974015 100644
--- a/resource/plugin.yml
+++ b/resource/plugin.yml
@@ -1,4 +1,4 @@
-version: 3.14.4.0
+version: 3.14.4.1
 main: me.rockyhawk.commandpanels.CommandPanels
 name: CommandPanels
 author: RockyHawk
diff --git a/src/me/rockyhawk/commandpanels/CommandPanels.java b/src/me/rockyhawk/commandpanels/CommandPanels.java
index 894eb58..69d618d 100644
--- a/src/me/rockyhawk/commandpanels/CommandPanels.java
+++ b/src/me/rockyhawk/commandpanels/CommandPanels.java
@@ -71,6 +71,7 @@ public class CommandPanels extends JavaPlugin {
 
     //get alternate classes
     public CommandTags commandTags = new CommandTags(this);
+    public Placeholders placeholders = new Placeholders(this);
     public OpenEditorGuis editorGuis = new OpenEditorGuis(this);
     public ExecuteOpenVoids openVoids = new ExecuteOpenVoids(this);
     public ItemCreation itemCreate = new ItemCreation(this);
@@ -278,7 +279,7 @@ public class CommandPanels extends JavaPlugin {
     //regular string papi
     public String papi(Player p, String setpapi) {
         try {
-            setpapi = setCpPlaceholders(p,setpapi);
+            setpapi = placeholders.setCpPlaceholders(p,setpapi);
             if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
                 OfflinePlayer offp = getServer().getOfflinePlayer(p.getUniqueId());
                 setpapi = PlaceholderAPI.setPlaceholders(offp, setpapi);
@@ -293,7 +294,7 @@ public class CommandPanels extends JavaPlugin {
     //string papi with no colours
     public String papiNoColour(Player p, String setpapi) {
         try {
-            setpapi = setCpPlaceholders(p,setpapi);
+            setpapi = placeholders.setCpPlaceholders(p,setpapi);
             if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
                 OfflinePlayer offp = getServer().getOfflinePlayer(p.getUniqueId());
                 setpapi = PlaceholderAPI.setPlaceholders(offp, setpapi);
@@ -315,12 +316,12 @@ public class CommandPanels extends JavaPlugin {
     }
 
     //papi except if it is a String List
-    public List<String> papi(Player p, List<String> setpapi, boolean placeholders) {
+    public List<String> papi(Player p, List<String> setpapi, boolean placeholder) {
         try {
-            if(placeholders) {
+            if(placeholder) {
                 int tempInt = 0;
                 for (String temp : setpapi) {
-                    setpapi.set(tempInt, setCpPlaceholders(p, temp));
+                    setpapi.set(tempInt, placeholders.setCpPlaceholders(p, temp));
                     tempInt += 1;
                 }
                 if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
@@ -349,7 +350,7 @@ public class CommandPanels extends JavaPlugin {
         try {
             int tempInt = 0;
             for (String temp : setpapi) {
-                setpapi.set(tempInt, setCpPlaceholders(p, temp));
+                setpapi.set(tempInt, placeholders.setCpPlaceholders(p, temp));
                 tempInt += 1;
             }
             if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
@@ -363,202 +364,6 @@ public class CommandPanels extends JavaPlugin {
         return setpapi;
     }
 
-    @SuppressWarnings("deprecation")
-    public String setCpPlaceholders(Player p, String str) {
-        //replace nodes with PlaceHolders
-        str = str.replaceAll("%cp-player-displayname%", p.getDisplayName());
-        str = str.replaceAll("%cp-player-name%", p.getName());
-        str = str.replaceAll("%cp-player-world%", p.getWorld().getName());
-        str = str.replaceAll("%cp-player-x%", String.valueOf(Math.round(p.getLocation().getX())));
-        str = str.replaceAll("%cp-player-y%", String.valueOf(Math.round(p.getLocation().getY())));
-        str = str.replaceAll("%cp-player-z%", String.valueOf(Math.round(p.getLocation().getZ())));
-        str = str.replaceAll("%cp-online-players%", Integer.toString(Bukkit.getServer().getOnlinePlayers().size()));
-        str = str.replaceAll("%cp-tag%", papi(tag));
-        //placeholder to check for server availability %cp-server-IP:PORT%
-        while (str.contains("%cp-server-")) {
-            int start = str.indexOf("%cp-server-");
-            int end = str.indexOf("%", str.indexOf("%cp-server-")+1);
-            String ip_port = str.substring(start, end).replace("%cp-server-", "").replace("%","");
-            Socket s = new Socket();
-            try {
-                s.connect(new InetSocketAddress(ip_port.split(":")[0], Integer.parseInt(ip_port.split(":")[1])), config.getInt("config.server-ping-timeout"));
-                str = str.replace(str.substring(start, end) + "%", "true");
-                s.close();
-            }catch (IOException ex){
-                str = str.replace(str.substring(start, end) + "%", "false");
-            }
-        }
-
-        //set custom placeholders to their values
-        for(String[] placeholder : customCommand.getCCP(p.getName())){
-            while (str.contains(placeholder[0])) {
-                int start = str.indexOf(placeholder[0]);
-                int end = start+placeholder[0].length()-1;
-                str = str.replace(str.substring(start, end) + "%", placeholder[1]);
-            }
-        }
-
-        //DO placeholders for detection of other items in a panel
-        //get material value from slot in current open inventory (panel)
-        while (str.contains("%cp-material-")) {
-            try {
-                int start = str.indexOf("%cp-material-");
-                int end = str.indexOf("%", str.indexOf("%cp-material-") + 1);
-                String matNumber = str.substring(start, end).replace("%cp-material-", "").replace("%", "");
-                String material;
-                try {
-                    material = p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber)).getType().toString();
-                    if(legacy.isLegacy()){
-                        //add the ID to the end if it is legacy (eg, material:id)
-                        material = material + ":" + p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber)).getType().getId();
-                    }
-                } catch (NullPointerException er) {
-                    material = "AIR";
-                }
-                str = str.replace(str.substring(start, end) + "%", material);
-            }catch(Exception ex){
-                debug(ex);
-                break;
-            }
-        }
-        //get stack amount from slot in current open inventory (panel)
-        while (str.contains("%cp-stack-")) {
-            try {
-                int start = str.indexOf("%cp-stack-");
-                int end = str.indexOf("%", str.indexOf("%cp-stack-") + 1);
-                String matNumber = str.substring(start, end).replace("%cp-stack-", "").replace("%", "");
-                int amount;
-                try {
-                    amount = p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber)).getAmount();
-                } catch (NullPointerException er) {
-                    amount = 0;
-                }
-                str = str.replace(str.substring(start, end) + "%", String.valueOf(amount));
-            }catch(Exception ex){
-                debug(ex);
-                break;
-            }
-        }
-        //is an item damaged
-        while (str.contains("%cp-damaged-")) {
-            try {
-                int start = str.indexOf("%cp-damaged-");
-                int end = str.indexOf("%", str.indexOf("%cp-damaged-") + 1);
-                String matNumber = str.substring(start, end).replace("%cp-damaged-", "").replace("%", "");
-                boolean damaged = false;
-                ItemStack itm = p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber));
-                try {
-                    if(legacy.isLegacy()){
-                        if(itm.getType().getMaxDurability() != 0) {
-                            damaged = (itm.getType().getMaxDurability() - itm.getDurability()) < itm.getType().getMaxDurability();
-                        }
-                    }else {
-                        Damageable itemDamage = (Damageable) itm.getItemMeta();
-                        damaged = itemDamage.hasDamage();
-                    }
-                } catch (NullPointerException er) {
-                    damaged = false;
-                }
-                str = str.replace(str.substring(start, end) + "%", String.valueOf(damaged));
-            }catch(Exception ex){
-                debug(ex);
-                break;
-            }
-        }
-        //is an item identical, uses custom-items (custom item, slot)
-        while (str.contains("%cp-identical-")) {
-            try {
-                int start = str.indexOf("%cp-identical-");
-                int end = str.indexOf("%", str.indexOf("%cp-identical-") + 1);
-                String matLocSlot = str.substring(start, end).replace("%cp-identical-", "").replace("%", "");
-                String matLoc = matLocSlot.split(",")[0];
-                int matSlot = Integer.parseInt(matLocSlot.split(",")[1]);
-                boolean isIdentical = false;
-                ItemStack itm = p.getOpenInventory().getTopInventory().getItem(matSlot);
-
-                try {
-                    //if it is a regular custom item
-                    ItemStack confItm = itemCreate.makeItemFromConfig(openPanels.getOpenPanel(p.getName()).getConfigurationSection("custom-item." + matLoc),p,true,true, true);
-                    if(itm.isSimilar(confItm) && itm.getAmount() == confItm.getAmount()){
-                        isIdentical = true;
-                    }
-
-                    //if custom item is an mmo item (1.14+ for the API)
-                    String customItemMaterial = openPanels.getOpenPanel(p.getName()).getString("custom-item." + matLoc + ".material");
-                    if (getServer().getPluginManager().isPluginEnabled("MMOItems") && customItemMaterial.startsWith("mmo=")) {
-                        String mmoType = customItemMaterial.split("\\s")[1];
-                        String mmoID = customItemMaterial.split("\\s")[2];
-
-                        if (isMMOItem(itm,mmoType,mmoID) && itm.getAmount() <= confItm.getAmount()) {
-                            isIdentical = true;
-                        }
-                    }
-                } catch (NullPointerException er) {
-                    isIdentical = false;
-                }
-
-                str = str.replace(str.substring(start, end) + "%", String.valueOf(isIdentical));
-            }catch(Exception ex){
-                debug(ex);
-                break;
-            }
-        }
-
-        //does %cp-random-MIN,MAX%
-        while (str.contains("%cp-random-")) {
-            int start = str.indexOf("%cp-random-");
-            int end = str.indexOf("%", str.indexOf("%cp-random-") + 1);
-            String min_max = str.substring(start, end).replace("%cp-random-", "").replace("%", "");
-            int min = Integer.parseInt(min_max.split(",")[0]);
-            int max = Integer.parseInt(min_max.split(",")[1]);
-            str = str.replace(str.substring(start, end) + "%", String.valueOf(getRandomNumberInRange(min, max)));
-        }
-        while (str.contains("%cp-player-online-")) {
-            int start = str.indexOf("%cp-player-online-");
-            int end = str.indexOf("-find%",str.indexOf("%cp-player-online-")+1);
-            String playerLocation = str.substring(start, end).replace("%cp-player-online-", "");
-            Player[] playerFind = Bukkit.getOnlinePlayers().toArray(new Player[Bukkit.getOnlinePlayers().size()]);
-            if (Integer.parseInt(playerLocation) > playerFind.length) {
-                str = str.replace(str.substring(start, end) + "-find%", papi(Objects.requireNonNull(config.getString("config.format.offline"))));
-            } else {
-                str = str.replace(str.substring(start, end) + "-find%", playerFind[Integer.parseInt(playerLocation) - 1].getName());
-            }
-        }
-
-        try {
-            if (econ != null) {
-                str = str.replaceAll("%cp-player-balance%", String.valueOf(Math.round(econ.getBalance(p))));
-            }
-        } catch (Exception place) {
-            //skip
-        }
-        if (this.getServer().getPluginManager().isPluginEnabled("TokenManager")) {
-            TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager");
-            assert api != null;
-            str = str.replaceAll("%cp-tokenmanager-balance%", Long.toString(api.getTokens(p).orElse(0)));
-        }
-        if (this.getServer().getPluginManager().isPluginEnabled("VotingPlugin")) {
-            str = str.replaceAll("%cp-votingplugin-points%", String.valueOf(UserManager.getInstance().getVotingPluginUser(p).getPoints()));
-        }
-        if (str.contains("%cp-player-input%")) {
-            for (String[] key : userInputStrings) {
-                if (key[0].equals(p.getName())) {
-                    userInputStrings.add(new String[]{p.getName(), str});
-                    return "cpc";
-                }
-            }
-            userInputStrings.add(new String[]{p.getName(), str});
-            List<String> inputMessages = new ArrayList<String>(config.getStringList("config.input-message"));
-            for (String temp : inputMessages) {
-                temp = temp.replaceAll("%cp-args%", Objects.requireNonNull(config.getString("config.input-cancel")));
-                p.sendMessage(papi(p, temp));
-            }
-            str = "cpc";
-        }
-        //end nodes with PlaceHolders
-        return str;
-    }
-
     //check for duplicate panel names
     public boolean checkDuplicatePanel(CommandSender sender){
         ArrayList<String> apanels = new ArrayList<>();
diff --git a/src/me/rockyhawk/commandpanels/classresources/CommandTags.java b/src/me/rockyhawk/commandpanels/classresources/CommandTags.java
index 5b691a8..04f4724 100644
--- a/src/me/rockyhawk/commandpanels/classresources/CommandTags.java
+++ b/src/me/rockyhawk/commandpanels/classresources/CommandTags.java
@@ -4,7 +4,6 @@ import com.google.common.io.ByteArrayDataOutput;
 import com.google.common.io.ByteStreams;
 import me.realized.tokenmanager.api.TokenManager;
 import me.rockyhawk.commandpanels.CommandPanels;
-import net.mmogroup.mmolib.api.item.NBTItem;
 import org.apache.commons.lang.ArrayUtils;
 import org.bukkit.*;
 import org.bukkit.configuration.ConfigurationSection;
diff --git a/src/me/rockyhawk/commandpanels/classresources/ItemCreation.java b/src/me/rockyhawk/commandpanels/classresources/ItemCreation.java
index 2bb002b..338519d 100644
--- a/src/me/rockyhawk/commandpanels/classresources/ItemCreation.java
+++ b/src/me/rockyhawk/commandpanels/classresources/ItemCreation.java
@@ -331,8 +331,8 @@ public class ItemCreation {
                 //if output is true, and values match it will be this item, vice versa
                 outputValue = cf.getBoolean("hasvalue.output");
             }
-            String value = ChatColor.stripColor(plugin.papi(p,plugin.setCpPlaceholders(p,cf.getString("hasvalue.value"))));
-            String compare = ChatColor.stripColor(plugin.papi(p,plugin.setCpPlaceholders(p,cf.getString("hasvalue.compare"))));
+            String value = ChatColor.stripColor(plugin.papi(p,plugin.placeholders.setCpPlaceholders(p,cf.getString("hasvalue.value"))));
+            String compare = ChatColor.stripColor(plugin.papi(p,plugin.placeholders.setCpPlaceholders(p,cf.getString("hasvalue.compare"))));
             if (compare.equals(value) == outputValue) {
                 //onOpen being 3 means it is the editor panel.. hasvalue items cannot be included to avoid item breaking
                 String section = hasSection(Objects.requireNonNull(cf.getConfigurationSection("hasvalue")), p);
@@ -348,8 +348,8 @@ public class ItemCreation {
                         //if output is true, and values match it will be this item, vice versa
                         outputValue = cf.getBoolean("hasvalue" + count + ".output");
                     }
-                    value = ChatColor.stripColor(plugin.papi(p,plugin.setCpPlaceholders(p,cf.getString("hasvalue" + count + ".value"))));
-                    compare = ChatColor.stripColor(plugin.papi(p,plugin.setCpPlaceholders(p,cf.getString("hasvalue" + count + ".compare"))));
+                    value = ChatColor.stripColor(plugin.papi(p,plugin.placeholders.setCpPlaceholders(p,cf.getString("hasvalue" + count + ".value"))));
+                    compare = ChatColor.stripColor(plugin.papi(p,plugin.placeholders.setCpPlaceholders(p,cf.getString("hasvalue" + count + ".compare"))));
                     if (compare.equals(value) == outputValue) {
                         //onOpen being 3 means it is the editor panel.. hasvalue items cannot be included to avoid item breaking
                         String section = hasSection(Objects.requireNonNull(cf.getConfigurationSection("hasvalue" + count)), p);
@@ -492,4 +492,39 @@ public class ItemCreation {
         }
         return file;
     }
+
+    /*
+    The ItemStack 'one' will be used, if it doesn't have a lore for example, it won't check to see if the other does have one
+    The isIdentical() function will check for the following
+    Material, Name, Lore, Enchanted
+     */
+    public boolean isIdentical(ItemStack one, ItemStack two){
+        //check material
+        if(one.getType() != two.getType()){
+            return false;
+        }
+        //check for name
+        try {
+            if (!one.getItemMeta().getDisplayName().equals(two.getItemMeta().getDisplayName())) {
+                if(one.getItemMeta().hasDisplayName()) {
+                    return false;
+                }
+            }
+        }catch(Exception ignore){}
+        //check for lore
+        try {
+            if (!one.getItemMeta().getLore().equals(two.getItemMeta().getLore())) {
+                if(one.getItemMeta().hasLore()) {
+                    return false;
+                }
+            }
+        }catch(Exception ignore){}
+        //check for enchantments
+        if(one.getEnchantments().equals(two.getEnchantments())){
+            if(!one.getEnchantments().isEmpty()) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/src/me/rockyhawk/commandpanels/classresources/Placeholders.java b/src/me/rockyhawk/commandpanels/classresources/Placeholders.java
new file mode 100644
index 0000000..b99dd8f
--- /dev/null
+++ b/src/me/rockyhawk/commandpanels/classresources/Placeholders.java
@@ -0,0 +1,229 @@
+package me.rockyhawk.commandpanels.classresources;
+
+import com.bencodez.votingplugin.user.UserManager;
+import me.realized.tokenmanager.api.TokenManager;
+import me.rockyhawk.commandpanels.CommandPanels;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class Placeholders {
+    CommandPanels plugin;
+    public Placeholders(CommandPanels pl) {
+        this.plugin = pl;
+    }
+
+    @SuppressWarnings("deprecation")
+    public String setCpPlaceholders(Player p, String str) {
+        //replace nodes with PlaceHolders
+        str = str.replaceAll("%cp-player-displayname%", p.getDisplayName());
+        str = str.replaceAll("%cp-player-name%", p.getName());
+        str = str.replaceAll("%cp-player-world%", p.getWorld().getName());
+        str = str.replaceAll("%cp-player-x%", String.valueOf(Math.round(p.getLocation().getX())));
+        str = str.replaceAll("%cp-player-y%", String.valueOf(Math.round(p.getLocation().getY())));
+        str = str.replaceAll("%cp-player-z%", String.valueOf(Math.round(p.getLocation().getZ())));
+        str = str.replaceAll("%cp-online-players%", Integer.toString(Bukkit.getServer().getOnlinePlayers().size()));
+        str = str.replaceAll("%cp-tag%", plugin.papi(plugin.tag));
+        //placeholder to check for server availability %cp-server-IP:PORT%
+        while (str.contains("%cp-server-")) {
+            int start = str.indexOf("%cp-server-");
+            int end = str.indexOf("%", str.indexOf("%cp-server-")+1);
+            String ip_port = str.substring(start, end).replace("%cp-server-", "").replace("%","");
+            Socket s = new Socket();
+            try {
+                s.connect(new InetSocketAddress(ip_port.split(":")[0], Integer.parseInt(ip_port.split(":")[1])), plugin.config.getInt("config.server-ping-timeout"));
+                str = str.replace(str.substring(start, end) + "%", "true");
+                s.close();
+            }catch (IOException ex){
+                str = str.replace(str.substring(start, end) + "%", "false");
+            }
+        }
+
+        //set custom placeholders to their values
+        for(String[] placeholder : plugin.customCommand.getCCP(p.getName())){
+            while (str.contains(placeholder[0])) {
+                int start = str.indexOf(placeholder[0]);
+                int end = start+placeholder[0].length()-1;
+                str = str.replace(str.substring(start, end) + "%", placeholder[1]);
+            }
+        }
+
+        //DO placeholders for detection of other items in a panel
+        //get material value from slot in current open inventory (panel)
+        while (str.contains("%cp-material-")) {
+            try {
+                int start = str.indexOf("%cp-material-");
+                int end = str.indexOf("%", str.indexOf("%cp-material-") + 1);
+                String matNumber = str.substring(start, end).replace("%cp-material-", "").replace("%", "");
+                String material;
+                try {
+                    material = p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber)).getType().toString();
+                    if(plugin.legacy.isLegacy()){
+                        //add the ID to the end if it is legacy (eg, material:id)
+                        material = material + ":" + p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber)).getType().getId();
+                    }
+                } catch (NullPointerException er) {
+                    material = "AIR";
+                }
+                str = str.replace(str.substring(start, end) + "%", material);
+            }catch(Exception ex){
+                plugin.debug(ex);
+                break;
+            }
+        }
+        //get stack amount from slot in current open inventory (panel)
+        while (str.contains("%cp-stack-")) {
+            try {
+                int start = str.indexOf("%cp-stack-");
+                int end = str.indexOf("%", str.indexOf("%cp-stack-") + 1);
+                String matNumber = str.substring(start, end).replace("%cp-stack-", "").replace("%", "");
+                int amount;
+                try {
+                    amount = p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber)).getAmount();
+                } catch (NullPointerException er) {
+                    amount = 0;
+                }
+                str = str.replace(str.substring(start, end) + "%", String.valueOf(amount));
+            }catch(Exception ex){
+                plugin.debug(ex);
+                break;
+            }
+        }
+        //is an item damaged
+        while (str.contains("%cp-damaged-")) {
+            try {
+                int start = str.indexOf("%cp-damaged-");
+                int end = str.indexOf("%", str.indexOf("%cp-damaged-") + 1);
+                String matNumber = str.substring(start, end).replace("%cp-damaged-", "").replace("%", "");
+                boolean damaged = false;
+                ItemStack itm = p.getOpenInventory().getTopInventory().getItem(Integer.parseInt(matNumber));
+                try {
+                    if(plugin.legacy.isLegacy()){
+                        if(itm.getType().getMaxDurability() != 0) {
+                            damaged = (itm.getType().getMaxDurability() - itm.getDurability()) < itm.getType().getMaxDurability();
+                        }
+                    }else {
+                        Damageable itemDamage = (Damageable) itm.getItemMeta();
+                        damaged = itemDamage.hasDamage();
+                    }
+                } catch (NullPointerException er) {
+                    damaged = false;
+                }
+                str = str.replace(str.substring(start, end) + "%", String.valueOf(damaged));
+            }catch(Exception ex){
+                plugin.debug(ex);
+                break;
+            }
+        }
+        //is an item identical, uses custom-items (custom item, slot)
+        while (str.contains("%cp-identical-")) {
+            try {
+                int start = str.indexOf("%cp-identical-");
+                int end = str.indexOf("%", str.indexOf("%cp-identical-") + 1);
+                String matLocSlot = str.substring(start, end).replace("%cp-identical-", "").replace("%", "");
+                String matLoc = matLocSlot.split(",")[0];
+                int matSlot = Integer.parseInt(matLocSlot.split(",")[1]);
+                boolean isIdentical = false;
+                ItemStack itm = p.getOpenInventory().getTopInventory().getItem(matSlot);
+
+                try {
+                    //if it is a regular custom item
+                    ItemStack confItm = plugin.itemCreate.makeItemFromConfig(plugin.openPanels.getOpenPanel(p.getName()).getConfigurationSection("custom-item." + matLoc),p,true,true, true);
+                    if(plugin.itemCreate.isIdentical(confItm,itm)){
+                        isIdentical = true;
+                    }
+
+                    //if custom item is an mmo item (1.14+ for the API)
+                    String customItemMaterial = plugin.openPanels.getOpenPanel(p.getName()).getString("custom-item." + matLoc + ".material");
+                    if (plugin.getServer().getPluginManager().isPluginEnabled("MMOItems") && customItemMaterial.startsWith("mmo=")) {
+                        String mmoType = customItemMaterial.split("\\s")[1];
+                        String mmoID = customItemMaterial.split("\\s")[2];
+
+                        if (plugin.isMMOItem(itm,mmoType,mmoID) && itm.getAmount() <= confItm.getAmount()) {
+                            isIdentical = true;
+                        }
+                    }
+                } catch (NullPointerException er) {
+                    isIdentical = false;
+                }
+
+                str = str.replace(str.substring(start, end) + "%", String.valueOf(isIdentical));
+            }catch(Exception ex){
+                plugin.debug(ex);
+                break;
+            }
+        }
+
+        //does %cp-random-MIN,MAX%
+        while (str.contains("%cp-random-")) {
+            try {
+                int start = str.indexOf("%cp-random-");
+                int end = str.indexOf("%", str.indexOf("%cp-random-") + 1);
+                String min_max = str.substring(start, end).replace("%cp-random-", "").replace("%", "");
+                int min = Integer.parseInt(min_max.split(",")[0]);
+                int max = Integer.parseInt(min_max.split(",")[1]);
+                str = str.replace(str.substring(start, end) + "%", String.valueOf(plugin.getRandomNumberInRange(min, max)));
+            }catch (Exception ex){
+                plugin.debug(ex);
+                break;
+            }
+        }
+        while (str.contains("%cp-player-online-")) {
+            try {
+                int start = str.indexOf("%cp-player-online-");
+                int end = str.indexOf("-find%", str.indexOf("%cp-player-online-") + 1);
+                String playerLocation = str.substring(start, end).replace("%cp-player-online-", "");
+                Player[] playerFind = Bukkit.getOnlinePlayers().toArray(new Player[Bukkit.getOnlinePlayers().size()]);
+                if (Integer.parseInt(playerLocation) > playerFind.length) {
+                    str = str.replace(str.substring(start, end) + "-find%", plugin.papi(Objects.requireNonNull(plugin.config.getString("config.format.offline"))));
+                } else {
+                    str = str.replace(str.substring(start, end) + "-find%", playerFind[Integer.parseInt(playerLocation) - 1].getName());
+                }
+            }catch (Exception ex){
+                plugin.debug(ex);
+                break;
+            }
+        }
+
+        try {
+            if (plugin.econ != null) {
+                str = str.replaceAll("%cp-player-balance%", String.valueOf(Math.round(plugin.econ.getBalance(p))));
+            }
+        } catch (Exception place) {
+            //skip
+        }
+        if (plugin.getServer().getPluginManager().isPluginEnabled("TokenManager")) {
+            TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager");
+            assert api != null;
+            str = str.replaceAll("%cp-tokenmanager-balance%", Long.toString(api.getTokens(p).orElse(0)));
+        }
+        if (plugin.getServer().getPluginManager().isPluginEnabled("VotingPlugin")) {
+            str = str.replaceAll("%cp-votingplugin-points%", String.valueOf(UserManager.getInstance().getVotingPluginUser(p).getPoints()));
+        }
+        if (str.contains("%cp-player-input%")) {
+            for (String[] key : plugin.userInputStrings) {
+                if (key[0].equals(p.getName())) {
+                    plugin.userInputStrings.add(new String[]{p.getName(), str});
+                    return "cpc";
+                }
+            }
+            plugin.userInputStrings.add(new String[]{p.getName(), str});
+            List<String> inputMessages = new ArrayList<String>(plugin.config.getStringList("config.input-message"));
+            for (String temp : inputMessages) {
+                temp = temp.replaceAll("%cp-args%", Objects.requireNonNull(plugin.config.getString("config.input-cancel")));
+                p.sendMessage(plugin.papi(p, temp));
+            }
+            str = "cpc";
+        }
+        //end nodes with PlaceHolders
+        return str;
+    }
+}