diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java index 5a97fbf7..88356738 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_17PacketFactory.java @@ -1,8 +1,11 @@ package lol.pyr.znpcsplus.packets; import com.github.retrooper.packetevents.PacketEventsAPI; +import com.github.retrooper.packetevents.protocol.entity.data.EntityData; +import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.util.Vector3d; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity; import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.config.ConfigManager; @@ -11,12 +14,15 @@ import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.util.NamedColor; import lol.pyr.znpcsplus.util.NpcLocation; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import java.util.Collections; import java.util.Optional; + public class V1_17PacketFactory extends V1_8PacketFactory { public V1_17PacketFactory(TaskScheduler scheduler, PacketEventsAPI packetEvents, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, ConfigManager configManager) { super(scheduler, packetEvents, propertyRegistry, textSerializer, configManager); @@ -27,6 +33,21 @@ public void spawnEntity(Player player, PacketEntity entity, PropertyHolder prope NpcLocation location = entity.getLocation(); sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), npcLocationToVector(location), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.of(new Vector3d()))); + + // Sets the nickname of an entity other than the player. If the display_name attribute is empty, the default entity name is used. + // V1_8PacketFactory spawnEntity method + // I am currently playing version 1.21.1, and I am busy, so it is not very convenient for me to test it. + if (displayNameProperty != null && properties.hasProperty(displayNameProperty.get())) { + EntityData> nameData = new EntityData<>( + 2, + EntityDataTypes.OPTIONAL_ADV_COMPONENT, + Optional.of(Component.text(properties.getProperty(displayNameProperty.get()))) + ); + sendPacket(player, new WrapperPlayServerEntityMetadata( + entity.getEntityId(), + Collections.singletonList(nameData) + )); + } sendAllMetadata(player, entity, properties); if (EntityTypes.isTypeInstanceOf(entity.getType(), EntityTypes.LIVINGENTITY)) sendAllAttributes(player, entity, properties); createTeam(player, entity, properties.getProperty(propertyRegistry.getByName("glow", NamedColor.class))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19_3PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19_3PacketFactory.java index 0f46d971..a885f9dd 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19_3PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_19_3PacketFactory.java @@ -29,7 +29,7 @@ public V1_19_3PacketFactory(TaskScheduler scheduler, PacketEventsAPI pac public CompletableFuture addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties) { if (entity.getType() != EntityTypes.PLAYER) return CompletableFuture.completedFuture(null); CompletableFuture future = new CompletableFuture<>(); - Component displayName = tabListDisplayNameProperty != null && properties.hasProperty(tabListDisplayNameProperty.get()) ? + Component tabListDisplayName = tabListDisplayNameProperty != null && properties.hasProperty(tabListDisplayNameProperty.get()) ? PapiUtil.set(textSerializer, player, properties.getProperty(tabListDisplayNameProperty.get())) : Component.text(PapiUtil.set(player, configManager.getConfig().tabDisplayName() .replace("{id}", Integer.toString(entity.getEntityId())) @@ -38,10 +38,14 @@ public CompletableFuture addTabPlayer(Player player, PacketEntity entity, "") )); boolean listed = alwaysVisibleInTabProperty == null || properties.getProperty(alwaysVisibleInTabProperty.get()); - skinned(player, properties, new UserProfile(entity.getUuid(), Integer.toString(entity.getEntityId()))).thenAccept(profile -> { + + // This is to set the entity name for NPCs + String displayName = displayNameProperty != null && properties.hasProperty(displayNameProperty.get()) ? + properties.getProperty(displayNameProperty.get()) : Integer.toString(entity.getEntityId()); + skinned(player, properties, new UserProfile(entity.getUuid(), displayName)).thenAccept(profile -> { WrapperPlayServerPlayerInfoUpdate.PlayerInfo info = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( profile, listed, 1, GameMode.CREATIVE, - displayName, null); + tabListDisplayName, null); sendPacket(player, new WrapperPlayServerPlayerInfoUpdate(EnumSet.of(WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_DISPLAY_NAME), info, info, info)); @@ -77,4 +81,4 @@ public void updateDisplayName(Player player, PacketEntity entity, Component disp entity.isListedInTabList(), 1, GameMode.CREATIVE, displayName, null)) ); } -} +} \ No newline at end of file diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java index da556749..bc614ad1 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java @@ -110,7 +110,7 @@ public void teleportEntity(Player player, PacketEntity entity) { public CompletableFuture addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties) { if (entity.getType() != EntityTypes.PLAYER) return CompletableFuture.completedFuture(null); CompletableFuture future = new CompletableFuture<>(); - Component displayName = tabListDisplayNameProperty != null && properties.getProperty(tabListDisplayNameProperty.get()) != null ? + Component tabListDisplayName = tabListDisplayNameProperty != null && properties.getProperty(tabListDisplayNameProperty.get()) != null ? PapiUtil.set(textSerializer, player, properties.getProperty(tabListDisplayNameProperty.get())) : Component.text(PapiUtil.set(player, configManager.getConfig().tabDisplayName() .replace("{id}", Integer.toString(entity.getEntityId())) @@ -118,10 +118,14 @@ public CompletableFuture addTabPlayer(Player player, PacketEntity entity, properties.getProperty(displayNameProperty.get()) : "") )); - skinned(player, properties, new UserProfile(entity.getUuid(), Integer.toString(entity.getEntityId()))).thenAccept(profile -> { + + // This is to set the entity name for NPCs. + String displayName = displayNameProperty != null && properties.hasProperty(displayNameProperty.get()) ? + properties.getProperty(displayNameProperty.get()) : Integer.toString(entity.getEntityId()); + skinned(player, properties, new UserProfile(entity.getUuid(), displayName)).thenAccept(profile -> { sendPacket(player, new WrapperPlayServerPlayerInfo( WrapperPlayServerPlayerInfo.Action.ADD_PLAYER, new WrapperPlayServerPlayerInfo.PlayerData( - displayName, profile, GameMode.CREATIVE, 1))); + tabListDisplayName, profile, GameMode.CREATIVE, 1))); entity.setListedInTabList(true); future.complete(null); }); @@ -147,8 +151,16 @@ public void createTeam(Player player, PacketEntity entity, NamedColor namedColor namedColor == null ? NamedTextColor.WHITE : NamedTextColor.NAMES.value(namedColor.name().toLowerCase()), WrapperPlayServerTeams.OptionData.NONE ))); + + PropertyHolder properties = entity.getProperties(); + String displayName = displayNameProperty != null && properties.hasProperty(displayNameProperty.get()) ? + properties.getProperty(displayNameProperty.get()) : Integer.toString(entity.getEntityId()); + // 这个displayName替换掉原来的实体ID,是为了 + // '当NPC实体为玩家类型时,隐藏掉NPC头顶上的名称显示 不然会和hologram一起显示 导致有些混淆与冲突' + // This displayName replaces the original entityID in order to + // 'hide the name display above the NPC's head when the NPC entity is a player type, otherwise it will be displayed together with the hologram, causing some confusion and conflict' sendPacket(player, new WrapperPlayServerTeams("npc_team_" + entity.getEntityId(), WrapperPlayServerTeams.TeamMode.ADD_ENTITIES, (WrapperPlayServerTeams.ScoreBoardTeamInfo) null, - entity.getType() == EntityTypes.PLAYER ? Integer.toString(entity.getEntityId()) : entity.getUuid().toString())); + entity.getType() == EntityTypes.PLAYER ? displayName : entity.getUuid().toString())); } @Override