From 84c581dd098c783a6414efbb642df1ddb96092bd Mon Sep 17 00:00:00 2001 From: fullwall Date: Mon, 27 Mar 2023 02:52:56 +0800 Subject: [PATCH] Allow on the fly /npc trackingrange --- .../main/java/net/citizensnpcs/Citizens.java | 1 - .../main/java/net/citizensnpcs/util/NMS.java | 51 ++++++++++++------- .../java/net/citizensnpcs/util/NMSBridge.java | 2 +- .../nms/v1_10_R1/util/NMSImpl.java | 14 +++++ .../nms/v1_11_R1/util/NMSImpl.java | 14 +++++ .../nms/v1_12_R1/util/NMSImpl.java | 13 +++++ .../v1_12_R1/util/PlayerlistTrackerEntry.java | 31 +++++++---- .../nms/v1_13_R2/util/NMSImpl.java | 13 +++++ .../v1_13_R2/util/PlayerlistTrackerEntry.java | 31 +++++++---- .../nms/v1_14_R1/util/NMSImpl.java | 2 + .../nms/v1_14_R1/util/PlayerlistTracker.java | 31 +++++++---- .../nms/v1_15_R1/util/NMSImpl.java | 2 + .../nms/v1_15_R1/util/PlayerlistTracker.java | 31 +++++++---- .../nms/v1_16_R3/util/NMSImpl.java | 2 + .../nms/v1_16_R3/util/PlayerlistTracker.java | 26 +++++++--- .../nms/v1_17_R1/util/NMSImpl.java | 2 + .../nms/v1_17_R1/util/PlayerlistTracker.java | 26 +++++++--- .../nms/v1_18_R2/util/NMSImpl.java | 2 + .../nms/v1_18_R2/util/PlayerlistTracker.java | 26 +++++++--- .../entity/EnderDragonController.java | 4 +- .../nms/v1_19_R3/entity/EntityHumanNPC.java | 9 ++-- .../v1_19_R3/util/CitizensEntityTracker.java | 25 ++++++--- .../nms/v1_19_R3/util/NMSImpl.java | 24 +++++---- .../v1_8_R3/entity/EnderDragonController.java | 2 - .../nms/v1_8_R3/util/NMSImpl.java | 14 +++++ 25 files changed, 290 insertions(+), 108 deletions(-) diff --git a/main/src/main/java/net/citizensnpcs/Citizens.java b/main/src/main/java/net/citizensnpcs/Citizens.java index 2a9541a6d..419ac2571 100644 --- a/main/src/main/java/net/citizensnpcs/Citizens.java +++ b/main/src/main/java/net/citizensnpcs/Citizens.java @@ -415,7 +415,6 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { return new ShopTrait(shops); })); selector = new NPCSelector(this); - Bukkit.getPluginManager().registerEvents(new EventListen(storedRegistries), this); Bukkit.getPluginManager().registerEvents(new Placeholders(), this); Placeholders.registerNPCPlaceholder(Pattern.compile("command_[a-zA-Z_0-9]+"), (npc, sender, input) -> { diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index 3ac7cc298..a56879074 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -182,8 +182,13 @@ public class NMS { return getFinalSetter(clazz, field, true); } - public static MethodHandle getFinalSetter(Class clazz, String fieldName, boolean log) { - Field field; + public static MethodHandle getFinalSetter(Class clazz, String field, boolean log) { + return getFinalSetter(NMS.getField(clazz, field, log), log); + } + + public static MethodHandle getFinalSetter(Field field, boolean log) { + if (field == null) + return null; if (MODIFIERS_FIELD == null) { if (UNSAFE == null) { try { @@ -191,7 +196,7 @@ public class NMS { } catch (Exception e) { e.printStackTrace(); if (log) { - Messaging.logTr(Messages.ERROR_GETTING_FIELD, fieldName, e.getLocalizedMessage()); + Messaging.logTr(Messages.ERROR_GETTING_FIELD, field.getName(), e.getLocalizedMessage()); } return null; } @@ -201,34 +206,41 @@ public class NMS { .bindTo(UNSAFE); UNSAFE_PUT_OBJECT = getMethodHandle(UNSAFE.getClass(), "putObject", true, Object.class, long.class, Object.class).bindTo(UNSAFE); - } - field = NMS.getField(clazz, fieldName, log); - if (field == null) { - return null; + UNSAFE_PUT_INT = getMethodHandle(UNSAFE.getClass(), "putInt", true, Object.class, long.class, int.class) + .bindTo(UNSAFE); + UNSAFE_PUT_FLOAT = getMethodHandle(UNSAFE.getClass(), "putFloat", true, Object.class, long.class, + float.class).bindTo(UNSAFE); + UNSAFE_PUT_DOUBLE = getMethodHandle(UNSAFE.getClass(), "putDouble", true, Object.class, long.class, + double.class).bindTo(UNSAFE); + UNSAFE_PUT_BOOLEAN = getMethodHandle(UNSAFE.getClass(), "putBoolean", true, Object.class, long.class, + boolean.class).bindTo(UNSAFE); + UNSAFE_PUT_LONG = getMethodHandle(UNSAFE.getClass(), "putLong", true, Object.class, long.class, + long.class).bindTo(UNSAFE); } try { boolean isStatic = Modifier.isStatic(field.getModifiers()); long offset = (long) (isStatic ? UNSAFE_STATIC_FIELD_OFFSET.invoke(field) : UNSAFE_FIELD_OFFSET.invoke(field)); - return isStatic ? MethodHandles.insertArguments(UNSAFE_PUT_OBJECT, 0, clazz, offset) - : MethodHandles.insertArguments(UNSAFE_PUT_OBJECT, 1, offset); + MethodHandle mh = field.getType() == int.class ? UNSAFE_PUT_INT + : field.getType() == boolean.class ? UNSAFE_PUT_BOOLEAN + : field.getType() == double.class ? UNSAFE_PUT_DOUBLE + : field.getType() == float.class ? UNSAFE_PUT_FLOAT + : field.getType() == long.class ? UNSAFE_PUT_LONG : UNSAFE_PUT_OBJECT; + return isStatic ? MethodHandles.insertArguments(mh, 0, field.getDeclaringClass(), offset) + : MethodHandles.insertArguments(mh, 1, offset); } catch (Throwable t) { t.printStackTrace(); if (log) { - Messaging.logTr(Messages.ERROR_GETTING_FIELD, fieldName, t.getLocalizedMessage()); + Messaging.logTr(Messages.ERROR_GETTING_FIELD, field.getName(), t.getLocalizedMessage()); } return null; } } - field = getField(clazz, fieldName, log); - if (field == null) { - return null; - } try { MODIFIERS_FIELD.setInt(field, field.getModifiers() & ~Modifier.FINAL); } catch (Exception e) { if (log) { - Messaging.logTr(Messages.ERROR_GETTING_FIELD, fieldName, e.getLocalizedMessage()); + Messaging.logTr(Messages.ERROR_GETTING_FIELD, field.getName(), e.getLocalizedMessage()); } return null; } @@ -236,7 +248,7 @@ public class NMS { return LOOKUP.unreflectSetter(field); } catch (Exception e) { if (log) { - Messaging.logTr(Messages.ERROR_GETTING_FIELD, fieldName, e.getLocalizedMessage()); + Messaging.logTr(Messages.ERROR_GETTING_FIELD, field.getName(), e.getLocalizedMessage()); } } return null; @@ -247,7 +259,7 @@ public class NMS { List found = getFieldsMatchingType(clazz, type, false); if (found.isEmpty()) return null; - return getFinalSetter(clazz, found.get(0).getName()); + return getFinalSetter(found.get(0), true); } catch (Exception e) { Messaging.logTr(Messages.ERROR_GETTING_FIELD, type, e.getLocalizedMessage()); } @@ -774,6 +786,11 @@ public class NMS { private static Field MODIFIERS_FIELD; private static Object UNSAFE; private static MethodHandle UNSAFE_FIELD_OFFSET; + private static MethodHandle UNSAFE_PUT_BOOLEAN; + private static MethodHandle UNSAFE_PUT_DOUBLE; + private static MethodHandle UNSAFE_PUT_FLOAT; + private static MethodHandle UNSAFE_PUT_INT; + private static MethodHandle UNSAFE_PUT_LONG; private static MethodHandle UNSAFE_PUT_OBJECT; private static MethodHandle UNSAFE_STATIC_FIELD_OFFSET; diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index fc2f4c595..5736ff2e0 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -253,5 +253,5 @@ public interface NMSBridge { public void updateNavigationWorld(Entity entity, World world); - public void updatePathfindingRange(NPC npc, float pathfindingRange);; + public void updatePathfindingRange(NPC npc, float pathfindingRange); } diff --git a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java index 9bbef6949..c3e3caf9b 100644 --- a/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java +++ b/v1_10_R1/src/main/java/net/citizensnpcs/nms/v1_10_R1/util/NMSImpl.java @@ -195,6 +195,7 @@ import net.minecraft.server.v1_10_R1.ChatMessage; import net.minecraft.server.v1_10_R1.Container; import net.minecraft.server.v1_10_R1.ContainerAnvil; import net.minecraft.server.v1_10_R1.ControllerJump; +import net.minecraft.server.v1_10_R1.ControllerLook; import net.minecraft.server.v1_10_R1.ControllerMove; import net.minecraft.server.v1_10_R1.CrashReport; import net.minecraft.server.v1_10_R1.CrashReportSystemDetails; @@ -349,6 +350,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -356,6 +358,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + tracker.trackedPlayers.clear(); } }; } @@ -1845,6 +1848,14 @@ public class NMSImpl implements NMSBridge { NMSImpl.sendPacketsNearby(from, location, Arrays.asList(packets), 64); } + public static void setLookControl(EntityInsentient mob, ControllerLook control) { + try { + LOOK_CONTROL_SETTER.invoke(mob, control); + } catch (Throwable e) { + e.printStackTrace(); + } + } + public static void setSize(Entity entity, float f, float f1, boolean justCreated) { if ((f != entity.width) || (f1 != entity.length)) { float f2 = entity.width; @@ -1882,6 +1893,7 @@ public class NMSImpl implements NMSBridge { private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.SILVERFISH, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST); + private static final Field CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getField(CraftBossBar.class, "handle"); private static final float DEFAULT_SPEED = 1F; private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c"); @@ -1892,6 +1904,8 @@ public class NMSImpl implements NMSBridge { private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "be"); + private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(EntityInsentient.class, + ControllerLook.class); private static Method MAKE_REQUEST; private static MethodHandle MOVE_CONTROLLER_MOVING = NMS.getSetter(ControllerMove.class, "h"); private static Field NAVIGATION_WORLD_FIELD = NMS.getField(NavigationAbstract.class, "b"); diff --git a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java index 48c02d458..561dddd46 100644 --- a/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java +++ b/v1_11_R1/src/main/java/net/citizensnpcs/nms/v1_11_R1/util/NMSImpl.java @@ -212,6 +212,7 @@ import net.minecraft.server.v1_11_R1.ChatMessage; import net.minecraft.server.v1_11_R1.Container; import net.minecraft.server.v1_11_R1.ContainerAnvil; import net.minecraft.server.v1_11_R1.ControllerJump; +import net.minecraft.server.v1_11_R1.ControllerLook; import net.minecraft.server.v1_11_R1.ControllerMove; import net.minecraft.server.v1_11_R1.CrashReport; import net.minecraft.server.v1_11_R1.CrashReportSystemDetails; @@ -370,6 +371,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -377,6 +379,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + tracker.trackedPlayers.clear(); } }; } @@ -1906,6 +1909,14 @@ public class NMSImpl implements NMSBridge { NMSImpl.sendPacketsNearby(from, location, Arrays.asList(packets), 64); } + public static void setLookControl(EntityInsentient mob, ControllerLook control) { + try { + LOOK_CONTROL_SETTER.invoke(mob, control); + } catch (Throwable e) { + e.printStackTrace(); + } + } + public static void setSize(Entity entity, float f, float f1, boolean justCreated) { if ((f != entity.width) || (f1 != entity.length)) { float f2 = entity.width; @@ -1943,6 +1954,7 @@ public class NMSImpl implements NMSBridge { private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.SILVERFISH, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST); + private static final Field CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getField(CraftBossBar.class, "handle"); private static final float DEFAULT_SPEED = 1F; private static final Field ENDERDRAGON_BATTLE_BAR_FIELD = NMS.getField(EnderDragonBattle.class, "c"); @@ -1952,6 +1964,8 @@ public class NMSImpl implements NMSBridge { private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "bd"); + private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(EntityInsentient.class, + ControllerLook.class); private static Method MAKE_REQUEST; private static MethodHandle MOVE_CONTROLLER_MOVING = NMS.getSetter(ControllerMove.class, "h"); private static Field NAVIGATION_WORLD_FIELD = NMS.getField(NavigationAbstract.class, "b"); diff --git a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java index dcfa3a1e9..68fc809ce 100644 --- a/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java +++ b/v1_12_R1/src/main/java/net/citizensnpcs/nms/v1_12_R1/util/NMSImpl.java @@ -215,6 +215,7 @@ import net.minecraft.server.v1_12_R1.ChatMessage; import net.minecraft.server.v1_12_R1.Container; import net.minecraft.server.v1_12_R1.ContainerAnvil; import net.minecraft.server.v1_12_R1.ControllerJump; +import net.minecraft.server.v1_12_R1.ControllerLook; import net.minecraft.server.v1_12_R1.ControllerMove; import net.minecraft.server.v1_12_R1.CrashReport; import net.minecraft.server.v1_12_R1.CrashReportSystemDetails; @@ -375,6 +376,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -382,6 +384,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + tracker.trackedPlayers.clear(); } }; } @@ -1913,6 +1916,14 @@ public class NMSImpl implements NMSBridge { NMSImpl.sendPacketsNearby(from, location, Arrays.asList(packets), 64); } + public static void setLookControl(EntityInsentient mob, ControllerLook control) { + try { + LOOK_CONTROL_SETTER.invoke(mob, control); + } catch (Throwable e) { + e.printStackTrace(); + } + } + public static void setSize(Entity entity, float f, float f1, boolean justCreated) { if ((f != entity.width) || (f1 != entity.length)) { float f2 = entity.width; @@ -1960,6 +1971,8 @@ public class NMSImpl implements NMSBridge { private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "bd"); + private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(EntityInsentient.class, + ControllerLook.class); private static Method MAKE_REQUEST; private static MethodHandle MOVE_CONTROLLER_MOVING = NMS.getSetter(ControllerMove.class, "h"); private static Field NAVIGATION_WORLD_FIELD = NMS.getField(NavigationAbstract.class, "b"); 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 9f7b59ed6..f9743deab 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 @@ -1,5 +1,6 @@ package net.citizensnpcs.nms.v1_12_R1.util; +import java.lang.invoke.MethodHandle; import java.lang.reflect.Field; import org.bukkit.Bukkit; @@ -14,6 +15,7 @@ import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; import net.minecraft.server.v1_12_R1.Entity; import net.minecraft.server.v1_12_R1.EntityPlayer; +import net.minecraft.server.v1_12_R1.EntityTracker; import net.minecraft.server.v1_12_R1.EntityTrackerEntry; public class PlayerlistTrackerEntry extends EntityTrackerEntry { @@ -52,21 +54,31 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - // prevent updates to NPC "viewers" - if ((entityplayer instanceof EntityHumanNPC) || (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity()))) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + if (entityplayer instanceof EntityHumanNPC) return; - lastUpdatedPlayer = entityplayer; + + this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); - lastUpdatedPlayer = null; } private static int getE(EntityTrackerEntry entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, (Integer) E.get(entry)); - } return (Integer) E.get(entry); } catch (IllegalArgumentException e) { e.printStackTrace(); @@ -124,5 +136,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { 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 final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class); private static Field U = NMS.getField(EntityTrackerEntry.class, "u"); } diff --git a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java index 3eeb86a01..b0400f4ab 100644 --- a/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java +++ b/v1_13_R2/src/main/java/net/citizensnpcs/nms/v1_13_R2/util/NMSImpl.java @@ -228,6 +228,7 @@ import net.minecraft.server.v1_13_R2.ChatMessage; import net.minecraft.server.v1_13_R2.Container; import net.minecraft.server.v1_13_R2.ContainerAnvil; import net.minecraft.server.v1_13_R2.ControllerJump; +import net.minecraft.server.v1_13_R2.ControllerLook; import net.minecraft.server.v1_13_R2.ControllerMove; import net.minecraft.server.v1_13_R2.CrashReport; import net.minecraft.server.v1_13_R2.CrashReportSystemDetails; @@ -396,6 +397,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -403,6 +405,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + tracker.trackedPlayers.clear(); } }; } @@ -2047,6 +2050,14 @@ public class NMSImpl implements NMSBridge { NMSImpl.sendPacketsNearby(from, location, Arrays.asList(packets), 64); } + public static void setLookControl(EntityInsentient mob, ControllerLook control) { + try { + LOOK_CONTROL_SETTER.invoke(mob, control); + } catch (Throwable e) { + e.printStackTrace(); + } + } + public static void setNotInSchool(EntityFish entity) { try { if (ENTITY_FISH_NUM_IN_SCHOOL != null) { @@ -2111,6 +2122,8 @@ public class NMSImpl implements NMSBridge { private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); public static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "bg"); + private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(EntityInsentient.class, + ControllerLook.class); private static Method MAKE_REQUEST; private static MethodHandle MOVE_CONTROLLER_MOVING = NMS.getSetter(ControllerMove.class, "h"); private static Field NAVIGATION_WORLD_FIELD = NMS.getField(NavigationAbstract.class, "b"); 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 d4fd28acd..e60aea7d3 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 @@ -1,5 +1,6 @@ package net.citizensnpcs.nms.v1_13_R2.util; +import java.lang.invoke.MethodHandle; import java.lang.reflect.Field; import org.bukkit.Bukkit; @@ -14,6 +15,7 @@ import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; import net.minecraft.server.v1_13_R2.Entity; import net.minecraft.server.v1_13_R2.EntityPlayer; +import net.minecraft.server.v1_13_R2.EntityTracker; import net.minecraft.server.v1_13_R2.EntityTrackerEntry; public class PlayerlistTrackerEntry extends EntityTrackerEntry { @@ -51,21 +53,31 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { @Override public void updatePlayer(final EntityPlayer entityplayer) { - // prevent updates to NPC "viewers" - if ((entityplayer instanceof EntityHumanNPC) || (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity()))) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + if (entityplayer instanceof EntityHumanNPC) return; - lastUpdatedPlayer = entityplayer; + + this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); - lastUpdatedPlayer = null; } private static int getE(EntityTrackerEntry entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, (Integer) E.get(entry)); - } return (Integer) E.get(entry); } catch (IllegalArgumentException e) { e.printStackTrace(); @@ -123,5 +135,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { 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 final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class); private static Field U = NMS.getField(EntityTrackerEntry.class, "u"); } diff --git a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java index 1cc359ab7..c1f2c2a2d 100644 --- a/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java +++ b/v1_14_R1/src/main/java/net/citizensnpcs/nms/v1_14_R1/util/NMSImpl.java @@ -436,6 +436,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(linked)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -443,6 +444,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + linked.clear(); } }; } 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 0b3cd6e96..c146ce029 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 @@ -48,14 +48,27 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!(entityplayer instanceof EntityHumanNPC)) { - // prevent updates to NPC "viewers" - if (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity())) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) return; - lastUpdatedPlayer = entityplayer; - super.updatePlayer(entityplayer); + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } } + + if (entityplayer instanceof EntityHumanNPC) + return; + + this.lastUpdatedPlayer = entityplayer; + super.updatePlayer(entityplayer); } private static int getD(EntityTracker entry) { @@ -87,11 +100,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { private static int getTrackingDistance(EntityTracker entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, - (Integer) TRACKING_RANGE.invoke(entry)); - } return (Integer) TRACKING_RANGE.invoke(entry); } catch (Throwable e) { e.printStackTrace(); @@ -104,4 +112,5 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { private static final MethodHandle TRACKER = NMS.getGetter(EntityTracker.class, "tracker"); private static final MethodHandle TRACKER_ENTRY = NMS.getGetter(EntityTracker.class, "trackerEntry"); private static final MethodHandle TRACKING_RANGE = NMS.getGetter(EntityTracker.class, "trackingDistance"); + private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class); } diff --git a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java index dcbb72799..5ae809392 100644 --- a/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java +++ b/v1_15_R1/src/main/java/net/citizensnpcs/nms/v1_15_R1/util/NMSImpl.java @@ -451,6 +451,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(linked)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -458,6 +459,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + linked.clear(); } }; } 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 195707a98..4fc2937b5 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 @@ -48,14 +48,27 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if (!(entityplayer instanceof EntityHumanNPC)) { - if (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity())) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) return; - // prevent updates to NPC "viewers" - this.lastUpdatedPlayer = entityplayer; - super.updatePlayer(entityplayer); + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } } + + if (entityplayer instanceof EntityHumanNPC) + return; + + this.lastUpdatedPlayer = entityplayer; + super.updatePlayer(entityplayer); } private static int getD(EntityTracker entry) { @@ -87,11 +100,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { private static int getTrackingDistance(EntityTracker entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, - (Integer) TRACKING_RANGE.invoke(entry)); - } return (Integer) TRACKING_RANGE.invoke(entry); } catch (Throwable e) { e.printStackTrace(); @@ -104,4 +112,5 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { private static final MethodHandle TRACKER = NMS.getGetter(EntityTracker.class, "tracker"); private static final MethodHandle TRACKER_ENTRY = NMS.getGetter(EntityTracker.class, "trackerEntry"); private static final MethodHandle TRACKING_RANGE = NMS.getGetter(EntityTracker.class, "trackingDistance"); + private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class); } diff --git a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java index 09709eb75..74d17aa47 100644 --- a/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java +++ b/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/util/NMSImpl.java @@ -465,6 +465,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(linked)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -472,6 +473,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + linked.clear(); } }; } 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 c1ff96d5b..b35e932d4 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 @@ -50,9 +50,25 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { @Override public void updatePlayer(final EntityPlayer entityplayer) { - if ((entityplayer instanceof EntityHumanNPC) || (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity()))) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + if (entityplayer instanceof EntityHumanNPC) return; + this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); } @@ -86,11 +102,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { private static int getTrackingDistance(EntityTracker entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, - (Integer) TRACKING_RANGE.invoke(entry)); - } return (Integer) TRACKING_RANGE.invoke(entry); } catch (Throwable e) { e.printStackTrace(); @@ -103,4 +114,5 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { private static final MethodHandle TRACKER = NMS.getGetter(EntityTracker.class, "tracker"); private static final MethodHandle TRACKER_ENTRY = NMS.getGetter(EntityTracker.class, "trackerEntry"); private static final MethodHandle TRACKING_RANGE = NMS.getGetter(EntityTracker.class, "trackingDistance"); + private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class); } diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java index 3aed06806..a6b4a6719 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/NMSImpl.java @@ -478,6 +478,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.remove(RemovalReason.KILLED); for (ServerPlayerConnection link : Lists.newArrayList(linked)) { Player entity = link.getPlayer().getBukkitEntity(); unlink(entity); @@ -485,6 +486,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + linked.clear(); } }; } 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 564141ecc..75fed751d 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 @@ -51,9 +51,25 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { @Override public void updatePlayer(final ServerPlayer entityplayer) { - if ((entityplayer instanceof EntityHumanNPC) || (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity()))) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + if (entityplayer instanceof EntityHumanNPC) return; + this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); } @@ -87,11 +103,6 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { private static int getTrackingDistance(TrackedEntity entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, - (Integer) TRACKING_RANGE.invoke(entry)); - } return (Integer) TRACKING_RANGE.invoke(entry); } catch (Throwable e) { e.printStackTrace(); @@ -104,4 +115,5 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class); private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class); private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class); + private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, int.class); } diff --git a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java index 0abc97f13..ac4be54c6 100644 --- a/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java +++ b/v1_18_R2/src/main/java/net/citizensnpcs/nms/v1_18_R2/util/NMSImpl.java @@ -484,6 +484,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.remove(RemovalReason.KILLED); for (ServerPlayerConnection link : Lists.newArrayList(linked)) { Player entity = link.getPlayer().getBukkitEntity(); unlink(entity); @@ -491,6 +492,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + linked.clear(); } }; } 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 3ed9bdc15..8411b4ba4 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 @@ -51,9 +51,25 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { @Override public void updatePlayer(final ServerPlayer entityplayer) { - if ((entityplayer instanceof EntityHumanNPC) || (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity()))) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + if (entityplayer instanceof EntityHumanNPC) return; + this.lastUpdatedPlayer = entityplayer; super.updatePlayer(entityplayer); } @@ -87,11 +103,6 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { private static int getTrackingDistance(TrackedEntity entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, - (Integer) TRACKING_RANGE.invoke(entry)); - } return (Integer) TRACKING_RANGE.invoke(entry); } catch (Throwable e) { e.printStackTrace(); @@ -104,4 +115,5 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class); private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class); private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class); + private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, int.class); } diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EnderDragonController.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EnderDragonController.java index 2c1515a72..b1438f078 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EnderDragonController.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EnderDragonController.java @@ -61,8 +61,8 @@ public class EnderDragonController extends MobEntityController { @Override public void aiStep() { if (npc != null) { - npc.update(); NMSImpl.updateMinecraftAIState(npc, this); + npc.update(); } if (npc != null && !npc.useMinecraftAI()) { if (getFirstPassenger() != null) { @@ -97,8 +97,6 @@ public class EnderDragonController extends MobEntityController { } } - - @Override protected SoundEvent getAmbientSound() { return NMSImpl.getSoundEffect(npc, super.getAmbientSound(), NPC.Metadata.AMBIENT_SOUND); diff --git a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java index 312f048cd..06fa2cb42 100644 --- a/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java +++ b/v1_19_R3/src/main/java/net/citizensnpcs/nms/v1_19_R3/entity/EntityHumanNPC.java @@ -117,12 +117,9 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable return; } super.die(damagesource); - Bukkit.getScheduler().runTaskLater(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - EntityHumanNPC.this.getLevel().removePlayerImmediately(EntityHumanNPC.this, RemovalReason.KILLED); - ((ServerLevel) level).getChunkSource().removeEntity(EntityHumanNPC.this); - } + Bukkit.getScheduler().runTaskLater(CitizensAPI.getPlugin(), () -> { + EntityHumanNPC.this.getLevel().removePlayerImmediately(EntityHumanNPC.this, RemovalReason.KILLED); + ((ServerLevel) level).getChunkSource().removeEntity(EntityHumanNPC.this); }, 15); // give enough time for death and smoke animation } 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 d7a528584..e0ea54871 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 @@ -75,8 +75,23 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { @Override public void updatePlayer(final ServerPlayer entityplayer) { - if ((entityplayer instanceof EntityHumanNPC) || (tracker instanceof NPCHolder - && ((NPCHolder) tracker).getNPC().isHiddenFrom(entityplayer.getBukkitEntity()))) + if (tracker instanceof NPCHolder) { + NPC npc = ((NPCHolder) tracker).getNPC(); + if (npc.isHiddenFrom(entityplayer.getBukkitEntity())) + 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()) { + try { + TRACKING_RANGE_SETTER.invoke(this, trackingRange); + npc.data().set("last-tracking-range", trackingRange); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + if (entityplayer instanceof EntityHumanNPC) return; this.lastUpdatedPlayer = entityplayer; @@ -112,11 +127,6 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { private static int getTrackingDistance(TrackedEntity entry) { try { - Entity entity = getTracker(entry); - if (entity instanceof NPCHolder) { - return ((NPCHolder) entity).getNPC().data().get(NPC.Metadata.TRACKING_RANGE, - (Integer) TRACKING_RANGE.invoke(entry)); - } return (Integer) TRACKING_RANGE.invoke(entry); } catch (Throwable e) { e.printStackTrace(); @@ -129,6 +139,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { private static final MethodHandle TRACKER = NMS.getFirstGetter(TrackedEntity.class, Entity.class); private static final MethodHandle TRACKER_ENTRY = NMS.getFirstGetter(TrackedEntity.class, ServerEntity.class); private static final MethodHandle TRACKING_RANGE = NMS.getFirstGetter(TrackedEntity.class, int.class); + private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, int.class); private static final MethodHandle TRACKING_SET_GETTER = NMS.getFirstGetter(TrackedEntity.class, Set.class); private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(TrackedEntity.class, Set.class); } 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 747a19afa..8e5999283 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 @@ -508,6 +508,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.remove(RemovalReason.KILLED); for (ServerPlayerConnection link : Lists.newArrayList(linked)) { Player entity = link.getPlayer().getBukkitEntity(); unlink(entity); @@ -515,6 +516,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + linked.clear(); } }; } @@ -2288,7 +2290,7 @@ public class NMSImpl implements NMSBridge { public static void setAdvancement(Player entity, PlayerAdvancements instance) { try { - ADVANCEMENTS_PLAYER_FIELD.invoke(getHandle(entity), instance); + ADVANCEMENTS_PLAYER_SETTER.invoke(getHandle(entity), instance); } catch (Throwable e) { e.printStackTrace(); } @@ -2452,10 +2454,11 @@ public class NMSImpl implements NMSBridge { } } - private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFirstFinalSetter(ServerPlayer.class, + private static final MethodHandle ADVANCEMENTS_PLAYER_SETTER = NMS.getFirstFinalSetter(ServerPlayer.class, PlayerAdvancements.class); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getFirstGetter(AttributeSupplier.class, Map.class); - private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeSupplier.class, "a"); + private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFirstFinalSetter(AttributeSupplier.class, + Map.class); private static final MethodHandle ATTRIBUTE_SUPPLIER = NMS.getFirstGetter(AttributeMap.class, AttributeSupplier.class); private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.BEE, @@ -2468,7 +2471,8 @@ public class NMSImpl implements NMSBridge { ServerPlayer.class, boolean.class); private static final Map, net.minecraft.world.entity.EntityType> CITIZENS_ENTITY_TYPES = Maps .newHashMap(); - private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getSetter(CraftBossBar.class, "handle"); + private static final MethodHandle CRAFT_BOSSBAR_HANDLE_FIELD = NMS.getFirstSetter(CraftBossBar.class, + ServerBossEvent.class); private static final float DEFAULT_SPEED = 1F; private static EntityDataAccessor ENDERMAN_CREEPY = null; private static final MethodHandle ENTITY_FISH_NUM_IN_SCHOOL = NMS.getFirstSetter(AbstractSchoolingFish.class, @@ -2501,10 +2505,12 @@ public class NMSImpl implements NMSBridge { PathFinder.class); private static final MethodHandle NAVIGATION_WORLD_FIELD = NMS.getFirstSetter(PathNavigation.class, Level.class); private static final Location PACKET_CACHE_LOCATION = new Location(null, 0, 0, 0); - private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_GETTER = NMS.getGetter(ChunkMap.class, "P"); - private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_SETTER = NMS.getSetter(ChunkMap.class, "P"); + private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_GETTER = NMS.getFirstGetter(ChunkMap.class, + int.class); + private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_SETTER = NMS.getFirstSetter(ChunkMap.class, + int.class); private static final MethodHandle PLAYER_INFO_ENTRIES_LIST = NMS - .getFinalSetter(ClientboundPlayerInfoUpdatePacket.class, "b"); + .getFirstFinalSetter(ClientboundPlayerInfoUpdatePacket.class, List.class); private static final MethodHandle PLAYERINFO_ENTRIES = PLAYER_INFO_ENTRIES_LIST; private static MethodHandle PORTAL_ENTRANCE_POS_GETTER = NMS.getGetter(Entity.class, "aw"); private static MethodHandle PORTAL_ENTRANCE_POS_SETTER = NMS.getSetter(Entity.class, "aw"); @@ -2529,9 +2535,7 @@ public class NMSImpl implements NMSBridge { try { // Middle one ENDERMAN_CREEPY = (EntityDataAccessor) NMS.getField(EnderMan.class, "bU").get(null); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { + } catch (Exception e) { e.printStackTrace(); } try { diff --git a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/entity/EnderDragonController.java b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/entity/EnderDragonController.java index 6240184ab..23bd58e75 100644 --- a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/entity/EnderDragonController.java +++ b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/entity/EnderDragonController.java @@ -108,8 +108,6 @@ public class EnderDragonController extends MobEntityController { } } - - @Override public void g(double x, double y, double z) { Vector vector = Util.callPushEvent(npc, x, y, z); diff --git a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java index a0ab26314..7bb5a4be9 100644 --- a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java +++ b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/NMSImpl.java @@ -178,6 +178,7 @@ import net.minecraft.server.v1_8_R3.ChatMessage; import net.minecraft.server.v1_8_R3.Container; import net.minecraft.server.v1_8_R3.ContainerAnvil; import net.minecraft.server.v1_8_R3.ControllerJump; +import net.minecraft.server.v1_8_R3.ControllerLook; import net.minecraft.server.v1_8_R3.ControllerMove; import net.minecraft.server.v1_8_R3.CrashReport; import net.minecraft.server.v1_8_R3.CrashReportSystemDetails; @@ -329,6 +330,7 @@ public class NMSImpl implements NMSBridge { @Override public void unlinkAll(Consumer callback) { + handle.die(); for (EntityPlayer link : Lists.newArrayList(tracker.trackedPlayers)) { Player entity = link.getBukkitEntity(); unlink(entity); @@ -336,6 +338,7 @@ public class NMSImpl implements NMSBridge { callback.accept(entity); } } + tracker.trackedPlayers.clear(); } }; } @@ -1704,6 +1707,14 @@ public class NMSImpl implements NMSBridge { NMSImpl.sendPacketsNearby(from, location, Arrays.asList(packets), 64); } + public static void setLookControl(EntityInsentient mob, ControllerLook control) { + try { + LOOK_CONTROL_SETTER.invoke(mob, control); + } catch (Throwable e) { + e.printStackTrace(); + } + } + public static void setSize(Entity entity, float f, float f1, boolean justCreated) { if ((f != entity.width) || (f1 != entity.length)) { float f2 = entity.width; @@ -1741,6 +1752,7 @@ public class NMSImpl implements NMSBridge { private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.SILVERFISH, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST); + private static final float DEFAULT_SPEED = 1F; private static Method ENTITY_ATTACK_A = NMS.getMethod(Entity.class, "a", true, EntityLiving.class, Entity.class); private static Map, Integer> ENTITY_CLASS_TO_INT; @@ -1749,6 +1761,8 @@ public class NMSImpl implements NMSBridge { private static Method GET_NMS_BLOCK = NMS.getMethod(CraftBlock.class, "getNMSBlock", false); private static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b"); private static final Field JUMP_FIELD = NMS.getField(EntityLiving.class, "aY"); + private static final MethodHandle LOOK_CONTROL_SETTER = NMS.getFirstSetter(EntityInsentient.class, + ControllerLook.class); private static Method MAKE_REQUEST; private static Field MOVE_CONTROLLER_MOVING = NMS.getField(ControllerMove.class, "f"); private static Field NAVIGATION_WORLD_FIELD = NMS.getField(NavigationAbstract.class, "c");