1.16.5 Removing Players from Tablist

Discussion in 'Spigot Plugin Development' started by FCKJohni, Jun 24, 2021.

  1. Hello,

    For our Roleplay Server I am trying to remove all Players from the Tablist, which means remove their name AND Head.


    I want to use ProtocolLib for that, and it should always work

    My Current Solution is this:
    Code (Java):

    package de.jaholl.essentials.listeners;

    import com.comphenix.protocol.PacketType;
    import com.comphenix.protocol.events.ListenerPriority;
    import com.comphenix.protocol.events.PacketAdapter;
    import com.comphenix.protocol.events.PacketEvent;
    import com.comphenix.protocol.wrappers.EnumWrappers;
    import com.comphenix.protocol.wrappers.PlayerInfoData;
    import com.comphenix.protocol.wrappers.WrappedChatComponent;
    import com.comphenix.protocol.wrappers.WrappedGameProfile;
    import de.jaholl.essentials.EssentialsPlugin;
    import de.jaholl.essentials.packets.WrapperPlayServerPlayerInfo;
    import org.bukkit.Bukkit;
    import org.bukkit.scheduler.BukkitRunnable;

    import java.util.Collections;

    public class PacketHandler extends PacketAdapter {

        private final EssentialsPlugin essentialsPlugin;

        public PacketHandler(EssentialsPlugin essentialsPlugin) {
            super(essentialsPlugin, ListenerPriority.HIGHEST, PacketType.Play.Server.NAMED_ENTITY_SPAWN);
            this.essentialsPlugin = essentialsPlugin;
        }

        @Override
        public void onPacketSending(PacketEvent event) {
            WrapperPlayServerPlayerInfo wrapperPlayServerPlayerInfo = new WrapperPlayServerPlayerInfo();
            wrapperPlayServerPlayerInfo.setAction(EnumWrappers.PlayerInfoAction.ADD_PLAYER);
            if (event.getPacket().getUUIDs().read(0) == null || Bukkit.getPlayer(event.getPacket().getUUIDs().read(0)) == null)
                return;
            var player = Bukkit.getPlayer(event.getPacket().getUUIDs().read(0));
            var playerInfoData = new PlayerInfoData(WrappedGameProfile.fromPlayer(player), 20, EnumWrappers.NativeGameMode.NOT_SET, WrappedChatComponent.fromText(""));
            wrapperPlayServerPlayerInfo.setData(Collections.singletonList(playerInfoData));
            wrapperPlayServerPlayerInfo.sendPacket(event.getPlayer());

            new BukkitRunnable() {
                @Override
                public void run() {
                    WrapperPlayServerPlayerInfo remove = new WrapperPlayServerPlayerInfo();
                    remove.setAction(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER);
                    var data = new PlayerInfoData(WrappedGameProfile.fromPlayer(player), 20, EnumWrappers.NativeGameMode.NOT_SET, WrappedChatComponent.fromText(""));
                    remove.setData(Collections.singletonList(data));
                    remove.sendPacket(event.getPlayer());
                }
            }.runTaskLater(essentialsPlugin, 100);

        }
    }

    The Problem with that Code is that sometimes instead of the Players having their normal Skin, they have a Steve or Alex Skin.

    Can anybody help me fix that please?
     
    #1 FCKJohni, Jun 24, 2021
    Last edited: Jun 25, 2021
  2. This is a common problem with npc skins. As you'll notice when on servers that have such plugins - the npc is added to the tab list for a split second then removed. This is done because that is how the client assigns skins to players. So, in order to fix your problem, your players will have to receive that tab list at least once in order for them to assign skins, then you can send a remove packet.
     
  3. well Thats what I tried todo, once the Named Entity Spawn packet is sent I add them to the tablist and remove them 10 sec later. like I said most of the time it works

    EDIT:
    Could I listen for the packet, cancel the sending and then send it manually? eg once the packet is being sent, cancel it pass the packet to a method that first adds the player to the tablist, then sends the spawn packet and after that sends the remove packet? should that get the packets in order
     
  4. The player has to be visible (on the client screen) at the time the tab list packet is added, so yes you can cancel the first packet by the server and then send your own later.
     
  5. I couldn't get that to work, I get a Stackoverflow because the Packet gets send in a loop so that won't work.
    Do you have an Idea how to fix it? or maybe an example code?
     
  6. Try use method
    Code (Text):
    PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, craftPlayers));
     
  7. Please look at the provided code first before saying anything like that. I already have code to remove players from the tablist
     
  8. bro stop posting random answers like that, it won't be helpful if you just post some randomness while you don't know anything about coding, i bet you copied this code somewhere... don't do that so that you get some attention/required amount of posts or something. dude it's annoying af.
     
  9. #BUMP#

    I still need a solution for this, and I haven't found one yet
     
  10. In the past to remove players from tab I just always used teams to hide other players in tab. Just have to make a team for each player and add everyone else into it and set it to hide them from tab in the team options. Does the trick for me and also means you can pre-add npc's so they never appear for a split second.
     
  11. well we looked at that, but on multiple Discord we were told to not do it that way idk why. also when we used a Plugin that does that we had the issue that some players could see Spectators in the Tablist. Thats why we want to use Packets.