1.16.5 Protocollib HidePlayers

Discussion in 'Spigot Plugin Development' started by xXPlayer2000, Dec 12, 2020.

  1. Hey Guys,
    so i want to remove players from the tablist, but if i just use Remove_Player the players are not loading anymore (visible) so i googled and found https://gist.github.com/aadnk/3928137
    But the line "manager.createPacketConstructor(PacketType.Play.Server.PLAYER_INFO, "", false, (int) 0);"
    is not working anymore (No suitable constructor found) and i really dont know how to change that.
    And if i just use a new PacketContainer its like a normal remove_player packet.
    Does anyone know how to use the createPacketConstructor or hidePlayers just in the tablist?
     
  2. I also had difficulties to do it. I described how I finally did it in my last post if this thread :
    https://www.spigotmc.org/threads/issue-hide-player-in-playerlist-only.452865/

    I didn't use ProtocolLib to hide the player in the tab, but only to set him visible again (by listening NAMED_ENTITY_SPAWN packet). To hide the player, I used NMS packets but as long as protocolLib works with vanilla packets, there is certainly a way to do it with ProtocolLib.
     
  3. SteelPhoenix

    Moderator

    Try https://github.com/dmulloy2/PacketWrapper
    It has wrapper classes for most packet types with easy to use accessors so it is really easy to create and send your own packets.

    As for your issue, all player spawn packets are ignored by the client if said player is not on the client's tablist. You have to add the player back to the player list before sending spawn packets, then you can remove the player from the list again.
     
  4. little spoonfeeding here but it seems this is hard to come by ! no libraries required! just NMS!


    Code (Text):
    private void removePlayerTabInfo(boolean boo)
    {
            PacketPlayOutPlayerInfo.EnumPlayerInfoAction info;
            if (!boo) { info = PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER; }
            else { info = PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER; }
            Player bukkitPlayer = Bukkit.getPlayer(player.getUUID());
            EntityPlayer[] playerNMS = new EntityPlayer[1];
            playerNMS[0] = ((CraftPlayer) bukkitPlayer).getHandle();
            PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(info, playerNMS);
            ((CraftPlayer) player.getPlayer()).getHandle().playerConnection.sendPacket(packet);
    }
    EDIT: they way its setup one can also easily convert it to handle multiple players at a time...or even all players could be hidden from all players. Though the only case for this is really minigames. Also this ONLY handles TABLIST not the actually hiding of the player...universal snippet I use.
     
  5. The problem is that if the player is not in the tab minecraft is not loading the players. So if you leave the view of the player u wont see him again
     
  6. What exactly are u doing with the named_entity_spawn packet i looked at your thread but still dont understand what u doing there
     
  7. Trying to do this but if i wanna add him back i get kicked out because of nullpointer

    Code (Text):
    @Override
        public void onPacketSending(PacketEvent event) {
            Player player = event.getPlayer();

            new BukkitRunnable() {

                @Override
                public void run() {


                    {
                        PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, (((CraftPlayer)player).getHandle()));
                        MinecraftServer.getServer().getPlayerList().sendAll(info);
                    }
                }
            }.runTaskLater(AmongUs.getInstance(), 10);
        }
     
  8. SteelPhoenix said everything :
    As for your issue, all player spawn packets are ignored by the client if said player is not on the client's tablist. You have to add the player back to the player list before sending spawn packets, then you can remove the player from the list again.


    Let imagine p1 is hidden from the tab list of p2.

    • The problem is : When the server has to send a packet about p1 to p2, p2 ignores it because p2 (his client side) does not see that p1 is online from the tab list. It happens here when the server send the NMS packet PacketPlayOutNamedEntitySpawn (named in ProtocolLib : PacketType.Play.Server.NAMED_ENTITY_SPAWN). In other words, this information from the server side is "Hey p2, you have to see p1 because he is close yo you !" and p2 thinks "Wait, p1 is offline because I don't see him in the playerList... Let's ignore this information, I woundn't have seen him anyway !"
    -> So when p1 "spawns" (leaves gamemode spectator near p2, or approaching p2, or respawn after death, and so on...), p1 will be invisible to p2.

    • The solution is : With ProtocolLib, listen when a packet NamedEntitySpawn is sent. If it happens, check if p2 (who receives this packet) can see p1 (whi is in the EntityModifier of the packet). If not, add p1 to the tablist of p2. Then after a short delay, remove p1 again.
    So what will happen when p1 will spawn :
    1. The listener is fired and everything is check.
    2. p2 can now see p1 in his tablist before the packet is sent (thanks to the protocollib listener)
    3. p1 spawns and p2 can see him (the packet is sent, everything is fine, nobody ignores it)
    4. After the delay, p1 is hidden from the player list again.

    It generalizes very well for all players, or some type of players.


    The only problem of this it that p1 twinkles once on the tabList of p2 when this happens. I've never found any solutions. In my case it was enough to do that.

    Hope it helps you !
     
    • Like Like x 1
  9. I use this along p.hidePlayer/p.showPlayer and I allow the admins to still interact with each other, ie you are not hidden from them with p.hidePlayer. I have no such issues of players not being able to see each other, just last night I teleported to another admin and he could see me just fine...I can only teleport when in admin mode! vanished from non-admin players and hidden from all players tab lists. Here is how I run it within the plugin.

    Code (Java):
    //CHECK IF PLAYER IS VANISHED
            if (!AdminConfig.vanishedAdmins.contains(player.getName()))
            {
                //ITERATE AND HIDE ADMIN FROM PLAYERS
                for (Player p : player.getMain().getServer().getOnlinePlayers())
                {
                    //CHECK IF PLAYER IS AN ADMIN
                    if (!AdminConfig.adminList.contains(player.getName()))
                    {
                        p.hidePlayer(player.getMain(), player.getPlayer());
                    }
                }
                AdminConfig.vanishedAdmins.add(player.getName());
                new BukkitRunnable() {
                    @Override
                    public void run() {
                        removePlayerTabInfo(false);
                    }
                }.runTaskLater(player.getMain(), 1L);
                if (config.getState(States.Vanish)) { player.getPlayer().sendMessage(Chat._vanishOn.txt); return; }
                config.setState(true, States.Vanish);
                player.getMain().getServer().broadcastMessage(ChatColor.YELLOW + player.getName() + Chat._fakeLogOut.txt);
            } else
            {
                //ITERATE AND UN-HIDE ADMIN FROM PLAYERS
                for (Player p : player.getMain().getServer().getOnlinePlayers())
                {
                    p.showPlayer(player.getMain(), player.getPlayer());
                }
                AdminConfig.vanishedAdmins.remove(player.getName());
                config.setState(false, States.Vanish);
                removePlayerTabInfo(true);
                player.getMain().getServer().broadcastMessage(ChatColor.YELLOW + player.getName() + Chat._fakeLogIn.txt);
            }
            player.save();
    }
    As You Can See I still remove the player from the other admins tablist