Updating scoreboard not working

Discussion in 'Plugin Development' started by Maxx_Qc, Oct 27, 2015.

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

    Maxx_Qc

    Hi guys.
    I'm making a plugin for my lobby's server and I want to add a scoreboard.
    This scoreboard needs to be updated each ~20 ticks to show the number of players in each server.
    ScoreboardAPI.java (open)

    Code:
    package qc.maxx.epichub.util;
    
    import com.google.common.base.Preconditions;
    import com.google.common.collect.Lists;
    import com.google.common.collect.Maps;
    import java.util.List;
    import java.util.Map;
    import org.bukkit.Bukkit;
    import org.bukkit.entity.Player;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Scoreboard;
    import org.bukkit.scoreboard.Team;
    
    public class ScoreBoardAPI
    {
        private Scoreboard scoreboard;
        private String title;
        private Map<String, Integer> scores;
        private List<Team> teams;
    
        public ScoreBoardAPI(String title)
        {
            this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
            this.title = title;
            this.scores = Maps.newLinkedHashMap();
            this.teams = Lists.newArrayList();
        }
    
        public void blankLine()
        {
            add(" ");
        }
    
        public void add(String text)
        {
            add(text, null);
        }
    
        public void add(String text, Integer score)
        {
            Preconditions.checkArgument(text.length() < 48, "text cannot be over 48 characters in length");
            text = fixDuplicates(text);
            this.scores.put(Colorize.c(text), score);
        }
    
        private String fixDuplicates(String text)
        {
            while (this.scores.containsKey(text)) {
                text = text + Colorize.c("&r");
            }
            if (text.length() > 48) {
                text = text.substring(0, 47);
            }
            return text;
        }
    
        public void build()
        {
            Objective obj = this.scoreboard.registerNewObjective(this.title.length() > 16 ? this.title.substring(0, 15) : this.title, "dummy");
            obj.setDisplayName(this.title);
            obj.setDisplaySlot(DisplaySlot.SIDEBAR);
      
            int index = this.scores.size();
            for (Map.Entry<String, Integer> text : this.scores.entrySet())
            {
                Integer score = Integer.valueOf(text.getValue() != null ? ((Integer)text.getValue()).intValue() : index);
                obj.getScore((String)text.getKey()).setScore(score.intValue());
                index--;
            }
        }
    
        public void reset()
        {
            this.title = null;
            this.scores.clear();
            for (Team t : this.teams) {
                t.unregister();
            }
            this.teams.clear();
        }
    
        public Scoreboard getScoreboard()
        {
            return this.scoreboard;
        }
    
        public void send(Player... players)
        {
            Player[] arrayOfPlayer;
            int j = (arrayOfPlayer = players).length;
            for (int i = 0; i < j; i++)
            {
                Player p = arrayOfPlayer[i];
                p.setScoreboard(this.scoreboard);
            }
        }
    }


    PlayerJoin.java (open)

    Code:
    package qc.maxx.epichub.events;
    
    import org.bukkit.Bukkit;
    import org.bukkit.GameMode;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
    
    import qc.maxx.epichub.main.EpicHub;
    import qc.maxx.epichub.util.Colorize;
    import qc.maxx.epichub.util.ScoreBoardAPI;
    import qc.maxx.epichub.util.Scroller;
    
    public class PlayerJoin implements Listener
    {
        private EpicHub plugin;
    
        public PlayerJoin(EpicHub plugin)
        {
            this.plugin = plugin;
            plugin.getServer().getPluginManager().registerEvents(this, plugin);
        }
      
        @SuppressWarnings("deprecation")
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent e)
        {
            e.setJoinMessage(plugin.getJoinMsg().replaceAll("%p", e.getPlayer().getName()));
            if(plugin.isSpawnSetup())
            {
                e.getPlayer().teleport(plugin.getSpawnLocation());
            }
            e.getPlayer().setGameMode(GameMode.ADVENTURE);
            e.getPlayer().setHealth(e.getPlayer().getMaxHealth());
            e.getPlayer().setFoodLevel(20);
            ItemStack clock = new ItemStack(Material.WATCH);
            ItemMeta clockMeta = clock.getItemMeta();
            clockMeta.setDisplayName(Colorize.c(this.plugin.getMagicClockName()));
            clock.setItemMeta(clockMeta);
            e.getPlayer().getInventory().setItem(8, clock);
            e.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 9999, 1));
            e.getPlayer().setAllowFlight(true);
          
            Scroller scroller = new Scroller("&9Network EpicFight", 20, 8, '&');
            final ScoreBoardAPI scoreboard = new ScoreBoardAPI(Colorize.c(scroller.next()));
            scoreboard.add("&6&l> &eLobby: &b" + plugin.getServer().getOnlinePlayers().size());
            scoreboard.add("  &eFactions: &b" + "0");
            scoreboard.add("  &ePvP: &b" + "0");
            scoreboard.add("  &eEvent: &b" + "0");
            scoreboard.add("  &eSoon: &b" + "0");
            scoreboard.blankLine();
            scoreboard.add("&awww.epicfight.fr");
            scoreboard.build();
          
            Bukkit.getServer().getScheduler().runTaskTimer(plugin, new Runnable()
            {
                public void run()
                {
                    scoreboard.send(Bukkit.getOnlinePlayers().toArray(new Player[0]));            
                }
            }, 0L, 50L);
          
            if(!e.getPlayer().hasPermission("epichub.admin.donthide"))
            {
                for(String s : plugin.getTogglePlayers())
                {
                    Player p = Bukkit.getPlayerExact(s);
                    if(p != null)
                    {
                        p.hidePlayer(e.getPlayer());
                    }
                }
            }
        }
    }
    

    Screen of my problem: [​IMG]
    Also, the scoreboard's name should be scrolling but it is not moving.
    Thank you!
     
    Last edited: Oct 27, 2015
  2. Offline

    Irantwomiles

    Haven't dealt with scoreboards in a while but can't you just have an int and add/subtract on player join/leave?
     
  3. Offline

    Maxx_Qc

    @Irantwomiles No because it uses multiple servers.
    Look at the screen
     
  4. Offline

    567legodude

    @Maxx_Qc Here is a couple things:
    1. It's not scrolling because scroller.next() is only called once, to set the title of the board at the beginning.
    2. scoreboard.send(Bukkit.getOnlinePlayers().toArray(new Player[0]));
    - That's not how you want to update the scoreboard to players on the server.

    Instead of sending the scoreboard every few ticks, why don't you just update it whenever a value changes.
     
  5. Offline

    Maxx_Qc

    @567legodude because each x ticks it will get the number of players on differents servers so i cannot update it whenever a value changes
    So what can i do to make it scrolls?
     
  6. Offline

    567legodude

    @Maxx_Qc You can just call for an update whenever a player joins or disconnects.
    To make it scroll, you have to constantly update the title for the board.
     
  7. Offline

    Zombie_Striker

    Yep, this will now most likely get moved to alternatives.
    And that can't be good.
     
  8. Offline

    Maxx_Qc

  9. Offline

    567legodude

    That is how that API is supposed to work. Giving a value of null means that it will use whatever the current index is whenever it is building the scoreboard.
     
  10. Offline

    Maxx_Qc

    Ok so, I got it to work but now everytime it updates, the scoreboard flashes
     
  11. Offline

    567legodude

    @Maxx_Qc If it's the entire scoreboard that's flashing, it's because you are showing the player a completely new scoreboard, which means it has to remove the old one, and then show them the new one.
    The goal is to find a way to not create a new scoreboard every time you update the values.
     
  12. Offline

    Maxx_Qc

  13. Offline

    567legodude

    @Maxx_Qc I gave you the answer, don't create a new scoreboard on every update.
    That means just have a single board, and update the values for the board.
     
Thread Status:
Not open for further replies.

Share This Page