Solved Need Code that get values out of strings and lores.

Discussion in 'Spigot Plugin Help' started by FatP, May 17, 2019.

  1. Hello,

    i currently made a shop that look like this:
    It's only the gui.
    I am currently on the click event and want to try to make it simplier than just having an own click event for every block.

    Instead i want a code that can extract all the data and save it into variables that i can use.
    I hope you can help me and show me some examples!


  2. Hello,

    What you want to achieve seems focused on the inventory click event. I mean, I don't think that you have other solutions for a GUI...

    Listening to the InventoryClickEvent, get the item clicked, and then get the datas that you need on it.
  3. Yes,

    here is my code i used for special things like spawners:

    if (clicked.getItemMeta().getDisplayName().equals("§fChicken Spawner")) {
    Integer price = 64350;
    if ( > (price - 1)) {, price);
    ItemStack item = (new ItemStack(Material.MOB_SPAWNER));
    ItemMeta itemm = item.getItemMeta();
    } else {

    But that is too tedious to do with 100+ items.
    So i am asking if there is a method to get all the stuff, like price, amount and things automatically trough the lores.
  4. I think the best way would be to create a wrapper class with all the data needed (displayName, price, item...), and a void like "execute()".

    When the plugin load, add all your custom things into a Map<String, WrapperClass>, where the String can be the display name of the item, or the Material.

    In the InventoryClickEvent, get from the map the wrapper class (from the display name for example) and just execute it.
  5. Strahan


    I'd just save it all in a database and load it from that so if you decide to change prices or items, you don't have to recompile a plugin.
  6. These both things are possible, but like i said.
    I want to try to make my life easier and not copy paste 100x the same code.

    I heard it's possible, so i am asking for someone can give me an example solution for my problem.

    Code (Java):
                           List<String> lore = clicked.getItemMeta().getLore();
                           String loreLine = lore.get(1);
    With this, i am in the correct line:
    "Price: $"Number""
    And i need to extract the Number somehow.

    If you can please help me with that.

    I am reffering to other post that seemed to fixed their problem, but i don't know how and their supposed solution doesn't work for me :/.
  7. A method I use is hiding item IDs in item lore and using a custom class like @Andross suggested. You basically come up with an ID system, you can use integers, or UUIDs see here for "serial numbers".
    You then use the chat color symbol to hide the ID from being visible to players on the item. for integers you can use something like this:
    Code (Java):

    public static Integer idToInt(String string)
         return Integer.parseInt(string.replace("§", ""));
        public static String intToId(Integer integer)
         String intString = "";
         for (int i = 0; i < integer.toString().length(); i++)
          intString += "§" + integer.toString().charAt(i);
         return intString;
    Take note that if you want items to stack (if they can stack normally), they must have the same ID on them, which means they will have the same properties when you look them up later. (Technically the need the identical names and lore, but you get the idea.)

    So now that you hid an item ID in the item lore somewhere, you have to devise a system that will use that ID to come up with some kind of useful information like price or something.

    You can save that info as a Map like @Andross suggested: Map<(Integer, UUID, String, what ever kind of ID your using), Custom Class You Created>, and then save that map in a database like @Strahan suggested, or "flat file" or something.

    So if the custom class you created is simply
    Code (Java):

    public class YourPluginItem {
        Double price;
        Player originalOwner;
        String someTextYouWantedToSave;
    You can simply read the item lore one time, find the ID, then say ok, this item is of ID type X, what item belongs to ID X, and what properties does it have.
    It saves you doing everything 100 times, but if you have 100 different kind of unique items you don't really have a choice other than making 100 kind of unique items.
  8. Just make an API for GUI’s, and you won’t need to get data from the item meta at all
  9. Can please someone just tell me:

    How i can get the number (integer) out of the lore : Price: $Number

    Thank you...

    I appreciate your suggestions, but i want to try it first with my method i have in my brain...
  10. I have solved it on my own.
  11. Strahan


    Of course, that's specifically why I said a database. You should never copy/paste code like that, it's a sign that your approach to the functionality is not correct. If you have the data in a database, you just loop the resultset to get the data. Only one code block.
  12. If i have the data in the database, i still have to write down all the data 100 times.
    Currently i just take the data from the lore.
    From the lore i have already done... so i don't do work twice. easy as that
  13. Strahan


    In your example, it's oak logs. So you're saying the person has oak logs to sell and the code will look at the logs to get the values? How does that work when they cut a tree down, is it automatically applying lore to it? Or do you mean you are looking at lore on the items used in the GUI?

    Either way, it's not ideal. What happens when you want to change prices? You need to dick around with the lore. Even more annoying if you were to change the price of, say, base wood logs. Then you need to update many lores to cover all the varieties, assuming you are listing them individually. It'd be much easier to just have all the values in a DB (or even a regular YAML config file) that is parsed dynamically. Sure, you need to load it initially but that's a one time thing and can be done automatically.

    But anyway, if you're satisfied with what you have, that's fine. It doesn't have to be efficient so long as you are happy with it :)

  14. Maybe there is a miscommunication or misunderstanding here.
    What i requested is only for buying items. Means, these things are only in the shop available and you would receive normal logs without lores in it.
    And if i want to change the price, i just have to change the ore.
    Our server is not released yet, so it's fine for us reloading it some times :)

    Ofc. for a sell shop, i will do it with config files. But in the sell shop, i won't have all items listened, only the important.

    Please Note, that i never disliked all your ideas, but i was just searchin for help for my problem
    and especially when i asked a second time to only answer my question
    you could have just told me how to do it...

    Anyway, have a nice day
  15. Strahan


    Yea, I must just not be on the same page. Well, to your issue, just pull the lore and parse the string. That's fairly simplistic; what part is giving you a problem?

    I just dicked around with it, here is what I had to parse it. This assumes that the format is static, of course if one changes the lore you'd need to fix this.
    Code (Text):
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        Player p = (Player)sender;
        ItemStack i = p.getInventory().getItemInMainHand();
        switch (label.toLowerCase()) {
        case "cmd1":
            List<String> tmp = new ArrayList<String>();
            tmp.add(ChatColor.YELLOW + "Price: " + ChatColor.GREEN + "$234");
            tmp.add(ChatColor.YELLOW + "Amount: " + ChatColor.GREEN + "32");
            ItemMeta im = i.getItemMeta(); im.setLore(tmp); i.setItemMeta(im);
        case "cmd2":
            Map<String, Integer> values = getShopValues(i);
            if (values == null) {
                p.sendMessage("This isn't a shop item.");
                return true;
            p.sendMessage(((!values.containsKey("price"))?"No price found":"Price: $" + values.get("price").toString()));
            p.sendMessage(((!values.containsKey("amount"))?"No amount found":"Amount: " + values.get("amount").toString()));
        return true;

    Map<String, Integer> getShopValues(ItemStack i) {
        if (!i.hasItemMeta()) return null;
        ItemMeta im = i.getItemMeta();
        if (!im.hasLore()) return null;

        Map<String, Integer> ret = new HashMap<String, Integer>();
        for (String tmp : im.getLore()) {
            tmp = ChatColor.stripColor(tmp).toLowerCase();
            try {
                if (tmp.indexOf("price:") > -1) ret.put("price", Integer.valueOf(tmp.substring(8, tmp.length())));
                if (tmp.indexOf("amount:") > -1) ret.put("amount", Integer.valueOf(tmp.substring(8, tmp.length())));
            } catch (NumberFormatException e) {
        return ret;
    I just made a command to set the lore to test then another to read it. Obviously the "meat" of it is the function, not the commands.
    #15 Strahan, May 20, 2019
    Last edited: May 20, 2019