Pass position/rotation values directly, fix relative position and rotation handling

This commit is contained in:
Nassim Jahnke 2024-10-19 12:55:59 +02:00
parent 4d4f66a1a2
commit 1c7017a056
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
6 changed files with 132 additions and 117 deletions

View File

@ -75,7 +75,11 @@ public class EntityPositionHandler {
}
}
positionStorage.setCoordinates(x, y, z, relative);
if (relative) {
positionStorage.addRelativePosition(x, y, z);
} else {
positionStorage.setPosition(x, y, z);
}
}
public EntityPositionStorage getStorage(UserConnection user, int entityId) {

View File

@ -34,15 +34,15 @@ public abstract class EntityPositionStorage {
return z;
}
public void setCoordinates(double x, double y, double z, boolean relative) {
if (relative) {
this.x += x;
this.y += y;
this.z += z;
} else {
public void setPosition(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void addRelativePosition(double relX, double relY, double relZ) {
this.x += relX;
this.y += relY;
this.z += relZ;
}
}

View File

@ -18,8 +18,6 @@
package com.viaversion.viabackwards.api.entities.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
public abstract class PlayerPositionStorage implements StorableObject {
private double x;
@ -53,19 +51,15 @@ public abstract class PlayerPositionStorage implements StorableObject {
this.z = z;
}
public void setCoordinates(PacketWrapper wrapper, boolean relative) {
setCoordinates(wrapper.get(Types.DOUBLE, 0), wrapper.get(Types.DOUBLE, 1), wrapper.get(Types.DOUBLE, 2), relative);
}
public void setCoordinates(double x, double y, double z, boolean relative) {
if (relative) {
this.x += x;
this.y += y;
this.z += z;
} else {
public void setPosition(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void addRelativePosition(double relX, double relY, double relZ) {
this.x += relX;
this.y += relY;
this.z += relZ;
}
}

View File

@ -31,10 +31,11 @@ import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_12;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_12;
@ -237,14 +238,11 @@ public class EntityPacketRewriter1_13 extends LegacyEntityRewriter<ClientboundPa
});
if (ViaBackwards.getConfig().isFix1_13FacePlayer()) {
PacketHandlers movementRemapper = new PacketHandlers() {
@Override
public void register() {
map(Types.DOUBLE);
map(Types.DOUBLE);
map(Types.DOUBLE);
handler(wrapper -> wrapper.user().get(PlayerPositionStorage1_13.class).setCoordinates(wrapper, false));
}
PacketHandler movementRemapper = wrapper -> {
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
wrapper.user().get(PlayerPositionStorage1_13.class).setPosition(x, y, z);
};
protocol.registerServerbound(ServerboundPackets1_12_1.MOVE_PLAYER_POS, movementRemapper); // Player Position
protocol.registerServerbound(ServerboundPackets1_12_1.MOVE_PLAYER_POS_ROT, movementRemapper); // Player Position And Look (serverbound)

View File

@ -47,6 +47,15 @@ import java.util.List;
public final class EntityPacketRewriter1_21_2 extends EntityRewriter<ClientboundPacket1_21_2, Protocol1_21_2To1_21> {
private static final int REL_X = 0;
private static final int REL_Y = 1;
private static final int REL_Z = 2;
private static final int REL_Y_ROT = 3;
private static final int REL_X_ROT = 4;
private static final int REL_DELTA_X = 5;
private static final int REL_DELTA_Y = 6;
private static final int REL_DELTA_Z = 7;
private static final int REL_ROTATE_DELTA = 8;
private boolean warned = ViaBackwards.getConfig().suppressEmulationWarnings();
public EntityPacketRewriter1_21_2(final Protocol1_21_2To1_21 protocol) {
@ -144,20 +153,22 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
wrapper.read(Types.DOUBLE); // Delta movement Y
wrapper.read(Types.DOUBLE); // Delta movement Z
updateRotation(wrapper);
final float yaw = wrapper.read(Types.FLOAT);
final float pitch = wrapper.read(Types.FLOAT);
writePackedRotation(wrapper, yaw, pitch);
});
protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_ROTATION, ClientboundPackets1_21.PLAYER_LOOK_AT, wrapper -> {
wrapper.passthrough(Types.FLOAT); // Y rot
wrapper.passthrough(Types.FLOAT); // X rot
final float yaw = wrapper.passthrough(Types.FLOAT);
final float pitch = wrapper.passthrough(Types.FLOAT);
final double yaw = Math.toRadians(wrapper.get(Types.FLOAT, 0));
final double pitch = Math.toRadians(wrapper.get(Types.FLOAT, 1));
final double yRadians = Math.toRadians(yaw);
final double xRadians = Math.toRadians(pitch);
final double factor = -Math.cos(-pitch);
final double deltaX = Math.sin(-yaw - (float) Math.PI) * factor;
final double deltaY = Math.sin(-pitch);
final double deltaZ = Math.cos(-yaw - (float) Math.PI) * factor;
final double factor = -Math.cos(-xRadians);
final double deltaX = Math.sin(-yRadians - (float) Math.PI) * factor;
final double deltaY = Math.sin(-xRadians);
final double deltaZ = Math.cos(-yRadians - (float) Math.PI) * factor;
final PlayerStorage storage = wrapper.user().get(PlayerStorage.class);
wrapper.write(Types.VAR_INT, 0); // From anchor
@ -167,46 +178,48 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
wrapper.write(Types.BOOLEAN, false); // At entity
final PacketWrapper entityMotionPacket = PacketWrapper.create(ServerboundPackets1_21_2.MOVE_PLAYER_ROT, wrapper.user());
entityMotionPacket.write(Types.FLOAT, wrapper.get(Types.FLOAT, 0));
entityMotionPacket.write(Types.FLOAT, wrapper.get(Types.FLOAT, 1));
entityMotionPacket.write(Types.FLOAT, yaw);
entityMotionPacket.write(Types.FLOAT, pitch);
entityMotionPacket.write(Types.UNSIGNED_BYTE, (short) 0); // On ground and horizontal collision
entityMotionPacket.sendToServer(Protocol1_21_2To1_21.class);
});
protocol.registerClientbound(ClientboundPackets1_21_2.TELEPORT_ENTITY, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
double movementX = wrapper.read(Types.DOUBLE);
double movementY = wrapper.read(Types.DOUBLE);
double movementZ = wrapper.read(Types.DOUBLE);
final double movementX = wrapper.read(Types.DOUBLE);
final double movementY = wrapper.read(Types.DOUBLE);
final double movementZ = wrapper.read(Types.DOUBLE);
// Pack y and x rot
updateRotation(wrapper);
final float yaw = wrapper.read(Types.FLOAT);
final float pitch = wrapper.read(Types.FLOAT);
writePackedRotation(wrapper, yaw, pitch);
final int relativeArguments = wrapper.read(Types.VAR_INT);
final int relativeArguments = wrapper.read(Types.INT);
// Send alongside separate entity motion
wrapper.send(Protocol1_21_2To1_21.class);
wrapper.cancel();
handleRelativeArguments(wrapper, relativeArguments, movementX, movementY, movementZ);
handleRelativeArguments(wrapper, x, y, z, yaw, pitch, relativeArguments, movementX, movementY, movementZ);
});
protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_POSITION, wrapper -> {
final int teleportId = wrapper.read(Types.VAR_INT);
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
double movementX = wrapper.read(Types.DOUBLE);
double movementY = wrapper.read(Types.DOUBLE);
double movementZ = wrapper.read(Types.DOUBLE);
final double movementX = wrapper.read(Types.DOUBLE);
final double movementY = wrapper.read(Types.DOUBLE);
final double movementZ = wrapper.read(Types.DOUBLE);
wrapper.passthrough(Types.FLOAT); // Y rot
wrapper.passthrough(Types.FLOAT); // X rot
final float yaw = wrapper.passthrough(Types.FLOAT);
final float pitch = wrapper.passthrough(Types.FLOAT);
// Just keep the new values in there
final int relativeArguments = wrapper.read(Types.INT);
@ -216,7 +229,8 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
// Send alongside separate entity motion
wrapper.send(Protocol1_21_2To1_21.class);
wrapper.cancel();
handleRelativeArguments(wrapper, relativeArguments, movementX, movementY, movementZ);
handleRelativeArguments(wrapper, x, y, z, yaw, pitch, relativeArguments, movementX, movementY, movementZ);
});
protocol.registerServerbound(ServerboundPackets1_20_5.PLAYER_COMMAND, wrapper -> {
@ -280,45 +294,45 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
});
protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_POS, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
fixOnGround(wrapper);
final PlayerStorage storage = wrapper.user().get(PlayerStorage.class);
storage.setPosition(wrapper);
storage.setPosition(x, y, z);
});
protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_POS_ROT, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.FLOAT); // Yaw
wrapper.passthrough(Types.FLOAT); // Pitch
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
final float yaw = wrapper.passthrough(Types.FLOAT);
final float pitch = wrapper.passthrough(Types.FLOAT);
fixOnGround(wrapper);
final PlayerStorage storage = wrapper.user().get(PlayerStorage.class);
storage.setPosition(wrapper);
storage.setRotation(wrapper);
storage.setPosition(x, y, z);
storage.setRotation(yaw, pitch);
});
protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_ROT, wrapper -> {
wrapper.passthrough(Types.FLOAT); // Yaw
wrapper.passthrough(Types.FLOAT); // Pitch
final float yaw = wrapper.passthrough(Types.FLOAT);
final float pitch = wrapper.passthrough(Types.FLOAT);
fixOnGround(wrapper);
final PlayerStorage storage = wrapper.user().get(PlayerStorage.class);
storage.setRotation(wrapper);
storage.setRotation(yaw, pitch);
});
protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_STATUS_ONLY, this::fixOnGround);
protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_VEHICLE, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.passthrough(Types.FLOAT); // Yaw
wrapper.passthrough(Types.FLOAT); // Pitch
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
final float yaw = wrapper.passthrough(Types.FLOAT);
final float pitch = wrapper.passthrough(Types.FLOAT);
final PlayerStorage storage = wrapper.user().get(PlayerStorage.class);
storage.setPosition(wrapper);
storage.setRotation(wrapper);
storage.setPosition(x, y, z);
storage.setRotation(yaw, pitch);
});
protocol.registerClientbound(ClientboundPackets1_21_2.PLAYER_INFO_UPDATE, wrapper -> {
@ -393,30 +407,39 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
});
}
private void updateRotation(PacketWrapper wrapper) {
private void writePackedRotation(final PacketWrapper wrapper, final float yaw, final float pitch) {
// Pack y and x rot
final float yaw = wrapper.read(Types.FLOAT);
final float pitch = wrapper.read(Types.FLOAT);
wrapper.write(Types.BYTE, (byte) Math.floor(yaw * 256F / 360F));
wrapper.write(Types.BYTE, (byte) Math.floor(pitch * 256F / 360F));
}
private void handleRelativeArguments(final PacketWrapper wrapper, final int relativeArguments, double movementX, double movementY, double movementZ) {
private void handleRelativeArguments(
final PacketWrapper wrapper,
double x, double y, double z,
float yaw, float pitch,
final int relativeArguments,
double movementX, double movementY, double movementZ
) {
// Position and rotation
final PlayerStorage storage = wrapper.user().get(PlayerStorage.class);
storage.setPosition(wrapper);
// Rotate Delta
if ((relativeArguments & 1 << 8) != 0) {
float yaw = wrapper.get(Types.FLOAT, 4);
if ((relativeArguments & 1 << 3) != 0) {
if ((relativeArguments & 1 << REL_X) != 0) {
x += storage.x();
}
if ((relativeArguments & 1 << REL_Y) != 0) {
y += storage.y();
}
if ((relativeArguments & 1 << REL_Z) != 0) {
z += storage.z();
}
if ((relativeArguments & 1 << REL_Y_ROT) != 0) {
yaw += storage.yaw();
}
float pitch = wrapper.get(Types.FLOAT, 5);
if ((relativeArguments & 1 << 4) != 0) {
if ((relativeArguments & 1 << REL_X_ROT) != 0) {
pitch += storage.pitch();
}
// Movement rotation
if ((relativeArguments & 1 << REL_ROTATE_DELTA) != 0) {
final double deltaYaw = Math.toRadians(storage.yaw() - yaw);
final double deltaYawCos = Math.cos(deltaYaw);
final double deltaYawSin = Math.sin(deltaYaw);
@ -430,11 +453,11 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
movementZ = movementZ * deltaPitchCos - movementY * deltaPitchSin;
}
final boolean relativeDeltaX = (relativeArguments & 1 << 5) != 0;
final boolean relativeDeltaY = (relativeArguments & 1 << 6) != 0;
final boolean relativeDeltaZ = (relativeArguments & 1 << 7) != 0;
final boolean relativeDeltaX = (relativeArguments & 1 << REL_DELTA_X) != 0;
final boolean relativeDeltaY = (relativeArguments & 1 << REL_DELTA_Y) != 0;
final boolean relativeDeltaZ = (relativeArguments & 1 << REL_DELTA_Z) != 0;
// Delta x, y, z
// Movement
if (relativeDeltaX && relativeDeltaY && relativeDeltaZ) {
final PacketWrapper explosionPacket = wrapper.create(ClientboundPackets1_21.EXPLODE);
explosionPacket.write(Types.DOUBLE, 0.0); // Center X
@ -469,7 +492,9 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
warned = true;
}
storage.setRotation(wrapper);
// Update at the end
storage.setPosition(x, y, z);
storage.setRotation(yaw, pitch);
}
private int boatTypeFromEntityType(final EntityType type) {

View File

@ -39,12 +39,6 @@ public final class PlayerStorage extends PlayerPositionStorage {
private double prevY;
private double prevZ;
public void setPosition(PacketWrapper wrapper) {
setX(wrapper.get(Types.DOUBLE, 0));
setY(wrapper.get(Types.DOUBLE, 1));
setZ(wrapper.get(Types.DOUBLE, 2));
}
public void tick(final UserConnection user) {
final double deltaX = x() - prevX;
final double deltaY = y() - prevY;
@ -97,9 +91,9 @@ public final class PlayerStorage extends PlayerPositionStorage {
return pitch;
}
public void setRotation(final PacketWrapper wrapper) {
this.yaw = wrapper.get(Types.FLOAT, 0);
this.pitch = wrapper.get(Types.FLOAT, 1);
public void setRotation(final float yaw, final float pitch) {
this.yaw = yaw;
this.pitch = pitch;
}
public void setPlayerCommandTrackedSneaking(final boolean playerCommandTrackedSneaking) {