public class NPCUtils { public EntityPlayer createNPC(Location location, String npcName, String texture, String signature) { MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer(); WorldServer nmsWorld = ((CraftWorld) location.getWorld()).getHandle(); GameProfile gameProfile = new GameProfile(UUID.randomUUID(), npcName); Property property = new Property("textures", texture, signature); gameProfile.getProperties().put("textures", property); EntityPlayer npc = new EntityPlayer(nmsServer, nmsWorld, gameProfile); npc.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); npc.displayName = npcName; return npc; } private PlayerConnection getPlayerConnection(Player player) { return ((CraftPlayer) player).getHandle().b; } private void fixSkinHelmetLayer(EntityPlayer npc, Player player) { DataWatcher dataWatcher = npc.getDataWatcher(); dataWatcher.set(new DataWatcherObject<>(17, DataWatcherRegistry.a), (byte) 127); getPlayerConnection(player).sendPacket(new PacketPlayOutEntityMetadata(npc.getId(), dataWatcher, true)); } public void showNPCAsClientSide(EntityPlayer npc, Player player) { PlayerConnection playerConnection = getPlayerConnection(player); PacketPlayOutPlayerInfo packetPlayOutPlayerInfo = new PacketPlayOutPlayerInfo( PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a, npc ); PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawn( npc ); playerConnection.sendPacket(packetPlayOutPlayerInfo); playerConnection.sendPacket(packetPlayOutNamedEntitySpawn); CraftScoreboardManager scoreboardManager = ((CraftServer) Bukkit.getServer()).getScoreboardManager(); CraftScoreboard mainScoreboard = scoreboardManager.getNewScoreboard(); Scoreboard scoreboard = mainScoreboard.getHandle(); ScoreboardTeam scoreboardTeam = scoreboard.getPlayerTeam(npc.getName()); if(scoreboardTeam == null) { scoreboardTeam = scoreboard.createTeam("NPC"); scoreboard.addPlayerToTeam(npc.getName(), scoreboardTeam); } else { scoreboard.addPlayerToTeam(npc.getName(), scoreboardTeam); } Bukkit.getServer().getScheduler().runTaskLater(Main.getPlugin(Main.class), () -> { PacketPlayOutPlayerInfo removeFromTabPacket = new PacketPlayOutPlayerInfo( PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, npc ); playerConnection.sendPacket(removeFromTabPacket); fixSkinHelmetLayer(npc, player); }, 1); } }