Updating Scoreboards

Discussion in 'Plugin Development' started by Lightcaster5, Feb 6, 2020.

  1. Offline

    Lightcaster5

    So first things first, I can update the scoreboard correctly, it is set up the right way. This post is only dealing with the problems I have when there is more than one player on the server at a time. I have it where it updates every second (I created a repeating runnable but surrounded everything in it with a runTaskAsynchronously runnable so tps is fine). The problem is, when there are multiple players online, the scoreboard flashes the values of both players when updating. Here is some similar code to what im using:
    Code:
    public void updateScoreBoards() {
            if (Bukkit.getOnlinePlayers().size() == 0) {
                return;
            } else {
                for (Player currentPlayer : Bukkit.getOnlinePlayers()) {
                   
                    // Do stuff to update
                }
            }
        }
    And here is my runnable that I am starting with a method that is called from onEnable()
    Code:
    new BukkitRunnable() {
    
                @Override
                public void run() {
                    Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
                        @Override
                        public void run() {
                            updateScoreBoards();
                        }
                    });
                }
    
            }.runTaskTimer(plugin, 20L, 20L);
    Help would be greatly appreciated, thanks <3
     
  2. Offline

    timtower Moderator Moderator

    @Lightcaster5 Don't call Bukkit things asynch.
    And don't worry about TPS, if you lag the server with this then you are doing something very wrong. Just have it on a runTaskTimer.
    How are you updating the scoreboard itself? Are you making new ones or updating old ones?
     
  3. Offline

    Lightcaster5

    I don't know how else I should get each player when updating then. I'm using teams, I used the tutorial on spigot.org to have a scoreboard that doesn't flicker and all I'm doing is resetting the prefix and suffix of entries. Heres the link to the thread: https://www.spigotmc.org/wiki/making-scoreboard-with-teams-no-flicker/

    EDIT: Could I use a Map? Adding players to a hashmap when they join and removing when they leave and just getting all the players from the map tp update it?
     
  4. Offline

    timtower Moderator Moderator

    That will give the same result as just looping over all players...
    Please post the entire block of code.
     
  5. Offline

    Lightcaster5

    Heres a lot...
    Code (open)

    Code:
    package me.lightcaster5.hostilityminigame.scoreboard;
    
    import java.text.NumberFormat;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    import org.bukkit.Bukkit;
    import org.bukkit.entity.Player;
    import org.bukkit.scheduler.BukkitRunnable;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Score;
    import org.bukkit.scoreboard.Scoreboard;
    import org.bukkit.scoreboard.Team;
    
    import me.lightcaster5.hostilityminigame.Main;
    import me.lightcaster5.hostilityminigame.SQL.SQLManager;
    import me.lightcaster5.hostilityminigame.utils.ChatPrefixEvaluator;
    import me.lightcaster5.hostilityminigame.utils.LevelEvaluator;
    import me.lightcaster5.hostilityminigame.utils.MapHandler;
    
    public class ScoreBoardManager {
    
        private final Main plugin;
        private final SQLManager sql;
        private final ChatPrefixEvaluator cpe;
        private final MapHandler map;
        private final LevelEvaluator le;
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yy");
        public String date = "" + dtf.format(now);
        public Scoreboard scoreboard;
        public Objective objective;
        public NumberFormat numberFormat = NumberFormat.getInstance(Locale.US);
    
        public ScoreBoardManager(Main plugin, SQLManager sql, ChatPrefixEvaluator cpe, MapHandler map, LevelEvaluator le) {
            this.plugin = plugin;
            this.sql = sql;
            this.cpe = cpe;
            this.map = map;
            this.le = le;
        }
    
        public void createScoreboard() {
            scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
            objective = scoreboard.registerNewObjective("§b§lHOSTILITY", "dummy");
        }
    
        public void setScoreBoard(Player player) {
    
            objective.setDisplaySlot(DisplaySlot.SIDEBAR);
    
           
           
            if (scoreboard.getTeam("dateLabel") == null) {
                scoreboard.registerNewTeam("dateLabel");
            }
            scoreboard.getTeam("dateLabel").addEntry("§7§7§7");
            scoreboard.getTeam("dateLabel").setPrefix("§7" + date);
            objective.getScore("§7§7§7").setScore(15);
    
           
           
            Score blank1 = objective.getScore("§1§1§1§1");
            blank1.setScore(14);
    
           
           
            if (scoreboard.getTeam("blank2") == null) {
                scoreboard.registerNewTeam("blank2");
            }
            scoreboard.getTeam("blank2").addEntry("§2§2§2§2");
            scoreboard.getTeam("blank2").setPrefix("§f");
    
           
           
            if (scoreboard.getTeam("blank3") == null) {
                scoreboard.registerNewTeam("blank3");
            }
            scoreboard.getTeam("blank3").addEntry("§3§3§3§3");
            scoreboard.getTeam("blank3").setPrefix("§f");
    
           
           
            if (scoreboard.getTeam("websiteLine") == null) {
                scoreboard.registerNewTeam("websiteLine");
            }
            scoreboard.getTeam("websiteLine").addEntry("§1§2§3");
            scoreboard.getTeam("websiteLine").setPrefix("§eplay.host");
            scoreboard.getTeam("websiteLine").setSuffix("§eility.cc");
    
           
           
            if (scoreboard.getTeam("goldCounter") == null) {
                scoreboard.registerNewTeam("goldCounter");
            }
            scoreboard.getTeam("goldCounter").addEntry("§6§6§6");
            scoreboard.getTeam("goldCounter").setPrefix("§fGold: §6");
            scoreboard.getTeam("goldCounter").setSuffix(numberFormat.format(sql.getPlayerGold(player.getUniqueId())) + "§6g");
    
           
           
            if (scoreboard.getTeam("levelCounter") == null) {
                scoreboard.registerNewTeam("levelCounter");
            }
            scoreboard.getTeam("levelCounter").addEntry("§2§2§2");
            scoreboard.getTeam("levelCounter").setPrefix("§fCurent Level: ");
            scoreboard.getTeam("levelCounter").setSuffix(cpe.getPrefixNoPrestige(player.getUniqueId()));
    
           
           
            if (scoreboard.getTeam("xpCounter") == null) {
                scoreboard.registerNewTeam("xpCounter");
            }
            Team xpCounter = scoreboard.getTeam("xpCounter");
            xpCounter.addEntry("§3§3§3");
            if (sql.getPlayerLevel(player.getUniqueId()) >= 120) {
                xpCounter.setPrefix("§fNeeded XP: ");
                xpCounter.setSuffix("§bMAXED");
            } else {
                xpCounter.setPrefix("§fNeeded XP: ");
                xpCounter.setSuffix("§b" + le.experienceToNextLevel(player.getUniqueId()));
            }
    
           
           
            if (scoreboard.getTeam("prestigeCounter") == null) {
                scoreboard.registerNewTeam("prestigeCounter");
            }
            Team prestigeCounter = scoreboard.getTeam("prestigeCounter");
            if (sql.getPlayerPrestige(player.getUniqueId()) != 0) {
                if (!prestigeCounter.hasEntry("§e§e§e")) {
                    prestigeCounter.addEntry("§e§e§e");
                }
                prestigeCounter.setPrefix("§fPrestige: §e");
                prestigeCounter.setSuffix(cpe.toRoman(sql.getPlayerPrestige(player.getUniqueId())));
                objective.getScore("§2§2§2").setScore(13);
                objective.getScore("§3§3§3").setScore(12);
                objective.getScore("§3§3§3§3").setScore(11);
                objective.getScore("§e§e§e").setScore(10);
                objective.getScore("§6§6§6").setScore(9);
                objective.getScore("§2§2§2§2").setScore(8);
                objective.getScore("§1§2§3").setScore(7);
            } else {
                scoreboard.resetScores("§e§e§e");
                prestigeCounter.setPrefix("");
                prestigeCounter.setSuffix("");
                objective.getScore("§2§2§2").setScore(13);
                objective.getScore("§3§3§3").setScore(12);
                objective.getScore("§3§3§3§3").setScore(11);
                objective.getScore("§6§6§6").setScore(10);
                objective.getScore("§2§2§2§2").setScore(9);
                objective.getScore("§1§2§3").setScore(8);
    
            }
    
            player.setScoreboard(scoreboard);
    
        }
    
        public void updateScoreBoards() {
            if (Bukkit.getOnlinePlayers().size() == 0) {
                return;
            } else {
                for (Player currentPlayer : map.onlinePlayerList) {
                   
                    if (currentPlayer.getScoreboard() != null) {
                        Scoreboard scoreboard = currentPlayer.getScoreboard();
    
                        scoreboard.getTeam("dateLabel").setPrefix("§7" + date);
    
                        scoreboard.getTeam("goldCounter").setPrefix("§fGold: §6");
                        scoreboard.getTeam("goldCounter")
                                .setSuffix(numberFormat.format(sql.getPlayerGold(currentPlayer.getUniqueId())) + "§6g");
    
                        scoreboard.getTeam("levelCounter").setPrefix("§fCurent Level: ");
                        scoreboard.getTeam("levelCounter").setSuffix(cpe.getPrefixNoPrestige(currentPlayer.getUniqueId()));
    
                        scoreboard.getTeam("xpCounter").setPrefix("§fNeeded XP: ");
                        if (sql.getPlayerLevel(currentPlayer.getUniqueId()) >= 120) {
                            scoreboard.getTeam("xpCounter").setPrefix("§fNeeded XP: ");
                            scoreboard.getTeam("xpCounter").setSuffix("§bMAXED");
                        } else {
                            scoreboard.getTeam("xpCounter").setPrefix("§fNeeded XP: ");
                            scoreboard.getTeam("xpCounter")
                                    .setSuffix("§b" + le.experienceToNextLevel(currentPlayer.getUniqueId()));
                        }
    
                        Team prestigeCounter = scoreboard.getTeam("prestigeCounter");
    
                        if (sql.getPlayerPrestige(currentPlayer.getUniqueId()) != 0) {
                            if (!prestigeCounter.hasEntry("§e§e§e")) {
                                prestigeCounter.addEntry("§e§e§e");
                            }
                            prestigeCounter.setPrefix("§fPrestige: §e");
                            prestigeCounter.setSuffix(cpe.toRoman(sql.getPlayerPrestige(currentPlayer.getUniqueId())));
                            objective.getScore("§2§2§2").setScore(13);
                            objective.getScore("§3§3§3").setScore(12);
                            objective.getScore("§3§3§3§3").setScore(11);
                            objective.getScore("§e§e§e").setScore(10);
                            objective.getScore("§6§6§6").setScore(9);
                            objective.getScore("§2§2§2§2").setScore(8);
                            objective.getScore("§1§2§3").setScore(7);
                        } else {
                            scoreboard.resetScores("§e§e§e");
                            prestigeCounter.setPrefix("");
                            prestigeCounter.setSuffix("");
                            objective.getScore("§2§2§2").setScore(13);
                            objective.getScore("§3§3§3").setScore(12);
                            objective.getScore("§3§3§3§3").setScore(11);
                            objective.getScore("§6§6§6").setScore(10);
                            objective.getScore("§2§2§2§2").setScore(9);
                            objective.getScore("§1§2§3").setScore(8);
    
                        }
    
                    } else {
                        Bukkit.getConsoleSender().sendMessage("§c§lScoreboard was null!!!");
                    }
                }
            }
        }
    
        public void start() {
            new BukkitRunnable() {
    
                @Override
                public void run() {
                    Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
                        @Override
                        public void run() {
                            map.addOneRepeat();
                            updateScoreBoards();
                        }
                    });
                }
    
            }.runTaskTimer(plugin, 20L, 20L);
        }
    
    }
    
     
  6. Offline

    timtower Moderator Moderator

  7. Offline

    Lightcaster5

    No, I thought about doing that somehow but I didn't know how.

    EDIT: I mean should I really need to do that? The response from the DB is very fast so I don't see how caching it would change much. Either way, I don't really know much about SQL and caching so I don't know if that would be a better route.
     
    Last edited: Feb 7, 2020
  8. Offline

    timtower Moderator Moderator

    @Lightcaster5 DB should not be called sync. Regardless of how fast.
     
  9. Offline

    Lightcaster5

    Do you have a thread of some sort that could get me started on how to cache data?
     
  10. Offline

    KarimAKL

    @timtower About the "async scoreboard" topic; do you know if you can create an async scoreboard using NMS instead of Bukkit? If so, @Lightcaster5 might want that.
     
  11. Offline

    timtower Moderator Moderator

    As far as async is possible in any way for this.
    My best suggestion would be to load all values from the database async, then let that start a sync runnable to handle the scoreboard itself.
     
  12. Offline

    Lightcaster5

    Well I mean I am getting the data from the db async right?
    Also while in civics class (dont even get me started on my timing) I was thinking of ways to go about this and thought I could use my map that holds a list of all online players and before I do any actual updating but still in the updateScoreboards() method, create a hashmap with the UUIDs of players along with their data. Im going to try this and get back to you guys on this.

    EDIT: Just tried it, it has something to do with the way im trying to update it for each player. Any ideas on other ways I could update it?

    bump

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Feb 8, 2020

Share This Page