Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ public void register() {
float yaw = wrapper.get(Types.FLOAT, 0);
float pitch = wrapper.get(Types.FLOAT, 1);

wrapper.set(Types.BYTE, 0, (byte) 0);
// 1.8 supports the rotation-relative flags (0x08/0x10) natively, and resolving them here
// would snap the camera to the tracked rotation, which lags the client's live look. Keep
// them on the wire and only resolve the position bits (native 1.8 servers use zero-delta
// rotation-relative teleports to leave the camera untouched).
wrapper.set(Types.BYTE, 0, (byte) (flags & 0x18));

if (flags != 0) {
if ((flags & 0x01) != 0) {
Expand All @@ -183,19 +187,17 @@ public void register() {
wrapper.set(Types.DOUBLE, 2, z);
}
if ((flags & 0x08) != 0) {
yaw += pos.getYaw();
wrapper.set(Types.FLOAT, 0, yaw);
yaw += pos.getYaw(); // tracked estimate only; the wire keeps the delta
}
if ((flags & 0x10) != 0) {
pitch += pos.getPitch();
wrapper.set(Types.FLOAT, 1, pitch);
}
}

pos.setPos(x, y, z);
pos.setYaw(yaw);
pos.setPitch(pitch);
pos.queueTeleport(teleportId, x, y, z, pos.getYaw(), pos.getPitch());
pos.queueTeleport(teleportId, x, y, z, pos.getYaw(), pos.getPitch(), (flags & 0x18) != 0);
});
}
});
Expand Down Expand Up @@ -364,12 +366,19 @@ public void register() {
// This Y error gets propagated from 1.7 to 1.8 to 1.9 which causes teleport confirmation to not properly be detected
// This fixes it similarly to how anticheats detect teleports: https://github.com/GrimAnticheat/Grim/blob/67aa3a9483a9b2a6987d594092697b4104c781f0/common/src/main/java/ac/grim/grimac/manager/SetbackTeleportUtil.java#L315
boolean closeEnoughY = Math.abs(teleport.y() - y) <= 1e-7;
// A view-relative teleport keeps its rotation deltas on the wire, so the client applies them
// to its own live look and echoes that - match on position only and adopt the echoed rotation
final boolean rotationMatches = teleport.viewRelative() || (teleport.yaw() == yaw && teleport.pitch() == pitch);

if (teleport.x() == x && closeEnoughY && teleport.z() == z && teleport.yaw() == yaw && teleport.pitch() == pitch) {
if (teleport.x() == x && closeEnoughY && teleport.z() == z && rotationMatches) {
final PacketWrapper confirmTeleport = PacketWrapper.create(ServerboundPackets1_9.ACCEPT_TELEPORTATION, wrapper.user());
confirmTeleport.write(Types.VAR_INT, teleport.id());
confirmTeleport.sendToServer(Protocol1_9To1_8.class);

if (teleport.viewRelative()) {
storage.setYaw(yaw);
storage.setPitch(pitch);
}
storage.confirmTeleport();
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public boolean hasPendingTeleports() {
return !this.pendingTeleports.isEmpty();
}

public void queueTeleport(final int id, final double x, final double y, final double z, final float yaw, final float pitch) {
this.pendingTeleports.add(new PendingTeleport(id, x, y, z, yaw, pitch));
public void queueTeleport(final int id, final double x, final double y, final double z, final float yaw, final float pitch, final boolean viewRelative) {
this.pendingTeleports.add(new PendingTeleport(id, x, y, z, yaw, pitch, viewRelative));
}

public PendingTeleport peekTeleport() {
Expand All @@ -100,7 +100,7 @@ public void confirmTeleport() {
this.pendingTeleports.poll();
}

public record PendingTeleport(int id, double x, double y, double z, float yaw, float pitch) {
public record PendingTeleport(int id, double x, double y, double z, float yaw, float pitch, boolean viewRelative) {
}

}