Solved Hiding players in a BukkitRunnable task doesn't hide them in the player list

Discussion in 'Spigot Plugin Development' started by VapidLinus, Apr 23, 2017.

  1. Hiding players from each other in a BukkitRunnable breaks hiding in the player list (tab list).

    Here's some sample code you can copy-paste to reproduce it:

    Code (Text):
    public class TestPlugin extends JavaPlugin implements Listener {

        @Override
        public void onEnable() {
            // Listen to events
            Bukkit.getPluginManager().registerEvents(this, this);
        }

        @EventHandler
        public void onJoin(final PlayerJoinEvent event) {
            // Hide all players from each other on the next tick
            new BukkitRunnable() {
                public void run() {
                    Player player = event.getPlayer();
               
                    for (Player other : Bukkit.getOnlinePlayers()) {
                        if (other.equals(player)) continue; // Skip self
                   
                        // Hide from each other
                        other.hidePlayer(player);
                        player.hidePlayer(other);
                   
                        // Confirm in console that this code is getting executed
                        getLogger().log(Level.INFO, "Hiding " + other.getName() + " and " + player.getName() + " from each other by task");
                    }
                }
            }.runTaskLater(this, 1);
        }

        @EventHandler
        public void onCommand(PlayerCommandPreprocessEvent event) {
            if (event.getMessage().equalsIgnoreCase("/hideall")) {
                Player player = event.getPlayer();
           
                for (Player other : Bukkit.getOnlinePlayers()) {
                    if (other.equals(player)) continue; // Skip self
               
                    // Hide from each other
                    other.hidePlayer(player);
                    player.hidePlayer(other);
               
                    // Confirm in console that this code is getting executed
                    getLogger().log(Level.INFO, "Hiding " + other.getName() + " and " + player.getName() + " from each other by /hideall");
                }
            }
        }
    }
    1) PlayerA joins the game
    2) PlayerB joins the game
    3.A) The two players cannot see each other in the game, as they are both hidden, but:
    3.B) PlayerA can see PlayerB on the player list, but PlayerB can't see PlayerA on the player list
    4) Running the "/hideall" command doesn't fix it. It seems that if you do it in a runnable task it breaks hiding completely for the involved players

    CraftBukkit version git-Spigot-a3f6ea5-6194f6c (MC: 1.11.2) (Implementing API version 1.11.2-R0.1-SNAPSHOT)
     
    #1 VapidLinus, Apr 23, 2017
    Last edited: Apr 28, 2017
  2. I use this exact api method in version 1.11.2 and it works perfectly fine for me.
     
    #2 SmokingIsBadMkay, Apr 23, 2017
    Last edited: Apr 27, 2017
  3. I got the steps for reproducing the bug wrong.
    I updated the OP with instructions on how to reproduce the bug I'm seeing.
     
  4. Have you tried using a different 1.11.2 release? I'm using CraftBukkit version git-Spigot-d4f98a3-4448a7e (MC: 1.11.2) (Implementing API vesion 1.11.2-R0.1-SNAPSHOT) and I do not have this problem. Also, is the Runnable really needed?
     
  5. Running an older version of Spigot isn't a solution to the bug.
    And of course the Runnable isn't necessary in my sample code, I am showing how to reproduce a bug that exists in Spigot. In my actual code I have a queue system for hide state updates that internally runs in a tickloop powered by Spigot's task system. The issue is that hidePlayer() doesn't seem to work in tasks at the moment, while it worked fine in previous versions.
     
    #5 VapidLinus, Apr 27, 2017
    Last edited: Apr 27, 2017
  6. I believe p.showPlayer() hides them from tab BUT
    p.canSee() hides only the player, and in the parameters is the player they want to not show, naturally.
    (Not sure if It's canSee(), may be something really similar tho.
     
  7. player.showPlayer(Player) is supposed to hide a player from the player list. If you try my sample code but move the code inside the Runnable to just the event, you will see that both players will be hidden from the player list.