package net.jitse.npclib.nms.v1_16_R1; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.datafixers.util.Pair; import net.jitse.npclib.NPCLib; import net.jitse.npclib.api.skin.Skin; import net.jitse.npclib.api.state.NPCSlot; import net.jitse.npclib.hologram.Hologram; import net.jitse.npclib.internal.MinecraftVersion; import net.jitse.npclib.internal.NPCBase; import net.jitse.npclib.nms.v1_16_R1.packets.*; import net.minecraft.server.v1_16_R1.*; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import java.util.Collections; import java.util.List; /** * @author Jitse Boonstra */ public class NPC_v1_16_R1 extends NPCBase { private PacketPlayOutNamedEntitySpawn packetPlayOutNamedEntitySpawn; private PacketPlayOutScoreboardTeam packetPlayOutScoreboardTeamRegister; private PacketPlayOutPlayerInfo packetPlayOutPlayerInfoAdd, packetPlayOutPlayerInfoRemove; private PacketPlayOutEntityHeadRotation packetPlayOutEntityHeadRotation; private PacketPlayOutEntityDestroy packetPlayOutEntityDestroy; public NPC_v1_16_R1(NPCLib instance, List lines) { super(instance, lines); } @Override public void createPackets() { this.hologram = new Hologram(MinecraftVersion.V1_15_R1, location.clone().add(0, 0.5, 0), text); PacketPlayOutPlayerInfoWrapper packetPlayOutPlayerInfoWrapper = new PacketPlayOutPlayerInfoWrapper(); // Packets for spawning the NPC: this.packetPlayOutScoreboardTeamRegister = new PacketPlayOutScoreboardTeamWrapper() .createRegisterTeam(name); // First packet to send. this.packetPlayOutPlayerInfoAdd = packetPlayOutPlayerInfoWrapper .create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, gameProfile, name); // Second packet to send. this.packetPlayOutNamedEntitySpawn = new PacketPlayOutNamedEntitySpawnWrapper() .create(uuid, location, entityId); // Third packet to send. this.packetPlayOutEntityHeadRotation = new PacketPlayOutEntityHeadRotationWrapper() .create(location, entityId); // Fourth packet to send. this.packetPlayOutPlayerInfoRemove = packetPlayOutPlayerInfoWrapper .create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, gameProfile, name); // Fifth packet to send (delayed). // Packet for destroying the NPC: this.packetPlayOutEntityDestroy = new PacketPlayOutEntityDestroy(entityId); // First packet to send. } @Override public void sendShowPackets(Player player) { PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; if (hasTeamRegistered.add(player.getUniqueId())) playerConnection.sendPacket(packetPlayOutScoreboardTeamRegister); playerConnection.sendPacket(packetPlayOutPlayerInfoAdd); playerConnection.sendPacket(packetPlayOutNamedEntitySpawn); playerConnection.sendPacket(packetPlayOutEntityHeadRotation); sendMetadataPacket(player); hologram.show(player); // Removing the player info after 10 seconds. Bukkit.getScheduler().runTaskLater(instance.getPlugin(), () -> playerConnection.sendPacket(packetPlayOutPlayerInfoRemove), 200); } @Override public void sendHidePackets(Player player) { PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; playerConnection.sendPacket(packetPlayOutEntityDestroy); playerConnection.sendPacket(packetPlayOutPlayerInfoRemove); hologram.hide(player); } @Override public void sendMetadataPacket(Player player) { PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadataWrapper().create(activeStates, entityId); playerConnection.sendPacket(packet); } @Override public void sendEquipmentPacket(Player player, NPCSlot slot, boolean auto) { PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; EnumItemSlot nmsSlot = slot.getNmsEnum(EnumItemSlot.class); ItemStack item = getItem(slot); Pair pair = new Pair<>(nmsSlot, CraftItemStack.asNMSCopy(item)); PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment(entityId, Collections.singletonList(pair)); playerConnection.sendPacket(packet); } @Override public void updateSkin(Skin skin) { GameProfile newProfile = new GameProfile(uuid, name); newProfile.getProperties().get("textures").clear(); newProfile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature())); this.packetPlayOutPlayerInfoAdd = new PacketPlayOutPlayerInfoWrapper().create(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, newProfile, name); for (Player player : Bukkit.getOnlinePlayers()) { PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection; playerConnection.sendPacket(packetPlayOutPlayerInfoRemove); playerConnection.sendPacket(packetPlayOutEntityDestroy); playerConnection.sendPacket(packetPlayOutPlayerInfoAdd); playerConnection.sendPacket(packetPlayOutNamedEntitySpawn); } } }