Solved Hide player without hiding from Tablist

Discussion in 'Plugin Development' started by DoctorDark, Feb 4, 2014.

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

    DoctorDark

    Hello, I need to hide players, but keep them displayed on the tablist, the hidePlayer() method works fine, however it removes them from the tablist aswell.

    How would I go about doing this?

    Thanks
     
  2. Offline

    Newby

    DoctorDark
    You can give them the invisibility potion effect and maybe there is a way to not show the potion effect particles but I'm not to sure about that
     
  3. Offline

    hurleyboarder

    Code:java
    1. Player player = (Player) sender;
    2. for (Player other : getServer().getOnlinePlayers()) {
    3. other.hidePlayer(player);


    The other makes it so it hides the player from other players. You want be able to tell your vanished but others cant see you.
     
  4. Offline

    DoctorDark

    hurleyboarder
    That would remove the player completely from the tablist aswell.

    Newby
    That could work with packets I believe, however I'd need it to work the same way as the hide and show methods.
     
  5. Offline

    hurleyboarder

    Sorry didnt finish my post
    Code:
    Player player = (Player) sender;
          for (Player other : getServer().getOnlinePlayers()) {
         other.hidePlayer(player);
    player.setPlayerListName(player.getName() + "");
    It shouldnt And it needs to be other.setPlayerListName(player.getName() + "");

    It should And i made a error it needs to be other.setPlayerListName(player.getName() + "");

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 6, 2016
  6. Offline

    DoctorDark

    hurleyboarder
    That won't set the player visible on the tablist, because they are hidden.
     
  7. Offline

    hurleyboarder

    The hiddeplayer just hides the textures of a player not the name on the list.
     
  8. Offline

    DoctorDark

    hurleyboarder
    It hides the player object to the players you define cannot see it, this includes the tablist. If you're unconvinced you should probably try it yourself...
     
  9. Offline

    Desle

    DoctorDark
    Packets is the closest to this request I think.. :(
     
  10. Offline

    Twisted_Panda

    Same thing I was thinking.
     
  11. As far as i know you have to use packet sending to let them reappear on the tab-list. A plugin that had to do this is PlayersInCubes: http://dev.bukkit.org/bukkit-plugins/playersincubes/

    This link shows the package that does the packet sending, that is used by pic: https://github.com/asofold/PlayersInCubes/tree/master/PlayersInCubes/src/me/asofold/bpl/pic/net

    Whenever pic hides a player A from another player B, it also sends a player list update packet to player B to keep player A on the tab-list of player B. Of course you can simplify the implementation, e.g. by coding against only one build of CraftBukkit, resulting in a few lines. Just pic is supposed to work with and without the tab-list "fixing".
     
    DoctorDark likes this.
  12. Offline

    Comphenix

    An alternative to @asofold's approach - especially if you want to support multiple versions without the pain of using tens of Maven modules - is to use ProtocolLib.

    I've just updated my HidePlayerList example for ProtocolLib 3.2.0. It supports every version of Minecraft since 1.4.2, though it could be extended further if necessary. It's trivial in use:
    Code:java
    1. private HidePlayerList playerList;
    2.  
    3. @Override
    4. public void onEnable() {
    5. playerList = new HidePlayerList(this);
    6. }
    7.  
    8. @Override
    9. public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    10. if (sender instanceof Player) {
    11. Player player = (Player) sender;
    12.  
    13. if (playerList.isVisible(player)) {
    14. playerList.hidePlayer(player);
    15. } else {
    16. playerList.showPlayer(player);
    17. }
    18. }
    19. return true;
    20. }

    By intercepting tab list packets, it can always tell if a given player is actually present in the tab list. It will transmit the necessary packets when a player is hidden or forcefully shown.
     
    DoctorDark likes this.
  13. Offline

    DoctorDark

    Comphenix

    I still find this to remove the player from the tablist for some reason;
    Using version 3.2.0 (dependency and plugin wise);

    It still seems to remove the player from the tablist when they are hidden;
    Code:
        @EventHandler
        public void onTeleport(PlayerTeleportEvent e) {
            final Player p = e.getPlayer();
           
            if (!VanishCommand.vanished.contains(p.getName())) {
               
                Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
                    public void run() {
                        for (Player players : Bukkit.getOnlinePlayers()) {
                            players.hidePlayer(p);
                            playerList.showPlayer(p);
                        }
                    }
                }, 20L);
               
                Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
                    public void run() {
                        for (Player players : Bukkit.getOnlinePlayers()) {
                            players.showPlayer(p);
                            playerList.showPlayer(p);
                        }
                    }
                }, 40L);
               
            }
        }
     
  14. Offline

    xTrollxDudex

    DoctorDark
    PHP:
    ((CraftPlayerplayer).getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(hidden.getName(), true10));
     
  15. Offline

    DoctorDark

    xTrollxDudex

    Thanks

    This appears to work, would there be any way to prevent it swapping positions in the tab menu however?
     
  16. Offline

    xTrollxDudex

    DoctorDark
    It depends on the order you show the packet to the player. In essense, it fills the next availible slot in the player list.
     
  17. Offline

    DoctorDark

    xTrollxDudex
    So I'm assuming a workaround for this could be showing the packet on join and setting their playerListName to null?
     
  18. Offline

    xTrollxDudex

    DoctorDark
    That could work, but it may check for a null parameter there. Let me check the source

    Edit: Setting to null won't work, it just sets it to the current player name
     
  19. Offline

    Comphenix

    Try instead to intercept the PacketPlayOutPlayerInfo packet sent in hidePlayer() and showPlayer(), and prevent it from ever being sent. Then you won't have this problem (download):
    Code:java
    1. public class ExampleMod extends JavaPlugin {
    2. private Set<String> ignoreTabList = Sets.newHashSet();
    3.  
    4. @Override
    5. public void onEnable() {
    6. ProtocolLibrary.getProtocolManager().addPacketListener(
    7. new PacketAdapter(this, PacketType.Play.Server.PLAYER_INFO) {
    8. @Override
    9. public void onPacketSending(PacketEvent event) {
    10. String name = event.getPacket().getStrings().read(0);
    11.  
    12. if (ignoreTabList.contains(name)) {
    13. event.setCancelled(true);
    14. }
    15. }
    16. });
    17. }
    18.  
    19. private void ignore(Player player) {
    20. ignoreTabList.add(player.getPlayerListName());
    21. }
    22.  
    23. public void unignore(Player player) {
    24. ignoreTabList.remove(player.getPlayerListName());
    25. }
    26.  
    27. @Override
    28. public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    29. if (args.length != 1) {
    30. sender.sendMessage(ChatColor.RED + "Must have one argument.");
    31. } else if (sender instanceof Player) {
    32. Player observer = (Player) sender;
    33. Player player = getServer().getPlayer(args[0]);
    34.  
    35. // Stop sending tab list packets about this player
    36. ignore(player);
    37.  
    38. if (observer.canSee(player)) {
    39. observer.hidePlayer(player);
    40. } else {
    41. observer.showPlayer(player);
    42. }
    43.  
    44. // Enable it again
    45. unignore(player);
    46. }
    47. return true;
    48. }
    49. }

    You could also cancel every PLAYER_INFO packet for a set period, if you don't want to manually add every player whose tab list name should stay intact.
     
    asofold and DoctorDark like this.
  20. Offline

    DoctorDark

    Comphenix

    That method seemed to do the trick, thanks.
     
    Comphenix likes this.
  21. Offline

    DoctorDark

    Comphenix

    Sorry for the necro/double post but would it be possible to only cancel for the event for a specific player?

    Thanks`
     
  22. Offline

    Comphenix

    Sure, you can use event.getPlayer() to get the player that is receiving the tab list update.
     
Thread Status:
Not open for further replies.

Share This Page