Solved Automatically update a sign

Discussion in 'Plugin Development' started by HCMatt, Apr 29, 2019.

Thread Status:
Not open for further replies.
  1. Offline

    HCMatt

    I am in the middle of creating a leaderboard plugin. This is how it works so far:

    1. Place a sign
    2. Line 1 = lboard
    3. Line 2 =1 (which place in the leader board you want it to be)
    4. Right click the Sign
    This then sends you a message with 1st place and how many kills they have and shows this on the sign. This all works fine.

    However, I need the sign to automatically update every so often. This is what I have tried:

    Code:
                                Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
    
                                    @Override
                                    public void run() {
                                        p.sendMessage("lboard updated");
                                        s.setLine(2, ChatColor.AQUA + name);
                                        s.setLine(3, ChatColor.DARK_AQUA + killsString);
                                        s.update();
                                    }
    
                                }, 20, 200);
    I have the time set so low for testing purposes.

    This code sends the "lboard updated" message successfully but the sign does not update.

    Thanks in advance.

    Mat
     
  2. Offline

    MightyOne

    I can't tell why the sign doesn't update but I also don't know how name and killString are computed. Maybe show some more of your code.

    Anyway, I could imagine that updating the sign in the EntityDamageByEntityEvent would be much more direct than letting a BukkitRunnable check every soandso ticks.
     
  3. Offline

    HCMatt

    This is my whole Event Handler

    Code:
           @EventHandler
        public void createLeaderboardSign(final PlayerInteractEvent e) {
            Player p = e.getPlayer();
            Action a = e.getAction();
    
            if (a == Action.RIGHT_CLICK_BLOCK) {
                Block b = e.getClickedBlock();
                if (b.getType() == Material.SIGN_POST || b.getType() == Material.WALL_SIGN) {
                    Sign s = (Sign) b.getState();
                    if (s.getLine(0).equalsIgnoreCase("lboard")) {
                        if (s.getLine(1).isEmpty()) {
                            p.sendMessage(ChatColor.RED + "You must specify a position for this sign.");
                        } else if (s.getLine(1).equalsIgnoreCase("1")) {
                            if (!p.hasPermission("rev.lboard.createsign")) {
                                p.sendMessage(ChatColor.RED + "You do not have permission to create a Leaderboard Sign.");
                                return;
                            } else {
                                s.setLine(0, ChatColor.GREEN + "[Leaderboard]");
                                s.setLine(1, ChatColor.BLUE + "First Place");
                                p.sendMessage(ChatColor.GREEN + "You created a sign for Leaderboard Rank: " + ChatColor.AQUA + "#1");
    
                                int maxKills = 0;
                                String maxKillsPlayer = "";
    
                                for (String playerName : getConfig().getConfigurationSection("Revelation.Stats.").getKeys(false)) {
                                    int kills = getConfig().getInt("Revelation.Stats." + playerName + ".Kills");
                                    if (kills > maxKills) {
                                        maxKills = kills;
                                        maxKillsPlayer = playerName;
                                    }
                                }
                                p.sendMessage("Most Kills: " + maxKillsPlayer + " with " + maxKills + " kills.");
    
                                String name = maxKillsPlayer;
                                String killsString = String.valueOf(maxKills);
                                Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
    
                                    @Override
                                    public void run() {
                                        /*works*/p.sendMessage("lboard updated");
                                        /*doesntwork*/s.setLine(2, ChatColor.AQUA + name);
                                        /*doesntwork*/s.setLine(3, ChatColor.DARK_AQUA + killsString);
                                        /*doesntwork*/s.update();
                                    }
    
                                }, 20, 200);
                            }
                        }
                    }
                }
            }
        }
    I figured this out myself.. Just incase anyone needs help with this:

    I needed to move this:
    Code:
                               int maxKills = 0;
                                String maxKillsPlayer = "";
    
                                for (String playerName : getConfig().getConfigurationSection("Revelation.Stats.").getKeys(false)) {
                                    int kills = getConfig().getInt("Revelation.Stats." + playerName + ".Kills");
                                    if (kills > maxKills) {
                                        maxKills = kills;
                                        maxKillsPlayer = playerName;
                                    }
                                }
                                p.sendMessage("Most Kills: " + maxKillsPlayer + " with " + maxKills + " kills.");
    
                                String name = maxKillsPlayer;
                                String killsString = String.valueOf(maxKills);
    Inside the runnable. So this is the new code that fully works:

    Code:
                                s.setLine(0, ChatColor.GREEN + "[Leaderboard]");
                                s.setLine(1, ChatColor.BLUE + "First Place");
                                p.sendMessage(ChatColor.GREEN + "You created a sign for Leaderboard Rank: " + ChatColor.AQUA + "#1");
    
                               
                                Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
    
                                    @Override
                                    public void run() {
                                        int maxKills = 0;
                                        String maxKillsPlayer = "";
    
                                        for (String playerName : getConfig().getConfigurationSection("Revelation.Stats.").getKeys(false)) {
                                            int kills = getConfig().getInt("Revelation.Stats." + playerName + ".Kills");
                                            if (kills > maxKills) {
                                                maxKills = kills;
                                                maxKillsPlayer = playerName;
                                            }
                                        }
                                        Bukkit.broadcastMessage(ChatColor.GRAY + "[" + ChatColor.DARK_AQUA + "Leaderboard" + ChatColor.GRAY + "]" + ChatColor.AQUA + " The Leaderboard has been updated!");
    
                                        String name = maxKillsPlayer;
                                        String killsString = String.valueOf(maxKills);
                                        s.setLine(2, ChatColor.AQUA + name);
                                        s.setLine(3, ChatColor.DARK_AQUA + killsString);
                                        s.update(true);
                                    }
                                }, 20, 6000);
                            }
    So now, once the sign is created, every 5 minutes it will update with the new highest kills player.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Apr 29, 2019
Thread Status:
Not open for further replies.

Share This Page