Removing A scoreboard from a player when they leave?

Discussion in 'Plugin Development' started by blok601, Dec 25, 2015.

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

    blok601

    I have a plugin that is causing a massive error when a player leaves. This plugin uses a scoreboard. Of course my error is that the server is trying to add a scoreboard to offline player. How would I remove it?

    Here is my code right now:

    Code:
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent e){
           
              final Player p = e.getPlayer();
                 
    
           
            Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable(){
                public void run(){
                      int tKills = getConfig().getInt(p.getUniqueId() + ".kills");
                      int tDeaths = getConfig().getInt(p.getUniqueId() + ".deaths");
    
                     
    
                        DecimalFormat df2 = new DecimalFormat("0.00");
                          double kd = tKills/ (double) tDeaths;
                          String kills = df2.format(kd);
                         
    
                    ScoreboardManager manager = Bukkit.getScoreboardManager();
                    String  sname = getConfig().getString("Server");
                    final Scoreboard board = manager.getNewScoreboard();
                    Objective objective = board.registerNewObjective("test", "dummmy");
                    objective.setDisplaySlot(DisplaySlot.SIDEBAR);
                    objective.setDisplayName(ChatColor.RED + "" + sname);
                   
                    Score score  = objective.getScore(ChatColor.AQUA + "Player name: " + ChatColor.GRAY + "" + p.getName());
                    score.setScore(10);
                   
                    Score score1 = objective.getScore(ChatColor.AQUA + "Kills: " +  ChatColor.GRAY + "" +  tKills);
                    score1.setScore(9);
                   
                   
                    Score score2 = objective.getScore(ChatColor.AQUA + "Deaths: " + ChatColor.GRAY + "" + tDeaths);
                    score2.setScore(8);
                   
                    if(!(tDeaths == 0)){
                        Score score3 = objective.getScore(ChatColor.AQUA + "K/D: " +   ChatColor.GRAY + "" + kills);
                        score3.setScore(7);
                    }else{
                        Score score3 = objective.getScore(ChatColor.AQUA + "K/D: " +   ChatColor.GRAY + "No Deaths!");
                        score3.setScore(7);
                    }
                   
                    if(p.isOnline()){
                        p.setScoreboard(board);
                    }else{
                        p.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard());
                    }
                }
            }, 0, 5);
        }
     
  2. Offline

    Xerox262

    Shouldn't this be the other way around? 5 then 0. I could've swore the first number was the wait before it ran it, then the second number is the delay between each one.

    P.S. Don't send an empty scoreboard.

    And why not check if they're online BEFORE you create everything?
     
    blok601 likes this.
  3. Offline

    Zombie_Striker

    @Xerox262
    Nope. The first value is the initial delay. The second is the delay between tasks.


    The only problem I have with your code is:
    So you have to make sure the player is online? If the plyaer is offline, then it should through an NPE shouldn't it?
    AND THIS! If the player is no longer online, you will STILL set his scoreboard to something.
     
    mine-care likes this.
  4. Offline

    Xerox262

    That's what I said...
     
  5. Offline

    Mrs. bwfctower

    You did say that, but your numbers seem to be switched around. Why would you want to have an initial delay of 5, and then repeat every... 0 ticks?

    If you set the first number to 0, the repeating tasks will start instantly.
     
  6. Offline

    blok601

    Fixed, but my only problem is, how would I remove it when they leave?
     
  7. Offline

    Mrs. bwfctower

    @blok601 You can use a PlayerQuitEvent, and from there get the Player, and remove them.
     
  8. Offline

    blok601

    I have a player quit event doing that already. I have something like:
    Code:
    @EventHandler
    public void onPlayerLeave(PlayerQuitEvent e){
    Player p = e.getPlayer();
    p.setScoreBoard(Bukkit.getScoreboardManager().getNewScoreboard();
    Although, this seems to be occurring when a player is banned. Is there a player ban event?
     
  9. Offline

    Mrs. bwfctower

    @blok601 Why would you need to differentiate? When a Player is no longer on the server (doesn't matter how they left, as long as they aren't on the server), the PlayerQuitEvent will be called. When a Player is banned, they are kicked from the server, and the PlayerQuitEvent is called.

    Just remove them from the scoreboard.
     
  10. Offline

    blok601

    How would I do that? I am trying to remove the scoreboard from them..
     
  11. Offline

    Mrs. bwfctower

  12. Offline

    blok601

    Okay, so then how would I remove it. I can't set it to null, i can't send then an empty scoreboard either. It throws an error when I send any scoreboard to an offline player (of course it would, not contradicting that).
     
  13. Offline

    Mrs. bwfctower

    @blok601 They aren't offline yet. They are removed from the server after the event is finished being called.

    Just set their scoreboard to an empty one.
     
    blok601 likes this.
  14. Offline

    blok601

    I believe I already did that. I will check the logs and post the error when it happens again. But its pretty much:

    "Can't pass a scoreboard to an invalid CraftPlayer"
     
  15. Offline

    Mrs. bwfctower

    Can you post the error?

    EDIT: Oh, you will when it happens again. Nevermind. But yeah, just let me know when it happens.
     
  16. Offline

    blok601

    Error (open)
    28.12 18:44:25 [Server] INFO at java.lang.Thread.run(Unknown Source) [?:1.8.0_45]28.12 18:44:25 [Server] INFO at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:536) [craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]28.12 18:44:25 [Server] INFO at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:628) [craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]28.12 18:44:25 [Server] INFO at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:335) [craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]28.12 18:44:25 [Server] INFO at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:679) [craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]28.12 18:44:25 [Server] INFO at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:349) [craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]28.12 18:44:25 [Server] INFO at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java:53) ~[craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]28.12 18:44:25 [Server] INFO at me.blok601.kc.Main$1.run(Main.java:318) ~[?:?]28.12 18:44:25 [Server] INFO at org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer.setScoreboard(CraftPlayer.java:1241) ~[craftbukkit-1.8.8.jar:git-Bukkit-9a17f01]


    Its not allowing me to copy the Illegal State Exception Part for some reason but it is basically: Cannot set scoreboard for invalid CraftPlayer

    @Mrs. bwfctower
     
    Last edited: Dec 28, 2015
  17. Offline

    Zombie_Striker

  18. Offline

    blok601

    Sorry, I am on a different computer that doesn't have access to my ftp client and such. My console isn't allowing me to copy straight from there. I will post my full error asap. Also, I have a decent knowledge of how to read stack traces.
     
  19. Offline

    Zombie_Striker

    Cool. if you do, then you should be able to pinpoint the exact line that is causing the problem. (I normally assume people don't know basic things, because most likely they don't.)
     
    blok601 likes this.
  20. Offline

    blok601

    Alright I have the full error here @Zombie_Striker:
     

    Attached Files:

  21. Offline

    Evonoucono

    Try this code in a PlayerQuitEvent it should remove a players scoreboard:
    Code:
    ScoreboardManager manager = Bukkit.getScoreboardManager();
    player.setScoreboard(manager.getNewScoreboard());
     
  22. Offline

    blok601

    @Evonoucono

    Already did that.
     
  23. Offline

    Zombie_Striker

    @blok601
    Looked at the error. What is at line 318?
     
  24. Offline

    Maxx_Qc

    You could make a class for the runnable and cancel it when the player leave.
     
  25. Offline

    m.d.simmo

    There's no need to create another class (although that might be the neater option). You can simply pass the task id into the runnable and then cancel the task in the runnable if the player is offline:

    Code:
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent e){
        final Player p = e.getPlayer();
    
        // need to pass the taskId through an array because we cannot use an
        // unassigned final field in the runnable
        final int[] taskId = new int[1];
         taskId[0] = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
             public void run() {
                 if ( !p.isOnline() ) {
                     Bukkit.getScheduler().cancelTask( taskId[0] );
                     return;
                 }
                // the rest of your code
                ...
            }
        }, 0, 5 );
    }
    
     
    Last edited: Dec 29, 2015
Thread Status:
Not open for further replies.

Share This Page