Implement event, and use it to link hologram display entity. unify some old tracker implementations. WIP implementation of unified player linking

This commit is contained in:
fullwall 2023-10-30 01:37:00 +08:00
parent 751e2a28ac
commit d17ca61e6e
20 changed files with 316 additions and 107 deletions

View File

@ -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<String, Integer> res = Maps.newHashMap();
for (NPC npc : npcRegistry) {

View File

@ -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()));
}
}

View File

@ -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 <em>holograms</em> 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();

View File

@ -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);
}

View File

@ -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<? extends SkinnableEntity> skinnableNPCs);
public void sendTabListRemove(Player recipient, Collection<? extends SkinnableEntity> 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);

View File

@ -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) {

View File

@ -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);
}

View File

@ -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().<Integer> 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);
}

View File

@ -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);

View File

@ -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().<Integer> 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);
}

View File

@ -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().<Integer> 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);
}

View File

@ -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().<Integer> 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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();

View File

@ -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<Pose> 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<Float> INTERACTION_HEIGHT = null;
private static EntityDataAccessor<Float> 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<Float>) NMS.getGetter(Interaction.class, "c").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
try {
DATA_POSE = (EntityDataAccessor<Pose>) NMS.getGetter(Entity.class, "ar").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
}
}

View File

@ -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;

View File

@ -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<Pose> 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<Float> INTERACTION_HEIGHT = null;
private static EntityDataAccessor<Float> 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<Boolean>) NMS.getField(EnderMan.class, "bV").get(null);
} catch (Exception e) {
e.printStackTrace();
}
try {
RABBIT_TYPE_DATAWATCHER = (EntityDataAccessor<Integer>) NMS
.getFirstStaticGetter(Rabbit.class, EntityDataAccessor.class).invoke();
} catch (Throwable e) {
e.printStackTrace();
}
try {
INTERACTION_HEIGHT = (EntityDataAccessor<Float>) NMS.getGetter(Interaction.class, "d").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
try {
INTERACTION_WIDTH = (EntityDataAccessor<Float>) NMS.getGetter(Interaction.class, "c").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
try {
DATA_POSE = (EntityDataAccessor<Pose>) NMS.getGetter(Entity.class, "as").invoke();
} catch (Throwable e) {
e.printStackTrace();
}
}
}

View File

@ -24,6 +24,7 @@ public class PlayerAnimationImpl {
playDefaultAnimation(player, radius, DEFAULTS.get(animation));
return;
}
switch (animation) {
case HURT:
sendPacketNearby(new ClientboundHurtAnimationPacket(player), player, radius);

View File

@ -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;