diff --git a/main/src/main/java/net/citizensnpcs/Citizens.java b/main/src/main/java/net/citizensnpcs/Citizens.java index 57d809045..7278f4826 100644 --- a/main/src/main/java/net/citizensnpcs/Citizens.java +++ b/main/src/main/java/net/citizensnpcs/Citizens.java @@ -95,7 +95,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { private final CommandManager commands = new CommandManager(); private Settings config; private boolean enabled; - private Locale locale; private LocationLookup locationLookup; private final NMSHelper nmsHelper = new NMSHelper() { private boolean SUPPORT_OWNER_PROFILE = true; @@ -548,7 +547,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { } } Translator.setInstance(new File(getDataFolder(), "lang"), locale); - this.locale = locale; } private void startMetrics() { @@ -559,7 +557,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { return 0; return Iterables.size(npcRegistry); })); - metrics.addCustomChart(new Metrics.SimplePie("locale", () -> locale.toString())); + metrics.addCustomChart(new Metrics.SimplePie("locale", () -> Locale.getDefault().toString())); metrics.addCustomChart(new Metrics.AdvancedPie("traits", () -> { Map res = Maps.newHashMap(); for (NPC npc : npcRegistry) { diff --git a/main/src/main/java/net/citizensnpcs/EventListen.java b/main/src/main/java/net/citizensnpcs/EventListen.java index 77b6aa28c..3c61d3026 100644 --- a/main/src/main/java/net/citizensnpcs/EventListen.java +++ b/main/src/main/java/net/citizensnpcs/EventListen.java @@ -90,6 +90,7 @@ import net.citizensnpcs.api.event.NPCDeathEvent; import net.citizensnpcs.api.event.NPCDespawnEvent; import net.citizensnpcs.api.event.NPCKnockbackEvent; import net.citizensnpcs.api.event.NPCLeftClickEvent; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCPushEvent; import net.citizensnpcs.api.event.NPCRemoveEvent; import net.citizensnpcs.api.event.NPCRightClickEvent; @@ -109,6 +110,7 @@ import net.citizensnpcs.trait.ClickRedirectTrait; import net.citizensnpcs.trait.CommandTrait; import net.citizensnpcs.trait.Controllable; import net.citizensnpcs.trait.CurrentLocation; +import net.citizensnpcs.trait.HologramTrait; import net.citizensnpcs.trait.ShopTrait; import net.citizensnpcs.util.ChunkCoord; import net.citizensnpcs.util.Messages; @@ -428,6 +430,55 @@ public class EventListen implements Listener { } } + @EventHandler(ignoreCancelled = true) + public void onNPCLinkToPlayer(NPCLinkToPlayerEvent event) { + NPC npc = event.getNPC(); + ClickRedirectTrait crt = npc.getTraitNullable(ClickRedirectTrait.class); + if (crt != null) { + HologramTrait ht = crt.getRedirectNPC().getTraitNullable(HologramTrait.class); + if (ht != null) { + ht.onHologramSeenByPlayer(npc, event.getPlayer()); + } + } + + /* TODO + if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) { + onNPCPlayerLinkToPlayer(event); + } + */ + } + + private void onNPCPlayerLinkToPlayer(NPCLinkToPlayerEvent event) { + Entity tracker = event.getNPC().getEntity(); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { + if (!tracker.isValid() || !event.getPlayer().isValid()) + return; + + NMS.sendPositionUpdate(tracker, false, null, null, NMS.getHeadYaw(tracker)); + }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks() + 1); + + boolean resetYaw = event.getNPC().data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, + Setting.RESET_YAW_ON_SPAWN.asBoolean()); + boolean sendTabRemove = NMS.sendTabListAdd(event.getPlayer(), (Player) tracker); + if (!sendTabRemove || !Setting.DISABLE_TABLIST.asBoolean()) { + if (resetYaw) { + // Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + // () -> PlayerAnimation.ARM_SWING.play((Player) tracker, event.getPlayer()), 1); + } + return; + } + + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { + if (!tracker.isValid() || !event.getPlayer().isValid()) + return; + + NMS.sendTabListRemove(event.getPlayer(), (Player) tracker); + if (resetYaw) { + // PlayerAnimation.ARM_SWING.play((Player) tracker, event.getPlayer()); + } + }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onNPCRemove(NPCRemoveEvent event) { toRespawn.values().remove(event.getNPC()); @@ -436,12 +487,14 @@ public class EventListen implements Listener { @EventHandler(ignoreCancelled = true) public void onNPCSeenByPlayer(NPCSeenByPlayerEvent event) { NPC npc = event.getNPC(); - if (npc.hasTrait(ClickRedirectTrait.class)) { - npc = npc.getOrAddTrait(ClickRedirectTrait.class).getRedirectNPC(); + ClickRedirectTrait crt = npc.getTraitNullable(ClickRedirectTrait.class); + if (crt != null) { + npc = crt.getRedirectNPC(); } - if (npc.hasTrait(PlayerFilter.class)) { - event.setCancelled(npc.getOrAddTrait(PlayerFilter.class).onSeenByPlayer(event.getPlayer())); + PlayerFilter pf = npc.getTraitNullable(PlayerFilter.class); + if (pf != null) { + event.setCancelled(pf.onSeenByPlayer(event.getPlayer())); } } diff --git a/main/src/main/java/net/citizensnpcs/trait/HologramTrait.java b/main/src/main/java/net/citizensnpcs/trait/HologramTrait.java index a5b5f40e1..f2eef9f09 100644 --- a/main/src/main/java/net/citizensnpcs/trait/HologramTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/HologramTrait.java @@ -14,7 +14,6 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; -import org.bukkit.entity.Interaction; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.ItemStack; @@ -36,9 +35,10 @@ import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.Util; /** - * Persists a hologram attached to the NPC. + * Manages a set of holograms attached to the NPC. Holograms are lines of text or items that follow the NPC at + * some offset (typically vertically offset). */ -// TODO: refactor this class and remove HologramDirection +// TODO: refactor this class @TraitName("hologramtrait") public class HologramTrait extends Trait { private Location currentLoc; @@ -99,6 +99,7 @@ public class HologramTrait extends Trait { hologramNPC = registry.createNPC(EntityType.INTERACTION, line); hologramNPC.addTrait(new ClickRedirectTrait(npc)); hologramNPC.data().set(NPC.Metadata.NAMEPLATE_VISIBLE, true); + hologramNPC.getOrAddTrait(MountTrait.class).setMountedOn(npc.getUniqueId()); } else { hologramNPC = registry.createNPC(EntityType.ARMOR_STAND, line); hologramNPC.getOrAddTrait(ArmorStandTrait.class).setAsHelperEntityWithName(npc); @@ -110,11 +111,6 @@ public class HologramTrait extends Trait { hologramNPC.spawn(currentLoc.clone().add(0, getEntityHeight() + heightOffset, 0)); - if (useDisplayEntities) { - ((Interaction) hologramNPC.getEntity()).setInteractionWidth(0); - NMS.updateMountedInteractionHeight(hologramNPC.getEntity(), npc.getEntity(), heightOffset); - } - Matcher itemMatcher = ITEM_MATCHER.matcher(line); if (itemMatcher.matches()) { Material item = SpigotUtil.isUsing1_13API() ? Material.matchMaterial(itemMatcher.group(1), false) @@ -214,6 +210,27 @@ public class HologramTrait extends Trait { } } + public void onHologramSeenByPlayer(NPC hologram, Player player) { + if (useDisplayEntities && npc.isSpawned()) { + double height = -1; + if (nameLine != null && hologram.equals(nameLine.hologram)) { + height = 0; + } else { + for (int i = 0; i < lines.size(); i++) { + if (hologram.equals(lines.get(i).hologram)) { + height = getHeight(i); + break; + } + } + } + + if (height == -1) + return; + + NMS.linkTextInteraction(player, hologram.getEntity(), npc.getEntity(), height); + } + } + @Override public void onRemove() { onDespawn(); diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index c4bb24afd..83a66beef 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -635,6 +635,10 @@ public class NMS { return BRIDGE.isValid(entity); } + public static void linkTextInteraction(Player player, Entity interaction, Entity mount, double height) { + BRIDGE.linkTextInteraction(player, interaction, mount, height); + } + public static void load(CommandManager commands) { BRIDGE.load(commands); } @@ -891,10 +895,6 @@ public class NMS { BRIDGE.updateInventoryTitle(player, view, newTitle); } - public static void updateMountedInteractionHeight(Entity entity, Entity mount, double height) { - BRIDGE.updateMountedInteractionHeight(entity, mount, height); - } - public static void updateNavigationWorld(org.bukkit.entity.Entity entity, org.bukkit.World world) { BRIDGE.updateNavigationWorld(entity, world); } diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index d75708669..85fc987c9 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -126,6 +126,9 @@ public interface NMSBridge { public boolean isValid(Entity entity); + public default void linkTextInteraction(Player player, Entity interaction, Entity mount, double height) { + } + public void load(CommandManager commands); public void look(Entity from, Entity to); @@ -145,9 +148,9 @@ public interface NMSBridge { public void playAnimation(PlayerAnimation animation, Player player, int radius); - public Runnable playerTicker(Player entity); + public Runnable playerTicker(Player entity);; - public void registerEntityClass(Class clazz);; + public void registerEntityClass(Class clazz); public void remove(Entity entity); @@ -163,20 +166,20 @@ public interface NMSBridge { public boolean sendTabListAdd(Player recipient, Player listPlayer); - public void sendTabListRemove(Player recipient, Collection skinnableNPCs); + public void sendTabListRemove(Player recipient, Collection skinnableNPCs);; public void sendTabListRemove(Player recipient, Player listPlayer);; public void sendTeamPacket(Player recipient, Team team, int mode);; default public void setAggressive(Entity entity, boolean aggro) { - }; + } public default void setAllayDancing(Entity entity, boolean dancing) { throw new UnsupportedOperationException(); - } + }; - public void setBodyYaw(Entity entity, float yaw);; + public void setBodyYaw(Entity entity, float yaw); public void setBoundingBox(Entity entity, BoundingBox box); @@ -262,9 +265,6 @@ public interface NMSBridge { public void updateInventoryTitle(Player player, InventoryView view, String newTitle); - public default void updateMountedInteractionHeight(Entity entity, Entity mount, double height) { - } - public void updateNavigationWorld(Entity entity, World world); public void updatePathfindingRange(NPC npc, float pathfindingRange); diff --git a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/PlayerlistTrackerEntry.java b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/PlayerlistTrackerEntry.java index 03de1e058..b23462922 100644 --- a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/PlayerlistTrackerEntry.java +++ b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/PlayerlistTrackerEntry.java @@ -6,6 +6,8 @@ import org.bukkit.Bukkit; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_10_R1.entity.EntityHumanNPC; @@ -27,7 +29,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - // prevent updates to NPC "viewers" if (entityplayer instanceof EntityHumanNPC) return; Entity tracker = getTracker(this); @@ -38,8 +39,12 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { if (event.isCancelled()) return; } - if (tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER) + + super.updatePlayer(entityplayer); + + if (tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; + if (entityplayer != tracker && c(entityplayer)) { if (!this.trackedPlayers.contains(entityplayer) && ((entityplayer.x().getPlayerChunkMap().a(entityplayer, tracker.ac, tracker.ae)) @@ -51,9 +56,12 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { return; skinnable.getSkinTracker().updateViewer(entityplayer.getBukkitEntity()); } + + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent( + ((NPCHolder) tracker).getNPC(), entityplayer.getBukkitEntity()))); } } - super.updatePlayer(entityplayer); } private static int getE(EntityTrackerEntry entry) { diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/PlayerlistTrackerEntry.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/PlayerlistTrackerEntry.java index 7defca074..069cdd767 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/PlayerlistTrackerEntry.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/PlayerlistTrackerEntry.java @@ -14,6 +14,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.ai.NPCHolder; @@ -86,19 +87,27 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) { + final EntityPlayer entityplayer = lastUpdatedPlayer; + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent( + new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), entityplayer.getBukkitEntity()))); + } + if (lastUpdatedPlayer == null || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; - final EntityPlayer entityplayer = lastUpdatedPlayer; + NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - lastUpdatedPlayer = null; NPC npc = ((NPCHolder) tracker).getNPC(); if (npc.data().get(NPC.Metadata.RESET_YAW_ON_SPAWN, Setting.RESET_YAW_ON_SPAWN.asBoolean())) { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -106,15 +115,17 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) { + if (entityplayer instanceof NPCHolder) + return; + + if (!isTracked(entityplayer) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; } - if (entityplayer instanceof NPCHolder) - return; + super.updatePlayer(entityplayer); } diff --git a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/PlayerlistTrackerEntry.java b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/PlayerlistTrackerEntry.java index ad7dc6585..fa9def283 100644 --- a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/PlayerlistTrackerEntry.java +++ b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/PlayerlistTrackerEntry.java @@ -14,6 +14,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_12_R1.entity.EntityHumanNPC; @@ -87,9 +88,15 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) { + final EntityPlayer entityplayer = lastUpdatedPlayer; + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent( + new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), entityplayer.getBukkitEntity()))); + } + if (lastUpdatedPlayer == null || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; - final EntityPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); lastUpdatedPlayer = null; NPC npc = ((NPCHolder) tracker).getNPC(); @@ -98,8 +105,10 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -107,12 +116,16 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!isTracked(entityplayer) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; + Integer trackingRange = npc.data(). get(NPC.Metadata.TRACKING_RANGE); if (TRACKING_RANGE_SETTER != null && trackingRange != null && npc.data().get("last-tracking-range", -1) != trackingRange.intValue()) { @@ -125,9 +138,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } } - if (entityplayer instanceof EntityHumanNPC) - return; - super.updatePlayer(entityplayer); } diff --git a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/PlayerlistTrackerEntry.java b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/PlayerlistTrackerEntry.java index 8932b2946..83bfb89fc 100644 --- a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/PlayerlistTrackerEntry.java +++ b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/PlayerlistTrackerEntry.java @@ -14,6 +14,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_13_R2.entity.EntityHumanNPC; @@ -86,9 +87,15 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) { + final EntityPlayer entityplayer = lastUpdatedPlayer; + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent( + new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), entityplayer.getBukkitEntity()))); + } if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; - final EntityPlayer entityplayer = lastUpdatedPlayer; + NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); lastUpdatedPlayer = null; NPC npc = ((NPCHolder) tracker).getNPC(); @@ -97,8 +104,10 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -106,7 +115,10 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!isTracked(entityplayer) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); @@ -124,9 +136,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } } - if (entityplayer instanceof EntityHumanNPC) - return; - super.updatePlayer(entityplayer); } @@ -186,15 +195,10 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } private static Field E = NMS.getField(EntityTrackerEntry.class, "e"); - private static Field F = NMS.getField(EntityTrackerEntry.class, "f"); - private static Field G = NMS.getField(EntityTrackerEntry.class, "g"); - private static Field TRACKER = NMS.getField(EntityTrackerEntry.class, "tracker"); - private static MethodHandle TRACKING_MAP_GETTER; - private static MethodHandle TRACKING_MAP_SETTER; private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class, int.class); diff --git a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/PlayerlistTracker.java b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/PlayerlistTracker.java index 0fa51c80f..ff896a90a 100644 --- a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/PlayerlistTracker.java +++ b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/PlayerlistTracker.java @@ -13,6 +13,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_14_R1.entity.EntityHumanNPC; @@ -87,8 +88,15 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { } public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) { + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), + lastUpdatedPlayer.getBukkitEntity()))); + } + if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; + final EntityPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); NPC npc = ((NPCHolder) tracker).getNPC(); @@ -97,8 +105,10 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -106,12 +116,16 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!isTracked(entityplayer) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; + Integer trackingRange = npc.data(). get(NPC.Metadata.TRACKING_RANGE); if (TRACKING_RANGE_SETTER != null && trackingRange != null && npc.data().get("last-tracking-range", -1) != trackingRange.intValue()) { @@ -124,9 +138,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { } } - if (entityplayer instanceof EntityHumanNPC) - return; - super.updatePlayer(entityplayer); } diff --git a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/PlayerlistTracker.java b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/PlayerlistTracker.java index 1886bd3f6..3b71f3e6f 100644 --- a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/PlayerlistTracker.java +++ b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/PlayerlistTracker.java @@ -13,6 +13,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_15_R1.entity.EntityHumanNPC; @@ -87,8 +88,15 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { } public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) { + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), + lastUpdatedPlayer.getBukkitEntity()))); + } + if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; + final EntityPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); NPC npc = ((NPCHolder) tracker).getNPC(); @@ -97,8 +105,10 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -106,12 +116,16 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!isTracked(entityplayer) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; + Integer trackingRange = npc.data(). get(NPC.Metadata.TRACKING_RANGE); if (TRACKING_RANGE_SETTER != null && trackingRange != null && npc.data().get("last-tracking-range", -1) != trackingRange.intValue()) { @@ -124,9 +138,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { } } - if (entityplayer instanceof EntityHumanNPC) - return; - super.updatePlayer(entityplayer); } diff --git a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/PlayerlistTracker.java b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/PlayerlistTracker.java index 31242dfd9..8867be36e 100644 --- a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/PlayerlistTracker.java +++ b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/PlayerlistTracker.java @@ -13,6 +13,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_16_R3.entity.EntityHumanNPC; @@ -87,9 +88,16 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { } public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) { + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), + lastUpdatedPlayer.getBukkitEntity()))); + } + if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER || !CitizensAPI.hasImplementation()) return; + final EntityPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); NPC npc = ((NPCHolder) tracker).getNPC(); @@ -98,8 +106,10 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -107,12 +117,16 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!tracker.dead && !isTracked(entityplayer) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!isTracked(entityplayer) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) return; + Integer trackingRange = npc.data(). get(NPC.Metadata.TRACKING_RANGE); if (TRACKING_RANGE_SETTER != null && trackingRange != null && npc.data().get("last-tracking-range", -1) != trackingRange.intValue()) { @@ -125,9 +139,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { } } - if (entityplayer instanceof EntityHumanNPC) - return; - super.updatePlayer(entityplayer); } diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerlistTracker.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerlistTracker.java index 70a514b66..e0c0a6244 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerlistTracker.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerlistTracker.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_17_R1.entity.EntityHumanNPC; @@ -35,9 +36,16 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { } public void updateLastPlayer() { + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), + lastUpdatedPlayer.getBukkitEntity()))); + } + if (tracker.isRemoved() || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER || !CitizensAPI.hasImplementation()) return; + final ServerPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); NPC npc = ((NPCHolder) tracker).getNPC(); @@ -46,8 +54,10 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -55,7 +65,10 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { @Override public void updatePlayer(final ServerPlayer entityplayer) { - if (!tracker.isRemoved() && !seenBy.contains(entityplayer.connection) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!seenBy.contains(entityplayer.connection) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); if (REQUIRES_SYNC == null) { REQUIRES_SYNC = !Bukkit.isPrimaryThread(); @@ -87,9 +100,6 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { return; } - if (entityplayer instanceof EntityHumanNPC) - return; - this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); } diff --git a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/PlayerlistTracker.java b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/PlayerlistTracker.java index bfd8804e3..b1e40f544 100644 --- a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/PlayerlistTracker.java +++ b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/PlayerlistTracker.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC; @@ -35,9 +36,16 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { } public void updateLastPlayer() { + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), + lastUpdatedPlayer.getBukkitEntity()))); + } + if (tracker.isRemoved() || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER || !CitizensAPI.hasImplementation()) return; + final ServerPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); NPC npc = ((NPCHolder) tracker).getNPC(); @@ -46,8 +54,10 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)), 1); } + if (!Setting.DISABLE_TABLIST.asBoolean()) return; + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); @@ -55,7 +65,10 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { @Override public void updatePlayer(final ServerPlayer entityplayer) { - if (!tracker.isRemoved() && !seenBy.contains(entityplayer.connection) && tracker instanceof NPCHolder) { + if (entityplayer instanceof EntityHumanNPC) + return; + + if (!seenBy.contains(entityplayer.connection) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); if (REQUIRES_SYNC == null) { REQUIRES_SYNC = !Bukkit.isPrimaryThread(); @@ -85,10 +98,12 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { if (cancelled) return; - } - if (entityplayer instanceof EntityHumanNPC) + this.lastUpdatedPlayer = entityplayer; + super.updatePlayer(entityplayer); + Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(npc, entityplayer.getBukkitEntity())); return; + } this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/CitizensEntityTracker.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/CitizensEntityTracker.java index cfdc971c9..a4c2d81ec 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/CitizensEntityTracker.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/CitizensEntityTracker.java @@ -11,6 +11,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC; @@ -39,6 +40,9 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { boolean res = super.add(conn); if (res) { updateLastPlayer(conn.getPlayer()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent( + ((NPCHolder) tracker).getNPC(), conn.getPlayer().getBukkitEntity()))); } return res; } @@ -87,7 +91,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { if (entityplayer instanceof EntityHumanNPC) return; - if (!tracker.isRemoved() && !seenBy.contains(entityplayer.connection) && tracker instanceof NPCHolder) { + if (!seenBy.contains(entityplayer.connection) && tracker instanceof NPCHolder) { NPC npc = ((NPCHolder) tracker).getNPC(); if (REQUIRES_SYNC == null) { REQUIRES_SYNC = !Bukkit.isPrimaryThread(); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java index a7166ae32..34012a538 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/util/NMSImpl.java @@ -281,6 +281,7 @@ import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; import net.minecraft.network.protocol.game.VecDeltaCodec; import net.minecraft.network.syncher.EntityDataAccessor; @@ -936,6 +937,22 @@ public class NMSImpl implements NMSBridge { return handle.valid && handle.isAlive(); } + @Override + public void linkTextInteraction(org.bukkit.entity.Player player, org.bukkit.entity.Entity entity, + org.bukkit.entity.Entity mount, double offset) { + Interaction handle = (Interaction) getHandle(entity); + offset += -0.5 + getHandle(mount).getPassengersRidingOffset(); + sendPacket(player, + new ClientboundBundlePacket(List.of( + new ClientboundSetEntityDataPacket(entity.getEntityId(), + List.of(new SynchedEntityData.DataItem<>(INTERACTION_WIDTH, 0f).value(), + new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, (float) offset).value(), + new SynchedEntityData.DataItem<>(DATA_POSE, Pose.CROAKING).value())), + new ClientboundSetPassengersPacket(getHandle(mount)), + new ClientboundSetEntityDataPacket(entity.getEntityId(), + List.of(new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, 999999f).value()))))); + } + @Override public void load(CommandManager manager) { registerTraitWithCommand(manager, EnderDragonTrait.class); @@ -1848,22 +1865,6 @@ public class NMSImpl implements NMSBridge { player.updateInventory(); } - @Override - public void updateMountedInteractionHeight(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity mount, - double offset) { - Interaction handle = (Interaction) getHandle(entity); - offset += -0.5 + getHandle(mount).getPassengersRidingOffset(); - ((org.bukkit.entity.Interaction) entity).setInteractionHeight((float) offset); - mount.addPassenger(entity); - handle.setPose(Pose.SNIFFING); - Bukkit.getScheduler().runTask(CitizensAPI.getPlugin(), () -> { - if (!entity.isValid()) - return; - sendPacketNearby(null, entity.getLocation(), new ClientboundSetEntityDataPacket(handle.getId(), - List.of(new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, 999999f).value()))); - }); - } - @Override public void updateNavigationWorld(org.bukkit.entity.Entity entity, World world) { if (NAVIGATION_WORLD_FIELD == null) @@ -2594,6 +2595,7 @@ public class NMSImpl implements NMSBridge { .newHashMap(); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getFirstSetter(CraftBossBar.class, ServerBossEvent.class); + private static EntityDataAccessor DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true, boolean.class, AABB.class); @@ -2617,6 +2619,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle HEAD_HEIGHT_METHOD = NMS.getFirstMethodHandle(Entity.class, true, Pose.class, EntityDimensions.class); private static EntityDataAccessor INTERACTION_HEIGHT = null; + private static EntityDataAccessor INTERACTION_WIDTH = null; private static final MethodHandle JUMP_FIELD = NMS.getGetter(LivingEntity.class, "bi"); private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(Mob.class, LookControl.class); private static final MethodHandle MAKE_REQUEST = NMS.getMethodHandle(YggdrasilAuthenticationService.class, @@ -2677,5 +2680,17 @@ public class NMSImpl implements NMSBridge { } catch (Throwable e) { e.printStackTrace(); } + + try { + INTERACTION_WIDTH = (EntityDataAccessor) NMS.getGetter(Interaction.class, "c").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } + + try { + DATA_POSE = (EntityDataAccessor) NMS.getGetter(Entity.class, "ar").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/CitizensEntityTracker.java b/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/CitizensEntityTracker.java index 0debe411f..4e3864caf 100644 --- a/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/CitizensEntityTracker.java +++ b/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/CitizensEntityTracker.java @@ -11,6 +11,7 @@ import com.google.common.collect.ForwardingSet; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_20_R2.entity.EntityHumanNPC; @@ -40,6 +41,9 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { boolean res = super.add(conn); if (res) { updateLastPlayer(conn.getPlayer()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent( + ((NPCHolder) tracker).getNPC(), conn.getPlayer().getBukkitEntity()))); } return res; } @@ -62,6 +66,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { if (tracker.isRemoved() || tracker.getBukkitEntity().getType() != EntityType.PLAYER || !CitizensAPI.hasImplementation()) return; + final ServerPlayer entityplayer = lastUpdatedPlayer; Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { if (tracker.isRemoved() || entityplayer.isRemoved()) @@ -81,6 +86,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { } return; } + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { if (tracker.isRemoved() || entityplayer.isRemoved()) return; diff --git a/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/NMSImpl.java b/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/NMSImpl.java index ef654a696..af0016247 100644 --- a/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/NMSImpl.java +++ b/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/NMSImpl.java @@ -271,6 +271,7 @@ import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; import net.minecraft.network.protocol.game.VecDeltaCodec; import net.minecraft.network.syncher.EntityDataAccessor; @@ -912,6 +913,21 @@ public class NMSImpl implements NMSBridge { return handle.valid && handle.isAlive(); } + @Override + public void linkTextInteraction(org.bukkit.entity.Player player, org.bukkit.entity.Entity entity, + org.bukkit.entity.Entity mount, double offset) { + Interaction handle = (Interaction) getHandle(entity); + offset += handle.getMyRidingOffset(getHandle(mount)); + sendPacket(player, new ClientboundBundlePacket(List.of( + new ClientboundSetEntityDataPacket(entity.getEntityId(), + List.of(new SynchedEntityData.DataItem<>(INTERACTION_WIDTH, 0f).value(), + new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, (float) offset).value(), + new SynchedEntityData.DataItem<>(DATA_POSE, Pose.CROAKING).value())), + new ClientboundSetPassengersPacket(getHandle(mount)), + new ClientboundSetEntityDataPacket(entity.getEntityId(), + List.of(new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, 999999f).value()))))); + } + @Override public void load(CommandManager manager) { registerTraitWithCommand(manager, EnderDragonTrait.class); @@ -1707,12 +1723,12 @@ public class NMSImpl implements NMSBridge { ENTITY_REGISTRY_SETTER.invoke(null, ENTITY_REGISTRY.get()); } catch (Throwable e) { } - } + }; @Override public void sleep(org.bukkit.entity.Player player, boolean sleeping) { getHandle(player).setPose(sleeping ? Pose.SLEEPING : Pose.STANDING); - }; + } @Override public void trySwim(org.bukkit.entity.Entity entity) { @@ -1824,22 +1840,6 @@ public class NMSImpl implements NMSBridge { player.updateInventory(); } - @Override - public void updateMountedInteractionHeight(org.bukkit.entity.Entity entity, org.bukkit.entity.Entity mount, - double offset) { - Interaction handle = (Interaction) getHandle(entity); - offset += handle.getMyRidingOffset(getHandle(mount)); - ((org.bukkit.entity.Interaction) entity).setInteractionHeight((float) offset); - mount.addPassenger(entity); - handle.setPose(Pose.SNIFFING); - Bukkit.getScheduler().runTask(CitizensAPI.getPlugin(), () -> { - if (!entity.isValid()) - return; - sendPacketNearby(null, entity.getLocation(), new ClientboundSetEntityDataPacket(handle.getId(), - List.of(new SynchedEntityData.DataItem<>(INTERACTION_HEIGHT, 999999f).value()))); - }); - } - @Override public void updateNavigationWorld(org.bukkit.entity.Entity entity, World world) { if (NAVIGATION_WORLD_FIELD == null) @@ -2576,6 +2576,7 @@ public class NMSImpl implements NMSBridge { public static MethodHandle CONNECTION_PACKET_LISTENER = NMS.getSetter(Connection.class, "q"); private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getFirstSetter(CraftBossBar.class, ServerBossEvent.class); + private static EntityDataAccessor DATA_POSE = null; private static final float DEFAULT_SPEED = 1F; public static final MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EnderDragon.class, true, boolean.class, AABB.class); @@ -2602,6 +2603,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle HEAD_HEIGHT_METHOD = NMS.getFirstMethodHandle(Entity.class, true, Pose.class, EntityDimensions.class); private static EntityDataAccessor INTERACTION_HEIGHT = null; + private static EntityDataAccessor INTERACTION_WIDTH = null; private static final MethodHandle JUMP_FIELD = NMS.getGetter(LivingEntity.class, "bj"); private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(Mob.class, LookControl.class); private static final MethodHandle MOVE_CONTROLLER_OPERATION = NMS.getSetter(MoveControl.class, "k"); @@ -2643,22 +2645,37 @@ public class NMSImpl implements NMSBridge { Messaging.logTr(Messages.ERROR_GETTING_ID_MAPPING, e.getMessage()); e.printStackTrace(); } + try { // Middle one ENDERMAN_CREEPY = (EntityDataAccessor) NMS.getField(EnderMan.class, "bV").get(null); } catch (Exception e) { e.printStackTrace(); } + try { RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor) NMS .getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke(); } catch (Throwable e) { e.printStackTrace(); } + try { INTERACTION_HEIGHT = (EntityDataAccessor) NMS.getGetter(Interaction.class, "d").invoke(); } catch (Throwable e) { e.printStackTrace(); } + + try { + INTERACTION_WIDTH = (EntityDataAccessor) NMS.getGetter(Interaction.class, "c").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } + + try { + DATA_POSE = (EntityDataAccessor) NMS.getGetter(Entity.class, "as").invoke(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/PlayerAnimationImpl.java b/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/PlayerAnimationImpl.java index 662bbf0d2..59adcf5ea 100644 --- a/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/PlayerAnimationImpl.java +++ b/v1_20_R2/src/main/java/net/citizensnpcs/nms/v1_20_R2/util/PlayerAnimationImpl.java @@ -24,6 +24,7 @@ public class PlayerAnimationImpl { playDefaultAnimation(player, radius, DEFAULTS.get(animation)); return; } + switch (animation) { case HURT: sendPacketNearby(new ClientboundHurtAnimationPacket(player), player, radius); diff --git a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerlistTrackerEntry.java b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerlistTrackerEntry.java index 175c8dbef..d918539a1 100644 --- a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerlistTrackerEntry.java +++ b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerlistTrackerEntry.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.NPCLinkToPlayerEvent; import net.citizensnpcs.api.event.NPCSeenByPlayerEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_8_R3.entity.EntityHumanNPC; @@ -34,7 +35,13 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } public void updateLastPlayer() { - if ((lastUpdatedPlayer == null) || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER) + if (lastUpdatedPlayer != null) { + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> Bukkit.getPluginManager().callEvent(new NPCLinkToPlayerEvent(((NPCHolder) tracker).getNPC(), + lastUpdatedPlayer.getBukkitEntity()))); + } + + if (lastUpdatedPlayer == null || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER) return; final EntityPlayer entityplayer = lastUpdatedPlayer; NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); @@ -56,7 +63,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - // prevent updates to NPC "viewers" if (entityplayer instanceof EntityHumanNPC) return; if (!trackedPlayers.contains(entityplayer) && tracker instanceof NPCHolder) { @@ -66,6 +72,7 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { if (event.isCancelled()) return; } + lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); lastUpdatedPlayer = null;