diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 7dbbf0b52..a8ca770aa 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -204,16 +204,15 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { movePlayerPacket.setPosition(this.position); movePlayerPacket.setRotation(getBedrockRotation()); movePlayerPacket.setOnGround(isOnGround); - movePlayerPacket.setMode(teleported ? MovePlayerPacket.Mode.TELEPORT : MovePlayerPacket.Mode.NORMAL); - - if (teleported) { - movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.UNKNOWN); + movePlayerPacket.setMode(this instanceof SessionPlayerEntity || teleported ? MovePlayerPacket.Mode.TELEPORT : MovePlayerPacket.Mode.NORMAL); + if (movePlayerPacket.getMode() == MovePlayerPacket.Mode.TELEPORT) { + movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR); } session.sendUpstreamPacket(movePlayerPacket); - if (teleported) { - // As of 1.19.0, head yaw seems to be ignored during teleports. + if (teleported && !(this instanceof SessionPlayerEntity)) { + // As of 1.19.0, head yaw seems to be ignored during teleports, also don't do this for session player. updateHeadLookRotation(headYaw); } @@ -239,7 +238,7 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { movePlayerPacket.setPosition(position); movePlayerPacket.setRotation(getBedrockRotation()); movePlayerPacket.setOnGround(isOnGround); - movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL); + movePlayerPacket.setMode(this instanceof SessionPlayerEntity ? MovePlayerPacket.Mode.TELEPORT : MovePlayerPacket.Mode.NORMAL); // If the player is moved while sleeping, we have to adjust their y, so it appears // correctly on Bedrock. This fixes GSit's lay. if (getFlag(EntityFlag.SLEEPING)) { @@ -247,9 +246,13 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity { // Force the player movement by using a teleport movePlayerPacket.setPosition(Vector3f.from(position.getX(), position.getY() - definition.offset() + 0.2f, position.getZ())); movePlayerPacket.setMode(MovePlayerPacket.Mode.TELEPORT); - movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.UNKNOWN); } } + + if (movePlayerPacket.getMode() == MovePlayerPacket.Mode.TELEPORT) { + movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR); + } + session.sendUpstreamPacket(movePlayerPacket); if (leftParrot != null) { leftParrot.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, true); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java index b6835151e..deae0fd7e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/SessionPlayerEntity.java @@ -36,6 +36,7 @@ import org.cloudburstmc.protocol.bedrock.data.AttributeData; import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket; +import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; @@ -43,7 +44,6 @@ import org.geysermc.geyser.entity.type.BoatEntity; import org.geysermc.geyser.entity.type.Entity; import org.geysermc.geyser.inventory.GeyserItemStack; import org.geysermc.geyser.item.Items; -import org.geysermc.geyser.level.BedrockDimension; import org.geysermc.geyser.level.block.Blocks; import org.geysermc.geyser.level.block.property.Properties; import org.geysermc.geyser.level.block.type.BlockState; @@ -117,15 +117,6 @@ public class SessionPlayerEntity extends PlayerEntity { @Getter @Setter private Vector2f bedrockInteractRotation = Vector2f.ZERO; - /** - * Determines if our position is currently out-of-sync with the Java server - * due to our workaround for the void floor - *
- * Must be reset when dying, switching worlds, or being teleported out of the void
- */
- @Getter @Setter
- private boolean voidPositionDesynched;
-
public SessionPlayerEntity(GeyserSession session) {
super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null);
@@ -152,29 +143,18 @@ public class SessionPlayerEntity extends PlayerEntity {
@Override
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) {
- if (voidPositionDesynched) {
- if (!isBelowVoidFloor()) {
- voidPositionDesynched = false; // No need to fix our offset; we've been moved
- }
- }
super.moveRelative(relX, relY, relZ, yaw, pitch, headYaw, isOnGround);
session.getCollisionManager().updatePlayerBoundingBox(this.position.down(definition.offset()));
}
- @Override
- public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) {
- if (voidPositionDesynched) {
- if (!isBelowVoidFloor()) {
- voidPositionDesynched = false; // No need to fix our offset; we've been moved
- }
- }
- super.moveAbsolute(position, yaw, pitch, headYaw, isOnGround, teleported);
- }
-
@Override
public void setPosition(Vector3f position) {
if (valid) { // Don't update during session init
session.getCollisionManager().updatePlayerBoundingBox(position);
+
+ if (session.isNoClip() && position.getY() >= session.getBedrockDimension().minY() - 5) {
+ session.setNoClip(false);
+ }
}
this.position = position.add(0, definition.offset(), 0);
}
@@ -200,6 +180,12 @@ public class SessionPlayerEntity extends PlayerEntity {
movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR);
session.sendUpstreamPacket(movePlayerPacket);
+
+ // We're just setting rotation, player shouldn't lose motion, send motion packet to account for that.
+ SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
+ entityMotionPacket.setRuntimeEntityId(geyserId);
+ entityMotionPacket.setMotion(motion);
+ session.sendUpstreamPacket(entityMotionPacket);
}
/**
@@ -211,6 +197,11 @@ public class SessionPlayerEntity extends PlayerEntity {
*/
public void setPositionManual(Vector3f position) {
this.position = position;
+
+ // Player is "above" the void so they're not supposed to no clip.
+ if (session.isNoClip() && position.getY() - EntityDefinitions.PLAYER.offset() >= session.getBedrockDimension().minY() - 5) {
+ session.setNoClip(false);
+ }
}
/**
@@ -360,9 +351,6 @@ public class SessionPlayerEntity extends PlayerEntity {
} else {
dirtyMetadata.put(EntityDataTypes.PLAYER_HAS_DIED, false);
}
-
- // We're either respawning or switching worlds, either way, we are no longer desynched
- this.setVoidPositionDesynched(false);
}
@Override
@@ -448,51 +436,7 @@ public class SessionPlayerEntity extends PlayerEntity {
super.setVehicle(entity);
}
-
- private boolean isBelowVoidFloor() {
- return position.getY() < voidFloorPosition();
- }
-
- public int voidFloorPosition() {
- // The void floor is offset about 40 blocks below the bottom of the world
- BedrockDimension bedrockDimension = session.getBedrockDimension();
- return bedrockDimension.minY() - 40;
- }
-
- /**
- * This method handles teleporting the player below or above the Bedrock void floor.
- * The Java server should never see this desync as we adjust the position that we send to it
- *
- * @param up in which direction to teleport - true to resync our position, or false to be
- * teleported below the void floor.
- */
- public void teleportVoidFloorFix(boolean up) {
- // Safety to avoid double teleports
- if ((voidPositionDesynched && !up) || (!voidPositionDesynched && up)) {
- return;
- }
-
- // Work around there being a floor at the bottom of the world and teleport the player below it
- // Moving from below to above the void floor works fine
- Vector3f newPosition = this.getPosition();
- if (up) {
- newPosition = newPosition.up(4f);
- voidPositionDesynched = false;
- } else {
- newPosition = newPosition.down(4f);
- voidPositionDesynched = true;
- }
-
- this.setPositionManual(newPosition);
- MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
- movePlayerPacket.setRuntimeEntityId(geyserId);
- movePlayerPacket.setPosition(newPosition);
- movePlayerPacket.setRotation(getBedrockRotation());
- movePlayerPacket.setMode(MovePlayerPacket.Mode.TELEPORT);
- movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR);
- session.sendUpstreamPacketImmediately(movePlayerPacket);
- }
-
+
/**
* Used to calculate player jumping velocity for ground status calculation.
*/
diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java
index 006304f1a..cae5287be 100644
--- a/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java
+++ b/core/src/main/java/org/geysermc/geyser/level/physics/CollisionManager.java
@@ -34,7 +34,7 @@ import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
-import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
+import org.cloudburstmc.protocol.bedrock.packet.UpdateClientInputLocksPacket;
import org.geysermc.erosion.util.BlockPositionIterator;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
@@ -166,7 +166,7 @@ public class CollisionManager {
}
// We need to parse the float as a string since casting a float to a double causes us to
// lose precision and thus, causes players to get stuck when walking near walls
- double javaY = bedrockPosition.getY() - EntityDefinitions.PLAYER.offset();
+ double javaY = Double.parseDouble(Float.toString(bedrockPosition.getY() - EntityDefinitions.PLAYER.offset()));
Vector3d position = Vector3d.from(Double.parseDouble(Float.toString(bedrockPosition.getX())), javaY,
Double.parseDouble(Float.toString(bedrockPosition.getZ())));
@@ -197,18 +197,19 @@ public class CollisionManager {
return null;
}
- position = playerBoundingBox.getBottomCenter();
-
boolean newOnGround = adjustedMovement.getY() != movement.getY() && movement.getY() < 0 || onGround;
// Send corrected position to Bedrock if they differ by too much to prevent de-syncs
- if (onGround != newOnGround || movement.distanceSquared(adjustedMovement) > INCORRECT_MOVEMENT_THRESHOLD) {
+ if (onGround != newOnGround || position.distanceSquared(playerBoundingBox.getBottomCenter()) > INCORRECT_MOVEMENT_THRESHOLD) {
PlayerEntity playerEntity = session.getPlayerEntity();
// Client will dismount if on a vehicle
if (playerEntity.getVehicle() == null && pistonCache.getPlayerMotion().equals(Vector3f.ZERO) && !pistonCache.isPlayerSlimeCollision()) {
- playerEntity.moveAbsolute(position.toFloat(), playerEntity.getYaw(), playerEntity.getPitch(), playerEntity.getHeadYaw(), onGround, true);
+ recalculatePosition();
+ return null;
}
}
+ position = playerBoundingBox.getBottomCenter();
+
if (!newOnGround) {
// Trim the position to prevent rounding errors that make Java think we are clipping into a block
position = Vector3d.from(position.getX(), Double.parseDouble(DECIMAL_FORMAT.format(position.getY())), position.getZ());
@@ -217,18 +218,14 @@ public class CollisionManager {
return new CollisionResult(position, TriState.byBoolean(onGround));
}
- // TODO: This makes the player look upwards for some reason, rotation values must be wrong
public void recalculatePosition() {
PlayerEntity entity = session.getPlayerEntity();
- // Gravity might need to be reset...
- entity.updateBedrockMetadata(); // TODO may not be necessary
- MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
- movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
- movePlayerPacket.setPosition(entity.getPosition());
- movePlayerPacket.setRotation(entity.getBedrockRotation());
- movePlayerPacket.setMode(MovePlayerPacket.Mode.NORMAL);
- session.sendUpstreamPacket(movePlayerPacket);
+ // This does the job and won't interrupt velocity + rotation.
+ UpdateClientInputLocksPacket inputLocksPacket = new UpdateClientInputLocksPacket();
+ inputLocksPacket.setLockComponentData(0); // Don't actually lock anything.
+ inputLocksPacket.setServerPosition(entity.getPosition());
+ session.sendUpstreamPacket(inputLocksPacket);
}
public BlockPositionIterator collidableBlocksIterator(BoundingBox box) {
@@ -280,7 +277,15 @@ public class CollisionManager {
// Main correction code
for (iter.reset(); iter.hasNext(); iter.next()) {
- BlockCollision blockCollision = BlockUtils.getCollision(blocks[iter.getIteration()]);
+ final int blockId = blocks[iter.getIteration()];
+
+ // These block have different offset between BE and JE so we ignore them because if we "correct" the position
+ // it will lead to complication and more inaccurate movement.
+ if (session.getBlockMappings().getCollisionIgnoredBlocks().contains(blockId)) {
+ continue;
+ }
+
+ BlockCollision blockCollision = BlockUtils.getCollision(blockId);
if (blockCollision != null) {
if (!blockCollision.correctPosition(session, iter.getX(), iter.getY(), iter.getZ(), playerBoundingBox)) {
return false;
diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java
index 738658a8d..007bc889c 100644
--- a/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java
+++ b/core/src/main/java/org/geysermc/geyser/registry/populator/BlockRegistryPopulator.java
@@ -32,6 +32,7 @@ import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
@@ -243,6 +244,7 @@ public final class BlockRegistryPopulator {
.toList();
Map
@@ -42,24 +42,37 @@ import lombok.RequiredArgsConstructor;
@Data
public class TeleportCache {
- private static final double ERROR_X_AND_Z = 0.1;
- private static final double ERROR_Y = 0.1;
+ private static final float ERROR_X_AND_Z = 0.1f;
+ private static final float ERROR_Y = 0.1f;
/**
* How many move packets the teleport can be unconfirmed for before it gets resent to the client
*/
private static final int RESEND_THRESHOLD = 20; // Make it one full second with auth input
- private final double x, y, z;
+ public TeleportCache(Vector3f position, float pitch, float yaw, int teleportConfirmId) {
+ this.position = position;
+ this.velocity = Vector3f.ZERO;
+ this.pitch = pitch;
+ this.yaw = yaw;
+ this.teleportConfirmId = teleportConfirmId;
+ this.teleportType = TeleportType.NORMAL;
+ }
+
+ private final Vector3f position;
+ private final Vector3f velocity;
private final float pitch, yaw;
private final int teleportConfirmId;
+ private final TeleportType teleportType;
private int unconfirmedFor = 0;
- public boolean canConfirm(Vector3d position) {
- return (Math.abs(this.x - position.getX()) < ERROR_X_AND_Z &&
- Math.abs(this.y - position.getY()) < ERROR_Y &&
- Math.abs(this.z - position.getZ()) < ERROR_X_AND_Z);
+ public boolean canConfirm(Vector3f position) {
+ final float distanceX = Math.abs(this.position.getX() - position.getX());
+ final float distanceY = Math.abs(this.position.getY() - position.getY());
+ final float distanceZ = Math.abs(this.position.getZ() - position.getZ());
+
+ return distanceX < ERROR_X_AND_Z && distanceY < ERROR_Y && distanceZ < ERROR_X_AND_Z;
}
public void incrementUnconfirmedFor() {
@@ -73,4 +86,9 @@ public class TeleportCache {
public boolean shouldResend() {
return unconfirmedFor >= RESEND_THRESHOLD;
}
+
+ public enum TeleportType {
+ NORMAL,
+ KEEP_VELOCITY;
+ }
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockMovePlayer.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockMovePlayer.java
index 9bad0b830..ca844a388 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockMovePlayer.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/input/BedrockMovePlayer.java
@@ -28,9 +28,13 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player.input;
import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
+import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
import org.geysermc.geyser.entity.EntityDefinitions;
+import org.geysermc.geyser.entity.type.BoatEntity;
+import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
+import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.level.physics.CollisionResult;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
@@ -55,11 +59,12 @@ final class BedrockMovePlayer {
// Ignore movement packets until Bedrock's position matches the teleported position
if (session.getUnconfirmedTeleport() != null) {
- session.confirmTeleport(packet.getPosition().toDouble().sub(0, EntityDefinitions.PLAYER.offset(), 0));
+ session.confirmTeleport(packet.getPosition().sub(0, EntityDefinitions.PLAYER.offset(), 0));
return;
}
- boolean actualPositionChanged = !entity.getPosition().equals(packet.getPosition());
+ // This is vanilla behaviour, LocalPlayer#sendPosition 1.21.8.
+ boolean actualPositionChanged = entity.getPosition().distanceSquared(packet.getPosition()) > 4e-8;
if (actualPositionChanged) {
// Send book update before the player moves
@@ -96,14 +101,47 @@ final class BedrockMovePlayer {
// Client is telling us it wants to move down, but something is blocking it from doing so.
boolean isOnGround;
- if (hasVehicle) {
+ if (hasVehicle || session.isNoClip()) {
// VERTICAL_COLLISION is not accurate while in a vehicle (as of 1.21.62)
// If the player is riding a vehicle or is in spectator mode, onGround is always set to false for the player
+ // Also do this if player have no clip ability since they shouldn't be able to collide with anything.
isOnGround = false;
} else {
isOnGround = packet.getInputData().contains(PlayerAuthInputData.VERTICAL_COLLISION) && entity.getLastTickEndVelocity().getY() < 0;
}
+ // Resolve https://github.com/GeyserMC/Geyser/issues/3521, no void floor on java so player not supposed to collide with anything.
+ // Therefore, we're fixing this by allowing player to no clip to clip through the floor, not only this fixed the issue but
+ // player y velocity should match java perfectly, much better than teleport player right down :)
+ // Shouldn't mess with anything because beyond this point there is nothing to collide and not even entities since they're prob dead.
+ if (packet.getPosition().getY() - EntityDefinitions.PLAYER.offset() < session.getBedrockDimension().minY() - 5) {
+ // Ensuring that we still can collide with collidable entity that are also in the void (eg: boat, shulker)
+ boolean possibleOnGround = false;
+
+ BoundingBox boundingBox = session.getCollisionManager().getPlayerBoundingBox().clone();
+
+ // Extend down by y velocity subtract by 2 so that we are a "little" ahead and can send no clip in time before player hit the entity.
+ boundingBox.extend(0, packet.getDelta().getY() - 2, 0);
+
+ for (Entity other : session.getEntityCache().getEntities().values()) {
+ if (!other.getFlag(EntityFlag.COLLIDABLE)) {
+ continue;
+ }
+
+ final BoundingBox entityBoundingBox = new BoundingBox(0, 0, 0, other.getBoundingBoxWidth(), other.getBoundingBoxHeight(), other.getBoundingBoxWidth());
+
+ // Also offset the position down for boat as their position is offset.
+ entityBoundingBox.translate(other.getPosition().down(other instanceof BoatEntity ? entity.getDefinition().offset() : 0).toDouble());
+
+ if (entityBoundingBox.checkIntersection(boundingBox)) {
+ possibleOnGround = true;
+ break;
+ }
+ }
+
+ session.setNoClip(!possibleOnGround);
+ }
+
entity.setLastTickEndVelocity(packet.getDelta());
entity.setMotion(packet.getDelta());
@@ -135,35 +173,6 @@ final class BedrockMovePlayer {
CollisionResult result = session.getCollisionManager().adjustBedrockPosition(packet.getPosition(), isOnGround, packet.getInputData().contains(PlayerAuthInputData.HANDLE_TELEPORT));
if (result != null) { // A null return value cancels the packet
Vector3d position = result.correctedMovement();
- boolean isBelowVoid = entity.isVoidPositionDesynched();
-
- boolean teleportThroughVoidFloor, mustResyncPosition;
- // Compare positions here for void floor fix below before the player's position variable is set to the packet position
- if (entity.getPosition().getY() >= packet.getPosition().getY() && !isBelowVoid) {
- int floorY = position.getFloorY();
- int voidFloorLocation = entity.voidFloorPosition();
- teleportThroughVoidFloor = floorY <= (voidFloorLocation + 1) && floorY >= voidFloorLocation;
- } else {
- teleportThroughVoidFloor = false;
- }
-
- if (teleportThroughVoidFloor || isBelowVoid) {
- // https://github.com/GeyserMC/Geyser/issues/3521 - no void floor in Java so we cannot be on the ground.
- isOnGround = false;
- }
-
- if (isBelowVoid) {
- int floorY = position.getFloorY();
- int voidFloorLocation = entity.voidFloorPosition();
- mustResyncPosition = floorY < voidFloorLocation && floorY >= voidFloorLocation - 1;
- } else {
- mustResyncPosition = false;
- }
-
- double yPosition = position.getY();
- if (entity.isVoidPositionDesynched()) { // not using the cached variable on purpose
- yPosition += 4; // We are de-synched since we had to teleport below the void floor.
- }
Packet movePacket;
if (rotationChanged) {
@@ -171,7 +180,7 @@ final class BedrockMovePlayer {
movePacket = new ServerboundMovePlayerPosRotPacket(
isOnGround,
horizontalCollision,
- position.getX(), yPosition, position.getZ(),
+ position.getX(), position.getY(), position.getZ(),
yaw, pitch
);
entity.setYaw(yaw);
@@ -179,7 +188,7 @@ final class BedrockMovePlayer {
entity.setHeadYaw(headYaw);
} else {
// Rotation did not change; don't send an update with rotation
- movePacket = new ServerboundMovePlayerPosPacket(isOnGround, horizontalCollision, position.getX(), yPosition, position.getZ());
+ movePacket = new ServerboundMovePlayerPosPacket(isOnGround, horizontalCollision, position.getX(), position.getY(), position.getZ());
}
entity.setPositionManual(packet.getPosition());
@@ -187,12 +196,6 @@ final class BedrockMovePlayer {
// Send final movement changes
session.sendDownstreamGamePacket(movePacket);
- if (teleportThroughVoidFloor) {
- entity.teleportVoidFloorFix(false);
- } else if (mustResyncPosition) {
- entity.teleportVoidFloorFix(true);
- }
-
session.getInputCache().markPositionPacketSent();
session.getSkullCache().updateVisibleSkulls();
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java
index 1c3ac4688..e8f99fbea 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java
@@ -26,6 +26,7 @@
package org.geysermc.geyser.translator.protocol.java.entity;
import org.checkerframework.checker.nullness.qual.NonNull;
+import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
@@ -58,7 +59,7 @@ public class JavaSetPassengersTranslator extends PacketTranslator