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 @@ -140,6 +140,11 @@ public void updateRotation(float yaw, float pitch, boolean isOnGround) {
moveRelative(0, 0, 0, yaw + 90, 0, 0, isOnGround);
}

@Override
public Vector3f position() {
return this.position.down(definition.offset());
}

public void setPaddlingLeft(BooleanEntityMetadata entityMetadata) {
isPaddlingLeft = entityMetadata.getPrimitiveValue();
if (!isPaddlingLeft) {
Expand Down
22 changes: 22 additions & 0 deletions core/src/main/java/org/geysermc/geyser/entity/type/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.geysermc.geyser.entity.properties.type.PropertyType;
import org.geysermc.geyser.entity.type.living.MobEntity;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
import org.geysermc.geyser.item.Items;
import org.geysermc.geyser.item.type.Item;
Expand Down Expand Up @@ -247,6 +248,10 @@ public void despawnEntity() {
passenger.setVehicle(null);
passenger.setFlag(EntityFlag.RIDING, false);
passenger.updateBedrockMetadata();

if (passenger instanceof SessionPlayerEntity playerEntity) {
playerEntity.setLastRemovedVehicle(this.entityId);
}
}

RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket();
Expand All @@ -256,6 +261,14 @@ public void despawnEntity() {
valid = false;
}

/**
* Set the player's position without applying an offset or moving the bounding box
* @param position the new position of the Bedrock player
*/
public void setPositionManual(Vector3f position) {
this.position = position;
}

public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) {
moveRelative(relX, relY, relZ, yaw, pitch, getHeadYaw(), isOnGround);
}
Expand Down Expand Up @@ -438,6 +451,15 @@ public void setFlags(ByteEntityMetadata entityMetadata) {
setInvisible((xd & 0x20) == 0x20);
}

/**
* Gets the position of the entity without it being offset.
*
* @return the position of the entity without the offset value
*/
public Vector3f position() {
return this.position;
}

/**
* Set a boolean - whether the entity is invisible or visible
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ protected void moveAbsoluteImmediate(Vector3f position, float yaw, float pitch,
.thenApply(BlockStateValues::getWaterLevel);
}

@Override
public Vector3f position() {
float offset = definition.offset();
return this.position.down(waterLevel.join() == 0 ? -offset : offset);
}

@Override
protected float getGravity() {
if (getFlag(EntityFlag.HAS_GRAVITY) && !isOnGround() && !isInWater()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ public Vector3f getBedrockRotation() {
return Vector3f.from(0, getYaw(), 0);
}

@Override
public Vector3f position() {
return this.position.down(definition.offset());
}

@Override
public boolean doesJumpDismount() {
// This is a little bit misleading because jumping is literally the only way to dismount for Touch users.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYa
super.moveAbsolute(position.add(Vector3f.from(0, definition.offset(), 0)), yaw, pitch, headYaw, isOnGround, teleported);
}

@Override
public Vector3f position() {
return this.position.down(definition.offset());
}

public void setFuseLength(IntEntityMetadata entityMetadata) {
currentTick = entityMetadata.getPrimitiveValue();
setFlag(EntityFlag.IGNITED, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYa
super.moveAbsolute(position.add(0, calculateLineOffset(), 0), yaw, pitch, headYaw, isOnGround, teleported);
}

@Override
public Vector3f position() {
return this.position.down(definition.offset());
}

@Override
protected void initializeMetadata() {
super.initializeMetadata();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

/**
Expand Down Expand Up @@ -129,6 +130,12 @@ public class SessionPlayerEntity extends PlayerEntity {

@Getter @Setter
private float javaYaw;

/**
* The vehicle that player was previously in before it got removed from the world.
*/
@Getter @Setter
private Integer lastRemovedVehicle = null;

public SessionPlayerEntity(GeyserSession session) {
super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null);
Expand Down Expand Up @@ -215,7 +222,7 @@ public void updateOwnRotation(float yaw, float pitch, float headYaw) {
* @param position the new position of the Bedrock player
*/
public void setPositionManual(Vector3f position) {
this.position = position;
super.setPositionManual(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) {
Expand Down Expand Up @@ -476,6 +483,9 @@ public void setVehicle(Entity entity) {
this.vehicle.updateBedrockMetadata();
}

if (entity != null) {
this.lastRemovedVehicle = null;
}
// Bedrock player can dismount by pressing jump while Java cannot, so we need to prevent player from jumping to match vanilla behaviour.
this.session.setLockInput(InputLocksFlag.JUMP, entity != null && entity.doesJumpDismount());
this.session.updateInputLocks();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.geysermc.geyser.entity.type.FishingHookEntity;
import org.geysermc.geyser.entity.type.HangingEntity;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.skin.SkinManager;
Expand Down Expand Up @@ -61,6 +62,12 @@ public void translate(GeyserSession session, ClientboundAddEntityPacket packet)
return;
}

final SessionPlayerEntity playerEntity = session.getPlayerEntity();
Integer lastRemovedVehicle = session.getPlayerEntity().getLastRemovedVehicle();
if (lastRemovedVehicle != null && lastRemovedVehicle == packet.getEntityId()) {
playerEntity.setLastRemovedVehicle(null);
}

Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
Vector3f motion = packet.getMovement().toFloat();
float yaw = packet.getYaw();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,74 @@

package org.geysermc.geyser.translator.protocol.java.entity;

import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import org.geysermc.geyser.util.MathUtils;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PositionElement;
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.ClientboundTeleportEntityPacket;
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosRotPacket;

@Translator(packet = ClientboundTeleportEntityPacket.class)
public class JavaTeleportEntityTranslator extends PacketTranslator<ClientboundTeleportEntityPacket> {

@Override
public void translate(GeyserSession session, ClientboundTeleportEntityPacket packet) {
session.getGeyser().getLogger().debug(packet.toString());
boolean sendPosition = false;

Entity entity = session.getEntityCache().getEntityByJavaId(packet.getId());
Integer lastRemovedVehicle = session.getPlayerEntity().getLastRemovedVehicle();
if (lastRemovedVehicle != null && packet.getId() == lastRemovedVehicle) {
entity = session.getPlayerEntity();
sendPosition = true;
}

if (entity == null) return;

Vector3d position = packet.getPosition();

position = position.add(
packet.getRelatives().contains(PositionElement.X) ? entity.getPosition().getX() : 0,
packet.getRelatives().contains(PositionElement.Y) ? entity.position().getY() : 0,
packet.getRelatives().contains(PositionElement.Z) ? entity.getPosition().getZ() : 0);

float newPitch = MathUtils.clamp(packet.getXRot() + (packet.getRelatives().contains(PositionElement.X_ROT) ? entity.getPitch() : 0), -90, 90);
float newYaw = packet.getYRot() + (packet.getRelatives().contains(PositionElement.Y_ROT) ? entity.getYaw() : 0);

float lastPitch = entity.getPitch(), lastYaw = entity.getYaw();
if (position.distanceSquared(entity.position().toDouble()) > 4096.0) {
entity.teleport(position.toFloat(), newYaw, newPitch, packet.isOnGround());
} else {
final Vector3d currentPosition = entity.position().toDouble();
entity.moveRelative(position.getX() - currentPosition.getX(), position.getY() - currentPosition.getY(), position.getZ() - currentPosition.getZ(),
newYaw, newPitch, packet.isOnGround());
}

Vector3f deltaMovement = packet.getDeltaMovement().toFloat().add(
packet.getRelatives().contains(PositionElement.DELTA_X) ? entity.getMotion().getX() : 0,
packet.getRelatives().contains(PositionElement.DELTA_Y) ? entity.getMotion().getY() : 0,
packet.getRelatives().contains(PositionElement.DELTA_Z) ? entity.getMotion().getZ() : 0
);

if (packet.getRelatives().contains(PositionElement.ROTATE_DELTA)) {
deltaMovement = MathUtils.xYRot(deltaMovement, (float) Math.toRadians(lastPitch - newPitch), (float) Math.toRadians(lastYaw - newYaw));
}

if (deltaMovement.distanceSquared(Vector3f.ZERO) > 1.0E-8F) {
entity.setMotion(deltaMovement);
SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
entityMotionPacket.setRuntimeEntityId(entity.getGeyserId());
entityMotionPacket.setMotion(entity.getMotion());
session.sendUpstreamPacket(entityMotionPacket);
}

if (sendPosition) {
ServerboundMovePlayerPosRotPacket positionPacket = new ServerboundMovePlayerPosRotPacket(false, false, position.getX(), position.getY(), position.getZ(), newYaw, newPitch);
session.sendDownstreamGamePacket(positionPacket);
}
}
}