diff --git a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 60b3f0ad7..199a0ae7a 100644 --- a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -1422,7 +1422,7 @@ public class NPCCommands { @Command( aliases = { "npc" }, - usage = "lookclose --range [range] -r[ealistic looking] --randomlook [true|false] --randomswitchtargets [true|false] --randompitchrange [min,max] --randomyawrange [min,max] --disablewhennavigating [true|false] --targetnpcs [true|false]", + usage = "lookclose --range [range] -r[ealistic looking] --randomlook [true|false] --perplayer [true|false] --randomswitchtargets [true|false] --randompitchrange [min,max] --randomyawrange [min,max] --disablewhennavigating [true|false] --targetnpcs [true|false]", desc = "Toggle whether a NPC will look when a player is near", modifiers = { "lookclose", "look" }, min = 1, @@ -2448,7 +2448,7 @@ public class NPCCommands { if (yaw != null) { NMS.setBodyYaw(npc.getEntity(), yaw); if (npc.getEntity().getType() == EntityType.PLAYER) { - PlayerAnimation.ARM_SWING.play((Player) npc.getEntity()); + NMS.sendPositionUpdate(npc.getEntity(), false, yaw, npc.getStoredLocation().getPitch(), null); } } if (pitch != null) { diff --git a/main/src/main/java/net/citizensnpcs/trait/RotationTrait.java b/main/src/main/java/net/citizensnpcs/trait/RotationTrait.java index a6fdf49a5..48328a716 100644 --- a/main/src/main/java/net/citizensnpcs/trait/RotationTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/RotationTrait.java @@ -139,6 +139,9 @@ public class RotationTrait extends Trait { NMS.setBodyYaw(entity, bodyYaw); NMS.setHeadYaw(entity, headYaw); NMS.setPitch(entity, pitch); + if (entity instanceof Player) { + NMS.sendPositionUpdate(entity, true, bodyYaw, pitch, headYaw); + } } } @@ -209,7 +212,7 @@ public class RotationTrait extends Trait { @Override public void apply() { if (Math.abs(lastBodyYaw - bodyYaw) + Math.abs(lastHeadYaw - headYaw) + Math.abs(pitch - lastPitch) > 1) { - NMS.sendRotationNearby(entity, bodyYaw, headYaw, pitch); + NMS.sendPositionUpdate(entity, true, bodyYaw, pitch, headYaw); } } diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index efc405d9c..96f09c255 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -645,12 +645,8 @@ public class NMS { BRIDGE.replaceTrackerEntry(entity); } - public static void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location location) { - BRIDGE.sendPositionUpdate(excluding, from, location); - } - - public static void sendRotationNearby(Entity entity, float bodyYaw, float headYaw, float pitch) { - BRIDGE.sendRotationNearby(entity, bodyYaw, headYaw, pitch); + public static void sendPositionUpdate(Entity from, boolean position, Float bodyYaw, Float pitch, Float headYaw) { + BRIDGE.sendPositionUpdate(from, position, bodyYaw, pitch, headYaw); } public static boolean sendTabListAdd(Player recipient, Player listPlayer) { diff --git a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java index 1f38c5781..e42a5fd56 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMSBridge.java +++ b/main/src/main/java/net/citizensnpcs/util/NMSBridge.java @@ -156,9 +156,7 @@ public interface NMSBridge { public void replaceTrackerEntry(Entity entity); - public void sendPositionUpdate(Player excluding, Entity from, Location location); - - public void sendRotationNearby(Entity from, float bodyYaw, float headYaw, float pitch); + public void sendPositionUpdate(Entity from, boolean position, Float bodyYaw, Float pitch, Float headYaw); public boolean sendTabListAdd(Player recipient, Player listPlayer); 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 b4fe41533..2a4b2a596 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 @@ -234,6 +234,8 @@ import net.minecraft.server.v1_10_R1.NetworkManager; import net.minecraft.server.v1_10_R1.Packet; import net.minecraft.server.v1_10_R1.PacketPlayOutAnimation; import net.minecraft.server.v1_10_R1.PacketPlayOutBed; +import net.minecraft.server.v1_10_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_10_R1.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_10_R1.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_10_R1.PacketPlayOutEntityHeadRotation; import net.minecraft.server.v1_10_R1.PacketPlayOutEntityTeleport; @@ -1094,22 +1096,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTrackerEntry entry = ((WorldServer) handle.world).getTracker().trackedEntities.get(handle.getId()); + long dx, dy, dz; + try { + dx = EntityTracker.a(handle.locX) - (long) ENTITY_TRACKER_ENTRY_X.invoke(entry); + dy = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Y.invoke(entry); + dz = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Z.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) dx, (short) dy, (short) dz, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -1940,14 +1957,20 @@ public class NMSImpl implements NMSBridge { 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"); + private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bK"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); private static DataWatcherObject ENDERMAN_ANGRY; private static Map, Integer> ENTITY_CLASS_TO_INT; private static Map, String> ENTITY_CLASS_TO_NAME; + private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Z = NMS.getGetter(EntityTrackerEntry.class, "zLoc"); 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"); 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 f7fab4d1e..99d61d9cb 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 @@ -254,6 +254,8 @@ import net.minecraft.server.v1_11_R1.NetworkManager; import net.minecraft.server.v1_11_R1.Packet; import net.minecraft.server.v1_11_R1.PacketPlayOutAnimation; import net.minecraft.server.v1_11_R1.PacketPlayOutBed; +import net.minecraft.server.v1_11_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_11_R1.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_11_R1.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_11_R1.PacketPlayOutEntityHeadRotation; import net.minecraft.server.v1_11_R1.PacketPlayOutEntityTeleport; @@ -1147,22 +1149,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTrackerEntry entry = ((WorldServer) handle.world).getTracker().trackedEntities.get(handle.getId()); + long dx, dy, dz; + try { + dx = EntityTracker.a(handle.locX) - (long) ENTITY_TRACKER_ENTRY_X.invoke(entry); + dy = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Y.invoke(entry); + dz = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Z.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) dx, (short) dy, (short) dz, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -1998,14 +2015,20 @@ 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"); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bJ"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); private static DataWatcherObject ENDERMAN_ANGRY; private static CustomEntityRegistry ENTITY_REGISTRY; + private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Z = NMS.getGetter(EntityTrackerEntry.class, "zLoc"); 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"); 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 e48dc55df..258b81c03 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 @@ -258,6 +258,8 @@ import net.minecraft.server.v1_12_R1.NetworkManager; import net.minecraft.server.v1_12_R1.Packet; import net.minecraft.server.v1_12_R1.PacketPlayOutAnimation; import net.minecraft.server.v1_12_R1.PacketPlayOutBed; +import net.minecraft.server.v1_12_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_12_R1.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_12_R1.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_12_R1.PacketPlayOutEntityHeadRotation; import net.minecraft.server.v1_12_R1.PacketPlayOutEntityTeleport; @@ -1154,22 +1156,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTrackerEntry entry = ((WorldServer) handle.world).getTracker().trackedEntities.get(handle.getId()); + long dx, dy, dz; + try { + dx = EntityTracker.a(handle.locX) - (long) ENTITY_TRACKER_ENTRY_X.invoke(entry); + dy = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Y.invoke(entry); + dz = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Z.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) dx, (short) dy, (short) dz, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2005,14 +2022,20 @@ public class NMSImpl implements NMSBridge { private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.SILVERFISH, EntityType.SHULKER, 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"); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bK"); public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); private static DataWatcherObject ENDERMAN_ANGRY; private static CustomEntityRegistry ENTITY_REGISTRY; + private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Z = NMS.getGetter(EntityTrackerEntry.class, "zLoc"); 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"); 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 374c1f1b7..4d419be7a 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 @@ -45,12 +45,9 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { lastUpdatedPlayer = null; if (!Setting.DISABLE_TABLIST.asBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - } - }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), + Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } @Override 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 507ae5736..1496f47c7 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 @@ -277,6 +277,7 @@ import net.minecraft.server.v1_13_R2.Packet; import net.minecraft.server.v1_13_R2.PacketPlayOutAnimation; import net.minecraft.server.v1_13_R2.PacketPlayOutBed; import net.minecraft.server.v1_13_R2.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_13_R2.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_13_R2.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_13_R2.PacketPlayOutEntityHeadRotation; import net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport; @@ -1197,18 +1198,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - Packet[] packets = new Packet[] { - new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), - (byte) (pitch * 256.0F / 360.0F), isOnGround(from)), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTrackerEntry entry = ((WorldServer) handle.world).getTracker().trackedEntities.get(handle.getId()); + long dx, dy, dz; + try { + dx = EntityTracker.a(handle.locX) - (long) ENTITY_TRACKER_ENTRY_X.invoke(entry); + dy = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Y.invoke(entry); + dz = EntityTracker.a(handle.locY) - (long) ENTITY_TRACKER_ENTRY_Z.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) dx, (short) dy, (short) dz, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2149,13 +2169,17 @@ public class NMSImpl implements NMSBridge { } private static MethodHandle ADVANCEMENT_PLAYER_FIELD = NMS.getFinalSetter(EntityPlayer.class, "cf"); + private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, EntityType.SHULKER, EntityType.PHANTOM); + private static final Method BLOCK_POSITION_B_D = NMS.getMethod(BlockPosition.PooledBlockPosition.class, "e", false, double.class, double.class, double.class); + 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", false); private static final Field ENDERDRAGON_BATTLE_FIELD = NMS.getField(EntityEnderDragon.class, "bR"); @@ -2165,6 +2189,9 @@ public class NMSImpl implements NMSBridge { private static Method ENTITY_FISH_METHOD = NMS.getMethod(EntityFish.class, "t", false, boolean.class); private static Field ENTITY_FISH_NUM_IN_SCHOOL; private static CustomEntityRegistry ENTITY_REGISTRY; + private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Z = NMS.getGetter(EntityTrackerEntry.class, "zLoc"); 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"); 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 6b28ba846..93a03f02c 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 @@ -44,12 +44,9 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { lastUpdatedPlayer = null; if (!Setting.DISABLE_TABLIST.asBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - } - }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), + Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } @Override 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 d460d5cc1..e33c14465 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 @@ -291,9 +291,10 @@ import net.minecraft.server.v1_14_R1.MobEffects; import net.minecraft.server.v1_14_R1.NavigationAbstract; import net.minecraft.server.v1_14_R1.NetworkManager; import net.minecraft.server.v1_14_R1.Packet; +import net.minecraft.server.v1_14_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_14_R1.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_14_R1.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_14_R1.PacketPlayOutEntityHeadRotation; -import net.minecraft.server.v1_14_R1.PacketPlayOutEntityTeleport; import net.minecraft.server.v1_14_R1.PacketPlayOutOpenWindow; import net.minecraft.server.v1_14_R1.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_14_R1.PacketPlayOutScoreboardTeam; @@ -1213,22 +1214,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTracker entry = ((WorldServer) handle.world).getChunkProvider().playerChunkMap.trackedEntities + .get(handle.getId()); + EntityTrackerEntry ete = null; + try { + ete = (EntityTrackerEntry) ENTITY_TRACKER_ENTRY_GETTER.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + Vec3D pos = handle.getPositionVector().d(ete.b()); + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) pos.x, (short) pos.y, (short) pos.z, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2224,6 +2240,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENT_PLAYER_FIELD = NMS.getFinalSetter(EntityPlayer.class, "advancementDataPlayer"); + private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, EntityType.SHULKER, @@ -2250,6 +2267,8 @@ public class NMSImpl implements NMSBridge { EntityPose.class); private static final MethodHandle ENTITY_SETPOSE_METHOD = NMS.getMethodHandle(Entity.class, "setPose", true, EntityPose.class); + private static final MethodHandle ENTITY_TRACKER_ENTRY_GETTER = NMS.getFirstGetter(EntityTracker.class, + EntityTrackerEntry.class); private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); private static final MethodHandle GOAL_FIELD = NMS.getGetter(PathfinderGoalSelector.class, "d"); private static final MethodHandle HEAD_HEIGHT = NMS.getSetter(Entity.class, "headHeight"); 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 f84b6d697..4b2ba982c 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 @@ -39,12 +39,9 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); if (!Setting.DISABLE_TABLIST.asBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - } - }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), + Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } @Override 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 e9b85331a..0ffa0986f 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 @@ -296,9 +296,10 @@ import net.minecraft.server.v1_15_R1.MobEffects; import net.minecraft.server.v1_15_R1.NavigationAbstract; import net.minecraft.server.v1_15_R1.NetworkManager; import net.minecraft.server.v1_15_R1.Packet; +import net.minecraft.server.v1_15_R1.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_15_R1.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_15_R1.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_15_R1.PacketPlayOutEntityHeadRotation; -import net.minecraft.server.v1_15_R1.PacketPlayOutEntityTeleport; import net.minecraft.server.v1_15_R1.PacketPlayOutOpenWindow; import net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_15_R1.PacketPlayOutScoreboardTeam; @@ -1230,22 +1231,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTracker entry = ((WorldServer) handle.world).getChunkProvider().playerChunkMap.trackedEntities + .get(handle.getId()); + EntityTrackerEntry ete = null; + try { + ete = (EntityTrackerEntry) ENTITY_TRACKER_ENTRY_GETTER.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + Vec3D pos = handle.getPositionVector().d(ete.b()); + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) pos.x, (short) pos.y, (short) pos.z, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2309,6 +2325,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENT_PLAYER_FIELD = NMS.getFinalSetter(EntityPlayer.class, "advancementDataPlayer"); + private static final Set BAD_CONTROLLER_LOOK = EnumSet.of(EntityType.POLAR_BEAR, EntityType.BEE, EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, @@ -2333,6 +2350,8 @@ public class NMSImpl implements NMSBridge { EntityPose.class); private static final MethodHandle ENTITY_SETPOSE_METHOD = NMS.getMethodHandle(Entity.class, "setPose", true, EntityPose.class); + private static final MethodHandle ENTITY_TRACKER_ENTRY_GETTER = NMS.getFirstGetter(EntityTracker.class, + EntityTrackerEntry.class); private static final MethodHandle FLYING_MOVECONTROL_FLOAT_GETTER = NMS.getFirstGetter(ControllerMoveFlying.class, boolean.class); private static final MethodHandle FLYING_MOVECONTROL_FLOAT_SETTER = NMS.getFirstSetter(ControllerMoveFlying.class, 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 5a22c326e..f45fc7ae5 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 @@ -39,12 +39,9 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); if (!Setting.DISABLE_TABLIST.asBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - } - }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), + Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } @Override 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 fa49503fd..5d38d8553 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 @@ -309,9 +309,10 @@ import net.minecraft.server.v1_16_R3.MobEffects; import net.minecraft.server.v1_16_R3.NavigationAbstract; import net.minecraft.server.v1_16_R3.NetworkManager; import net.minecraft.server.v1_16_R3.Packet; +import net.minecraft.server.v1_16_R3.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_16_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_16_R3.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_16_R3.PacketPlayOutEntityHeadRotation; -import net.minecraft.server.v1_16_R3.PacketPlayOutEntityTeleport; import net.minecraft.server.v1_16_R3.PacketPlayOutOpenWindow; import net.minecraft.server.v1_16_R3.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_16_R3.PacketPlayOutScoreboardTeam; @@ -1267,22 +1268,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTracker entry = ((WorldServer) handle.world).getChunkProvider().playerChunkMap.trackedEntities + .get(handle.getId()); + EntityTrackerEntry ete = null; + try { + ete = (EntityTrackerEntry) ENTITY_TRACKER_ENTRY_GETTER.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + Vec3D pos = handle.getPositionVector().d(ete.b()); + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (short) pos.x, (short) pos.y, (short) pos.z, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.isOnGround())); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.isOnGround())); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2333,6 +2349,7 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle ADVANCEMENT_PLAYER_FIELD = NMS.getFinalSetter(EntityPlayer.class, "advancementDataPlayer"); + private static final MethodHandle ATTRIBUTE_MAP = NMS.getGetter(AttributeMapBase.class, "d"); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP = NMS.getGetter(AttributeProvider.class, "a"); private static final MethodHandle ATTRIBUTE_PROVIDER_MAP_SETTER = NMS.getFinalSetter(AttributeProvider.class, "a"); @@ -2359,6 +2376,8 @@ public class NMSImpl implements NMSBridge { private static CustomEntityRegistry ENTITY_REGISTRY; private static final MethodHandle ENTITY_SETPOSE_METHOD = NMS.getMethodHandle(Entity.class, "setPose", true, EntityPose.class); + private static final MethodHandle ENTITY_TRACKER_ENTRY_GETTER = NMS.getFirstGetter(EntityTracker.class, + EntityTrackerEntry.class); private static final MethodHandle FISHING_HOOK_HOOKED = NMS.getGetter(EntityFishingHook.class, "hooked"); private static final MethodHandle FISHING_HOOK_HOOKED_SETTER = NMS.getSetter(EntityFishingHook.class, "hooked"); private static final MethodHandle FLYING_MOVECONTROL_FLOAT_GETTER = NMS.getFirstGetter(ControllerMoveFlying.class, 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 24b3fe42c..7a962f116 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 @@ -16,7 +16,6 @@ import net.citizensnpcs.util.NMS; import net.minecraft.server.v1_16_R3.Entity; import net.minecraft.server.v1_16_R3.EntityPlayer; import net.minecraft.server.v1_16_R3.EntityTrackerEntry; -import net.minecraft.server.v1_16_R3.PacketPlayOutAnimation; import net.minecraft.server.v1_16_R3.PlayerChunkMap; import net.minecraft.server.v1_16_R3.PlayerChunkMap.EntityTracker; @@ -40,13 +39,9 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker { NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); if (!Setting.DISABLE_TABLIST.asBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new PacketPlayOutAnimation(tracker, 0)); - NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - } - }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), + Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } @Override 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 03c56e46a..a26df95d0 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 @@ -248,12 +248,12 @@ import net.minecraft.network.Connection; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; -import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -1250,25 +1250,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new ClientboundTeleportEntityPacket(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.getYRot(); - float oldPitch = handle.getXRot(); - handle.setYBodyRot(bodyYaw); - handle.setXRot(pitch); - sendPacketsNearby(null, from.getLocation(), new ClientboundTeleportEntityPacket(handle), // new - // ClientboundMoveEntityPacket.Rot(handle.getId(), - // (byte) (bodyYaw * - // 256.0F / 360.0F), - // (byte) (pitch * 256.0F / 360.0F), handle.onGround), - new ClientboundRotateHeadPacket(handle, (byte) (headYaw * 256.0F / 360.0F))); - handle.setYBodyRot(oldBody); - handle.setXRot(oldPitch); + if (bodyYaw == null) { + bodyYaw = handle.getYRot(); + } + if (pitch == null) { + pitch = handle.getXRot(); + } + List> toSend = Lists.newArrayList(); + if (position) { + TrackedEntity entry = ((ServerLevel) handle.level).getChunkProvider().chunkMap.G.get(handle.getId()); + ServerEntity se = null; + try { + se = (ServerEntity) SERVER_ENTITY_GETTER.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + Vec3 pos = handle.position().subtract(se.sentPos()); + toSend.add( + new ClientboundMoveEntityPacket.PosRot(handle.getId(), (short) pos.x, (short) pos.y, (short) pos.z, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.isOnGround())); + } else { + toSend.add(new ClientboundMoveEntityPacket.Rot(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.isOnGround())); + } + if (headYaw != null) { + toSend.add(new ClientboundRotateHeadPacket(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2320,6 +2332,7 @@ public class NMSImpl implements NMSBridge { } private static final MethodHandle ADVANCEMENTS_PLAYER_FIELD = NMS.getFinalSetter(ServerPlayer.class, "cr"); + 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_SUPPLIER = NMS.getFirstGetter(AttributeMap.class, @@ -2370,6 +2383,8 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle PUFFERFISH_D = NMS.getSetter(Pufferfish.class, "bT"); private static EntityDataAccessor RABBIT_TYPE_DATAWATCHER = null; private static final Random RANDOM = Util.getFastRandom(); + private static final MethodHandle SERVER_ENTITY_GETTER = NMS.getFirstGetter(TrackedEntity.class, + ServerEntity.class); private static MethodHandle SET_PROFILE_METHOD; private static final MethodHandle SIZE_FIELD_GETTER = NMS.getFirstGetter(Entity.class, EntityDimensions.class); private static final MethodHandle SIZE_FIELD_SETTER = NMS.getFirstSetter(Entity.class, EntityDimensions.class); 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 ecfdef60d..588ad57f2 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 @@ -13,7 +13,6 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_17_R1.entity.EntityHumanNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; -import net.minecraft.network.protocol.game.ClientboundAnimatePacket; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ChunkMap.TrackedEntity; import net.minecraft.server.level.ServerEntity; @@ -44,7 +43,6 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { @Override public void run() { - NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)); NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); } }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); 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 7ae6bb8c0..df9ceb11f 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 @@ -249,12 +249,12 @@ import net.minecraft.network.Connection; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; -import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -1258,23 +1258,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new ClientboundTeleportEntityPacket(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.getYRot(); - float oldPitch = handle.getXRot(); - handle.setYBodyRot(bodyYaw); - handle.setXRot(pitch); - sendPacketsNearby(null, from.getLocation(), new ClientboundTeleportEntityPacket(handle), - // newClientboundMoveEntityPacket.Rot(handle.getId(), (byte) (bodyYaw *256.0F / 360.0F), (byte) (pitch * - // 256.0F / 360.0F), handle.onGround), - new ClientboundRotateHeadPacket(handle, (byte) (headYaw * 256.0F / 360.0F))); - handle.setYBodyRot(oldBody); - handle.setXRot(oldPitch); + if (bodyYaw == null) { + bodyYaw = handle.getYRot(); + } + if (pitch == null) { + pitch = handle.getXRot(); + } + List> toSend = Lists.newArrayList(); + if (position) { + TrackedEntity entry = ((ServerLevel) handle.level).getChunkSource().chunkMap.entityMap.get(handle.getId()); + ServerEntity se = null; + try { + se = (ServerEntity) SERVER_ENTITY_GETTER.invoke(entry); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + Vec3 pos = handle.position().subtract(se.sentPos()); + toSend.add( + new ClientboundMoveEntityPacket.PosRot(handle.getId(), (short) pos.x, (short) pos.y, (short) pos.z, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new ClientboundMoveEntityPacket.Rot(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new ClientboundRotateHeadPacket(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -2370,6 +2384,7 @@ public class NMSImpl implements NMSBridge { EntityType.SILVERFISH, EntityType.SHULKER, EntityType.ENDERMITE, EntityType.ENDER_DRAGON, EntityType.BAT, EntityType.SLIME, EntityType.DOLPHIN, EntityType.MAGMA_CUBE, EntityType.HORSE, EntityType.GHAST, EntityType.SHULKER, EntityType.PHANTOM); + private static final MethodHandle BEHAVIOR_TREE_MAP = NMS.getGetter(Brain.class, "f"); private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity"); private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class, "a", true, @@ -2419,6 +2434,8 @@ public class NMSImpl implements NMSBridge { private static final MethodHandle PUFFERFISH_D = NMS.getSetter(Pufferfish.class, "bW"); private static EntityDataAccessor RABBIT_TYPE_DATAWATCHER = null; private static final Random RANDOM = Util.getFastRandom(); + private static final MethodHandle SERVER_ENTITY_GETTER = NMS.getFirstGetter(TrackedEntity.class, + ServerEntity.class); private static MethodHandle SET_PROFILE_METHOD; private static final MethodHandle SIZE_FIELD_GETTER = NMS.getFirstGetter(Entity.class, EntityDimensions.class); private static final MethodHandle SIZE_FIELD_SETTER = NMS.getFirstSetter(Entity.class, EntityDimensions.class); 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 7c2b257ba..daa88a388 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 @@ -13,7 +13,6 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_18_R2.entity.EntityHumanNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; -import net.minecraft.network.protocol.game.ClientboundAnimatePacket; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ChunkMap.TrackedEntity; import net.minecraft.server.level.ServerEntity; @@ -41,13 +40,9 @@ public class PlayerlistTracker extends ChunkMap.TrackedEntity { NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); if (!Setting.DISABLE_TABLIST.asBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { - @Override - public void run() { - NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)); - NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - } - }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); + Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), + () -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()), + Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } @Override 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 e7972454b..068367fac 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 @@ -16,7 +16,6 @@ import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.nms.v1_19_R3.entity.EntityHumanNPC; import net.citizensnpcs.npc.ai.NPCHolder; import net.citizensnpcs.util.NMS; -import net.minecraft.network.protocol.game.ClientboundAnimatePacket; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ChunkMap.TrackedEntity; import net.minecraft.server.level.ServerEntity; @@ -62,14 +61,10 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity { final ServerPlayer entityplayer = lastUpdatedPlayer; boolean sendTabRemove = NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); if (!sendTabRemove || !Setting.DISABLE_TABLIST.asBoolean()) { - Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), - () -> NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)), - 1); return; } Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> { NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()); - NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0)); }, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks()); } 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 330410cdd..e75b62587 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 @@ -280,7 +280,6 @@ import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; -import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; import net.minecraft.network.protocol.game.VecDeltaCodec; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.resources.ResourceLocation; @@ -1354,33 +1353,37 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location location) { - sendPacketNearby(excluding, location, new ClientboundTeleportEntityPacket(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.getYRot(); - float oldPitch = handle.getXRot(); - // handle.setYRot(bodyYaw); - // handle.setXRot(pitch); - TrackedEntity entry = ((ServerLevel) handle.level).getChunkSource().chunkMap.entityMap.get(handle.getId()); - VecDeltaCodec vdc = null; - try { - vdc = (VecDeltaCodec) POSITION_CODEC_GETTER.invoke((ServerEntity) SERVER_ENTITY_GETTER.invoke(entry)); - } catch (Throwable e) { - e.printStackTrace(); - return; + if (bodyYaw == null) { + bodyYaw = handle.getYRot(); } - Vec3 pos = handle.trackingPosition(); - sendPacketsNearby(null, from.getLocation(), // new ClientboundTeleportEntityPacket(handle), - new ClientboundMoveEntityPacket.PosRot(handle.getId(), (short) vdc.encodeX(pos), - (short) vdc.encodeY(pos), (short) vdc.encodeZ(pos), (byte) (bodyYaw * 256.0F / 360.0F), - (byte) (pitch * 256.0F / 360.0F), handle.onGround), - new ClientboundRotateHeadPacket(handle, (byte) (headYaw * 256.0F / 360.0F))); - // handle.setYRot(oldBody); - // handle.setXRot(oldPitch); + if (pitch == null) { + pitch = handle.getXRot(); + } + List> toSend = Lists.newArrayList(); + if (position) { + TrackedEntity entry = ((ServerLevel) handle.level).getChunkSource().chunkMap.entityMap.get(handle.getId()); + VecDeltaCodec vdc = null; + try { + vdc = (VecDeltaCodec) POSITION_CODEC_GETTER.invoke((ServerEntity) SERVER_ENTITY_GETTER.invoke(entry)); + } catch (Throwable e) { + e.printStackTrace(); + return; + } + Vec3 pos = handle.trackingPosition(); + toSend.add(new ClientboundMoveEntityPacket.PosRot(handle.getId(), (short) vdc.encodeX(pos), + (short) vdc.encodeY(pos), (short) vdc.encodeZ(pos), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new ClientboundMoveEntityPacket.Rot(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new ClientboundRotateHeadPacket(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override 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 fee38359f..57780c049 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 @@ -209,6 +209,8 @@ import net.minecraft.server.v1_8_R3.NetworkManager; import net.minecraft.server.v1_8_R3.Packet; import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation; import net.minecraft.server.v1_8_R3.PacketPlayOutBed; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutEntityLook; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook; import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment; import net.minecraft.server.v1_8_R3.PacketPlayOutEntityHeadRotation; import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport; @@ -1015,22 +1017,31 @@ public class NMSImpl implements NMSBridge { } @Override - public void sendPositionUpdate(Player excluding, org.bukkit.entity.Entity from, Location storedLocation) { - sendPacketNearby(excluding, storedLocation, new PacketPlayOutEntityTeleport(getHandle(from))); - } - - @Override - public void sendRotationNearby(org.bukkit.entity.Entity from, float bodyYaw, float headYaw, float pitch) { + public void sendPositionUpdate(org.bukkit.entity.Entity from, boolean position, Float bodyYaw, Float pitch, + Float headYaw) { Entity handle = getHandle(from); - float oldBody = handle.yaw; - float oldPitch = handle.pitch; - handle.yaw = bodyYaw; - handle.pitch = pitch; - Packet[] packets = new Packet[] { new PacketPlayOutEntityTeleport(handle), - new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F)) }; - sendPacketsNearby(null, from.getLocation(), packets); - handle.yaw = oldBody; - handle.pitch = oldPitch; + if (bodyYaw == null) { + bodyYaw = handle.yaw; + } + if (pitch == null) { + pitch = handle.pitch; + } + List> toSend = Lists.newArrayList(); + if (position) { + EntityTrackerEntry entry = ((WorldServer) handle.world).getTracker().trackedEntities.get(handle.getId()); + long dx = MathHelper.floor(handle.locX * 32.0) - entry.xLoc; + long dy = MathHelper.floor(handle.locY * 32.0) - entry.yLoc; + long dz = MathHelper.floor(handle.locZ * 32.0) - entry.zLoc; + toSend.add(new PacketPlayOutRelEntityMoveLook(handle.getId(), (byte) dx, (byte) dy, (byte) dz, + (byte) (bodyYaw * 256.0F / 360.0F), (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } else { + toSend.add(new PacketPlayOutEntityLook(handle.getId(), (byte) (bodyYaw * 256.0F / 360.0F), + (byte) (pitch * 256.0F / 360.0F), handle.onGround)); + } + if (headYaw != null) { + toSend.add(new PacketPlayOutEntityHeadRotation(handle, (byte) (headYaw * 256.0F / 360.0F))); + } + sendPacketsNearby(null, from.getLocation(), toSend, 64); } @Override @@ -1800,12 +1811,18 @@ 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; + public static MethodHandle ENDERDRAGON_CHECK_WALLS = NMS.getFirstMethodHandleWithReturnType(EntityEnderDragon.class, true, boolean.class, AxisAlignedBB.class); + private static Method ENTITY_ATTACK_A = NMS.getMethod(Entity.class, "a", true, EntityLiving.class, Entity.class); private static Map, Integer> ENTITY_CLASS_TO_INT; private static Map, String> ENTITY_CLASS_TO_NAME; + private static final MethodHandle ENTITY_TRACKER_ENTRY_X = NMS.getGetter(EntityTrackerEntry.class, "xLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Y = NMS.getGetter(EntityTrackerEntry.class, "yLoc"); + private static final MethodHandle ENTITY_TRACKER_ENTRY_Z = NMS.getGetter(EntityTrackerEntry.class, "zLoc"); private static final Location FROM_LOCATION = new Location(null, 0, 0, 0); private static Method GET_NMS_BLOCK = NMS.getMethod(CraftBlock.class, "getNMSBlock", false); private static Field GOAL_FIELD = NMS.getField(PathfinderGoalSelector.class, "b");