1.15.2 Please help me fix this

Discussion in 'Spigot Plugin Development' started by SoberLone, Apr 3, 2020.

  1. Hello,

    This is the method i am using (getting information from config):

    Code (Text):
    public ItemStack getItem(Player player, int item) {
            ItemStack stack = new ItemStack(Material.matchMaterial(this.main.getConfig().getString("gamemodes." + item + ".material")));
            String name = this.main.getConfig().getString("gamemodes." + item + ".display-name");
            List<String> lore = this.main.getConfig().getStringList("gamemodes." + item + ".lore");
            if (name != null || name != "none" || lore != null || lore.get(0) != "none") {
                List<String> lore0 = new ArrayList<>();
                ItemMeta meta = stack.getItemMeta();
                if (name != null || name != "none")
                    meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
                if (lore != null || lore.get(0) != "none") {
                    int i = 0;
                    while (i != lore.size()) {
                        lore0.add(ChatColor.translateAlternateColorCodes('&', lore.get(i)
                                .replace("%online%", " " +
                                        main.serverCount.get(ChatColor.stripColor(
                                                main.getConfig().getString("gamemodes." + item + ".serverIdentifier"))))));
                        i++;
                    }
                    meta.setLore(lore0);
                }
                stack.setItemMeta(meta);
            }
            return stack;

        }
    I am replacing %online% (the placeholder) with the amount of players on the server (This works!).

    My only issue is that i cannot get it to update, if i use a runnable it is completely breaking the items.

    Thank you in advance.
     
  2. Nothing immediately catches my eye, so I'm curious if the problem lies in what you're doing after you call this method. Once you give the item to a player, maybe try calling Player#updateInventory (yes, even though it's deprecated).

    Also, don't save items like this. Bukkit has specific methods for saving an ItemStack. Use getConfig().getItemStack("path") and getConfig.set("path", ItemStack) instead of what you're doing. Saves time and prevents lore with certain YAML characters from breaking your config.
     
  3. Thats quite brief. Im not sure which part i need to update and how to do it
     
  4. Choco

    Moderator

    You cannot compare Strings with an equality operator. This is a reference comparison ensuring two objects are located at the same memory address (and consequently, are the same instance). Unless the strings are internalized, a literal will not often == another value. "test" == "test" is false (this is incorrect, my mistake). Compare the contents of a String with its .equals() method.
     
    #4 Choco, Apr 3, 2020
    Last edited: Apr 3, 2020
  5. This is not entirely true. Literals, in fact, are always interned, which is why "test" == "test" returns true (in this case they would also be in the same constant pool). The problem is that the string in question (name) is not a literal and therefore not interned. Apart from that, you're correct. To compare the value, i.e. the content of a String, you must use equals().
     
  6. Choco

    Moderator

    You're right. That's my mistake.
     
    • Friendly Friendly x 1
  7. You mentioned you're using a runnable. Are you running it on asynchronously? If so, it might explain why it's breaking the object. Try switching to a synchronized runnable instead if this is the case. Calling Bukkit API methods asynchronously is bad news.
     
  8. I completely removed the method, as it was not working correctly :)

    https://imgur.com/16JEnn9

    I'm trying to update the playercount at the bottom every second, not sure how to do it though
    (I have the method working, i mean just updating the lore)
     
  9. Bump, could someone help me sort a method to update the lore of the item
     
  10. Keep a set of players who have the GUI open (add when player opens GUI, remove when closes). Everytime the server count switches, create your new ItemStack with your method and iterate over your set and update each inventory one tick later.
     
  11. I haven't looked at spigot in a couple years but I'm sure you could use a scheduler to update the lore every couple seconds. If you update it too quickly it will reset the item position and meta data too quickly and will freak out. Try a bigger delay.

    Code (Text):
    Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
        @Override
        public void run() {
            Bukkit.broadcastMessage("This message is shown immediately and then repeated every second");
        }
    }, 0L, 20L); //0 Tick initial delay, 20 Tick (1 Second) between repeats