diff --git a/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java b/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java index 8a74a0f..d901401 100644 --- a/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java +++ b/SpigotCore_8/src/de/steamwar/core/BountifulWrapper8.java @@ -78,6 +78,19 @@ public class BountifulWrapper8 implements BountifulWrapper.IBountifulWrapper { }; } + @Override + public BountifulWrapper.PositionSetter getRelMoveSetter(Class packetClass) { + Reflection.FieldAccessor moveX = Reflection.getField(packetClass, "b", byte.class); + Reflection.FieldAccessor moveY = Reflection.getField(packetClass, "c", byte.class); + Reflection.FieldAccessor moveZ = Reflection.getField(packetClass, "d", byte.class); + + return (packet, x, y, z) -> { + moveX.set(packet, (byte)(x*32)); + moveY.set(packet, (byte)(y*32)); + moveZ.set(packet, (byte)(z*32)); + }; + } + @Override public BountifulWrapper.UUIDSetter getUUIDSetter(Class packetClass) { return (packet, uuid) -> {}; diff --git a/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java b/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java index 5602d9a..2832f2f 100644 --- a/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java +++ b/SpigotCore_9/src/de/steamwar/core/BountifulWrapper9.java @@ -72,6 +72,20 @@ public class BountifulWrapper9 implements BountifulWrapper.IBountifulWrapper { }; } + @Override + public BountifulWrapper.PositionSetter getRelMoveSetter(Class packetClass) { + Class type = Core.getVersion() > 12 ? short.class : int.class; + Reflection.FieldAccessor moveX = Reflection.getField(packetClass, "b", type); + Reflection.FieldAccessor moveY = Reflection.getField(packetClass, "c", type); + Reflection.FieldAccessor moveZ = Reflection.getField(packetClass, "d", type); + + return (packet, x, y, z) -> { + moveX.set(packet, (short)(x*4096)); + moveY.set(packet, (short)(y*4096)); + moveZ.set(packet, (short)(z*4096)); + }; + } + @Override public BountifulWrapper.UUIDSetter getUUIDSetter(Class packetClass) { Reflection.FieldAccessor uuidField = Reflection.getField(packetClass, UUID.class, 0); diff --git a/SpigotCore_Main/src/de/steamwar/core/BountifulWrapper.java b/SpigotCore_Main/src/de/steamwar/core/BountifulWrapper.java index a0625a2..2e53290 100644 --- a/SpigotCore_Main/src/de/steamwar/core/BountifulWrapper.java +++ b/SpigotCore_Main/src/de/steamwar/core/BountifulWrapper.java @@ -39,6 +39,7 @@ public class BountifulWrapper { Object getDataWatcherItem(Object dataWatcherObject, Object value); PositionSetter getPositionSetter(Class packetClass, int fieldOffset); + PositionSetter getRelMoveSetter(Class packetClass); UUIDSetter getUUIDSetter(Class packetClass); } diff --git a/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore_Main/src/de/steamwar/entity/REntity.java index 9ffbdc2..2acc9b4 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -104,20 +104,37 @@ public class REntity { move(location.getX(), location.getY(), location.getZ(), location.getPitch(), location.getYaw(), rotToByte(location.getYaw())); } + private static final double MAX_REL_MOVE = Core.getVersion() > 8 ? 8.0 : 4.0; public void move(double locX, double locY, double locZ, float pitch, float yaw, byte headYaw) { server.preEntityMove(this, locX, locZ); + double fromX = this.x; double fromZ = this.z; + double diffX = locX - x; + double diffY = locY - y; + double diffZ = locZ - z; + boolean rotEq = this.yaw == yaw && this.pitch == pitch; + this.x = locX; this.y = locY; this.z = locZ; this.yaw = rotToByte(yaw); this.pitch = rotToByte(pitch); - server.updateEntity(this, getTeleportPacket()); + + if(Math.abs(diffX) < MAX_REL_MOVE && Math.abs(diffY) < MAX_REL_MOVE && Math.abs(diffZ) < MAX_REL_MOVE) { + Object packet = getMoveLookPacket(diffX, diffY, diffZ,rotEq); + + if(packet != null) + server.updateEntity(this, packet); + } else { + server.updateEntity(this, getTeleportPacket()); + } + if(this.headYaw != headYaw) { this.headYaw = headYaw; server.updateEntity(this, getHeadRotationPacket()); } + server.postEntityMove(this, fromX, fromZ); } @@ -364,6 +381,35 @@ public class REntity { return packet; } + private static final Class entityPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntity"); + private static final Reflection.FieldAccessor moveEntityId = Reflection.getField(entityPacket, int.class, 0); + private static final BountifulWrapper.PositionSetter movePosition = BountifulWrapper.impl.getRelMoveSetter(entityPacket); + private static final Reflection.FieldAccessor lookYaw = Reflection.getField(entityPacket, "e", byte.class); + private static final Reflection.FieldAccessor lookPitch = Reflection.getField(entityPacket, "f", byte.class); + private static final Class lookPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntity$PacketPlayOutEntityLook"); + private static final Class movePacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntity$PacketPlayOutRelEntityMove"); + private static final Class moveLookPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntity$PacketPlayOutRelEntityMoveLook"); + private Object getMoveLookPacket(double diffX, double diffY, double diffZ, boolean rotEq) { + Class clazz; + if(diffX == 0 && diffY == 0 && diffZ == 0) { + if(rotEq) + return null; + + clazz = lookPacket; + } else if (rotEq) { + clazz = movePacket; + } else { + clazz = moveLookPacket; + } + + Object packet = Reflection.newInstance(clazz); + moveEntityId.set(packet, entityId); + movePosition.set(packet, diffX, diffY, diffZ); + lookYaw.set(packet, yaw); + lookPitch.set(packet, pitch); + return packet; + } + private static final Class headRotationPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutEntityHeadRotation"); private static final Reflection.FieldAccessor headRotationEntity = Reflection.getField(headRotationPacket, int.class, 0); private static final Reflection.FieldAccessor headRotationYaw = Reflection.getField(headRotationPacket, byte.class, 0);