ProtocolLib

3M Downloads

Use of ADD_PLAYER

ryanalexander opened this issue ยท 5 comments

commented

Make sure you're doing the following

  • You're using the latest build for your server version
  • This isn't an issue caused by another plugin
  • You've checked for duplicate issues
  • You didn't use /reload

Describe the question
Attempting to create a non-player character in tab

API method(s) used
PacketContainer(PacketType.Play.Server.PLAYER_INFO)
playerData.getPlayerInfoActions()
playerData.getPlayerInfoDataLists()

Expected behavior
A player "DummyPlayer" is added to the tab list for all players

Code
`
package net.stelch.minegames.MineClient.utils;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.EntityPlayer;
import net.minecraft.server.level.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import redis.clients.jedis.Jedis;

import java.util.*;

public class TabManager {
Jedis jedis;
List dummyPlayers = new ArrayList<>();

public TabManager(JavaPlugin plugin, ConfigurationSection config) {
    jedis = new Jedis(config.getString("host"), config.getInt("port"));
    jedis.select(config.getInt("database"));

    ProtocolManager packetManager = ProtocolLibrary.getProtocolManager();

    // Adding dummy players
    DummyPlayer dummyPlayer = new DummyPlayer();
    dummyPlayer.uuid = UUID.randomUUID();
    dummyPlayer.name = "Dummy";
    dummyPlayer.gameMode = GameMode.SURVIVAL;
    dummyPlayer.latency = 0;
    dummyPlayers.add(dummyPlayer);

    new BukkitRunnable(){
        @Override
        public void run() {
            reloadDummyPlayers();
        }
    }.runTaskTimer(plugin, 0, 20);
}

class InferredPlayer implements HumanEntity {
}

public void reloadDummyPlayers() {
    ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
    List<PlayerInfoData> playerInfoDataList = new ArrayList<>();

    dummyPlayers.forEach(dummyPlayer -> {
        WrappedGameProfile gameProfile = new WrappedGameProfile(dummyPlayer.uuid, dummyPlayer.name);
        PlayerInfoData playerInfoData = new PlayerInfoData(
                gameProfile,
                dummyPlayer.latency,
                EnumWrappers.NativeGameMode.fromBukkit(dummyPlayer.gameMode),
                WrappedChatComponent.fromText(dummyPlayer.name)
        );
        playerInfoDataList.add(playerInfoData);
    });

    if (!playerInfoDataList.isEmpty()) {
        PacketContainer playerData = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
        playerData.getPlayerInfoActions().write(0, Collections.singleton(EnumWrappers.PlayerInfoAction.ADD_PLAYER));
        playerData.getPlayerInfoDataLists().write(1, playerInfoDataList);

        Bukkit.getOnlinePlayers().forEach(player -> {
            protocolManager.sendServerPacket(player, playerData);
        });
    } else {
        Bukkit.getLogger().warning("No player info data to send.");
    }
}

public class DummyPlayer {
    UUID uuid;
    String name;
    GameMode gameMode;
    int latency;
}

}

`

Additional context
NA

commented

Context: I am unsure if this is just me approaching this wrong, but there are no errors reported and the expected result is not occuring

commented

Same for me, trying to re-create a player in the tablist for updating the skin.
Did you have any success with this yet?

For me, this doesnt work in 1.21.1.

commented

@Gandalf1783 I found out that I was using the wrong data in the container.
I also found out that https://github.com/dmulloy2/ProtocolLib/blob/master/src/main/java/com/comphenix/protocol/wrappers/WrappedGameProfile.java and https://github.com/dmulloy2/PacketWrapper/blob/master/PacketWrapper/src/main/java/com/comphenix/packetwrapper/WrapperPlayServerPlayerInfo.java exist which make it a bit easier.

May be good if there were errors to point in the right direction, but at least it works if done properly.

commented

Sorry, but can you elaborate on "using the wrong data in the container"?
You mean the "playerInfoDataList" that you are passing into the container?
What are you using instead?

I havent used the PacketWrapper yet, I will try and use that one now...

commented

Sorry, but can you elaborate on "using the wrong data in the container"? You mean the "playerInfoDataList" that you are passing into the container? What are you using instead?

I havent used the PacketWrapper yet, I will try and use that one now...

The correct data to use is shown in the PacketWrapper. As this was user error on my end, I've closed this issue.