Solved NMS Enable EntityPlayer Overlays

Discussion in 'Plugin Development' started by Excel8392, Apr 5, 2020.

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

    Excel8392

    I am trying to create a plugin similar to citizens, but much more lightweight and with far less features.
    Currently I am working on creating "fake" players that will act as NPCs, and am having trouble enabling the skin overlays for them.
    According to this page, enabling all the overlays should be done with byte 127. I am using this code:
    Code (open)
    Code:
    public class Npc {
    
        public EntityPlayer entityPlayer;
        private GameProfile gameProfile;
        private Location location;
        private int entityId;
        private DataWatcher watcher;
    
        public Npc(Location location, String skinUuid) {
            gameProfile = new GameProfile(UUID.fromString(skinUuid), "npc");
            this.location = location;
            MinecraftServer minecraftServer = ((CraftServer) Bukkit.getServer()).getServer();
            WorldServer worldServer = ((CraftWorld) this.location.getWorld()).getHandle();
            this.entityPlayer = new EntityPlayer(minecraftServer, worldServer, this.gameProfile, new PlayerInteractManager(worldServer));
            this.entityPlayer.playerConnection = new PlayerConnection(minecraftServer, new NetworkManager(EnumProtocolDirection.CLIENTBOUND), this.entityPlayer);
            this.entityPlayer.setHealth(1f);
            this.entityPlayer.setCustomNameVisible(false);
            this.entityPlayer.setLocation(this.location.getX(), this.location.getY(), this.location.getZ(), this.location.getYaw(), this.location.getPitch());
            this.entityId = this.entityPlayer.getId();
            this.watcher = this.entityPlayer.getDataWatcher();
            this.watcher.set(new DataWatcherObject<Byte>(13, DataWatcherRegistry.a), new Byte((byte) 127));
            worldServer.addEntity(this.entityPlayer);
        }
    
        public Integer getEntityId() {
            return this.entityId;
        }
    
        public void spawnForPlayer(Player player) {
            ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, this.entityPlayer));
            ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutNamedEntitySpawn(entityPlayer));
            ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityMetadata(entityPlayer.getId(), watcher, true));
        }
    
    }
    

    However, on server startup, I get an exception ticking world, but the main line is this:
    Caused by: java.lang.ClassCastException: java.lang.Byte cannot be cast to java.util.Optional
    Somehow, the server doesn't like this line:
    this.watcher.set(new DataWatcherObject<Byte>(13, DataWatcherRegistry.a), new Byte((byte) 127));
    But I'm not sure what is wrong with it - I'm using the non-primitive byte object, so there shouldn't be a problem...?

    Side note: If I remove this line:
    worldServer.addEntity(this.entityPlayer);
    then I will only get that exception when executing the spawnForPlayer method, and it points to this line:
    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityMetadata(entityPlayer.getId(), watcher, true));
    Meaning that the issue is indeed with the DataWatcher.


    I am using minecraft version 1.15.

    Also bonus question if you can answer it: is it possible to spawn an EntityPlayer with a player skin without setting the GameProfile UUID to use that player's UUID?

    Any help is appreciated! Thanks.

    I am an idiot, I put 13 as the index for the overlays, when it should be 16 with newer versions of minecraft. However if anyone is able to answer the bonus question at the bottom that would be great.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Apr 5, 2020
  2. Offline

    KarimAKL

    I can't answer this question but, i can link you a thread that might help you answer it.
    Link: https://www.spigotmc.org/threads/assign-skin-to-an-npc.169558/
    There's also a useful tool linked in the thread for getting signed skins from images.
    The tool still works, although it changed from https://skulls.inventivetalent.org to https://mineskin.org
     
  3. Offline

    Excel8392

    KarimAKL likes this.
Thread Status:
Not open for further replies.

Share This Page