From 774d3670c5a193f1807b4e5a376703baccfd55e4 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 26 Oct 2024 01:27:55 -0400 Subject: [PATCH] Horses are still weird, but boats are mostly working --- .../geysermc/geyser/entity/type/Entity.java | 5 - .../entity/vehicle/VehicleComponent.java | 1 - .../geyser/session/GeyserSession.java | 6 - .../geyser/session/cache/InputCache.java | 10 ++ .../geyser/session/cache/TeleportCache.java | 2 +- .../BedrockMoveEntityAbsoluteTranslator.java | 8 +- .../bedrock/BedrockPlayerInputTranslator.java | 41 ------- .../player/BedrockMovePlayerTranslator.java | 27 ++--- .../BedrockPlayerAuthInputTranslator.java | 103 +++++++++++++++++- .../org/geysermc/geyser/util/MathUtils.java | 11 ++ 10 files changed, 138 insertions(+), 76 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 7f1eca8d6..0d3214709 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -701,9 +701,4 @@ public class Entity implements GeyserEntity { packet.setData(data); session.sendUpstreamPacket(packet); } - - @SuppressWarnings("unchecked") - public @Nullable I as(Class entityClass) { - return entityClass.isInstance(this) ? (I) this : null; - } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java b/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java index 4f4a46dc9..91f54162b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java +++ b/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java @@ -758,7 +758,6 @@ public class VehicleComponent { ServerboundMoveVehiclePacket moveVehiclePacket = new ServerboundMoveVehiclePacket(javaPos.getX(), javaPos.getY(), javaPos.getZ(), rotation.getX(), rotation.getY()); vehicle.getSession().sendDownstreamPacket(moveVehiclePacket); - vehicle.getSession().setLastVehicleMoveTimestamp(System.currentTimeMillis()); } protected double getGravity() { diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 9b9e86bb2..dd8fdd59b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -524,12 +524,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource { @Setter private boolean placedBucket; - /** - * Used to send a ServerboundMoveVehiclePacket for every PlayerInputPacket after idling on a boat/horse for more than 100ms - */ - @Setter - private long lastVehicleMoveTimestamp = System.currentTimeMillis(); - /** * Counts how many ticks have occurred since an arm animation started. * -1 means there is no active arm swing; -2 means an arm swing will start in a tick. diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java index b59df0c16..c666ded64 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/InputCache.java @@ -25,6 +25,8 @@ package org.geysermc.geyser.session.cache; +import lombok.Getter; +import lombok.Setter; import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData; import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; import org.geysermc.geyser.session.GeyserSession; @@ -37,6 +39,10 @@ public final class InputCache { private ServerboundPlayerInputPacket inputPacket = new ServerboundPlayerInputPacket(false, false, false, false, false, false, false); private boolean lastHorizontalCollision; private int ticksSinceLastMovePacket; + @Getter @Setter + private int jumpingTicks; + @Getter @Setter + private float jumpScale; public InputCache(GeyserSession session) { this.session = session; @@ -61,6 +67,10 @@ public final class InputCache { } } + public boolean wasJumping() { + return this.inputPacket.isJump(); + } + public void markPositionPacketSent() { this.ticksSinceLastMovePacket = 0; } diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java index 80139a988..7a7a5f1e2 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/TeleportCache.java @@ -48,7 +48,7 @@ public class TeleportCache { /** * How many move packets the teleport can be unconfirmed for before it gets resent to the client */ - private static final int RESEND_THRESHOLD = 5; + private static final int RESEND_THRESHOLD = 20; // Make it one full second with auth input private final double x, y, z; private final float pitch, yaw; diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java index f2d69d51c..81b06c87d 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockMoveEntityAbsoluteTranslator.java @@ -42,17 +42,15 @@ public class BedrockMoveEntityAbsoluteTranslator extends PacketTranslator= 100) { - Vector3f vehiclePosition = vehicle.getPosition(); - - if (vehicle instanceof BoatEntity && !vehicle.isOnGround()) { - // Remove some Y position to prevents boats flying up - vehiclePosition = vehiclePosition.down(vehicle.getDefinition().offset()); - } - - ServerboundMoveVehiclePacket moveVehiclePacket = new ServerboundMoveVehiclePacket( - vehiclePosition.getX(), vehiclePosition.getY(), vehiclePosition.getZ(), - vehicle.getYaw() - 90, vehicle.getPitch() - ); - session.sendDownstreamGamePacket(moveVehiclePacket); - } - } } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java index a22c44089..1940258e4 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java @@ -31,7 +31,6 @@ import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData; import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; -import org.geysermc.geyser.entity.vehicle.ClientVehicle; import org.geysermc.geyser.level.physics.CollisionResult; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; @@ -48,17 +47,17 @@ public final class BedrockMovePlayerTranslator { SessionPlayerEntity entity = session.getPlayerEntity(); if (!session.isSpawned()) return; + // 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)); + return; + } + boolean actualPositionChanged = !entity.getPosition().equals(packet.getPosition()); if (actualPositionChanged) { // Send book update before the player moves session.getBookEditCache().checkForSend(); - - // 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)); - return; - } } if (entity.getBedPosition() != null) { @@ -72,9 +71,11 @@ public final class BedrockMovePlayerTranslator { float pitch = packet.getRotation().getX(); float headYaw = packet.getRotation().getY(); - // shouldSendPositionReminder also increments a tick counter, so make sure it's always called. - boolean positionChanged = session.getInputCache().shouldSendPositionReminder() || actualPositionChanged; - boolean rotationChanged = entity.getYaw() != yaw || entity.getPitch() != pitch || entity.getHeadYaw() != headYaw; + boolean hasVehicle = entity.getVehicle() != null; + + // shouldSendPositionReminder also increments a tick counter, so make sure it's always called unless the player is on a vehicle. + boolean positionChanged = !hasVehicle && session.getInputCache().shouldSendPositionReminder() || actualPositionChanged; + boolean rotationChanged = hasVehicle || (entity.getYaw() != yaw || entity.getPitch() != pitch || entity.getHeadYaw() != headYaw); if (session.getLookBackScheduledFuture() != null) { // Resend the rotation if it was changed by Geyser @@ -99,12 +100,6 @@ public final class BedrockMovePlayerTranslator { session.sendDownstreamGamePacket(playerRotationPacket); } else if (positionChanged) { - // World border collision will be handled by client vehicle - if (!(entity.getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) - && session.getWorldBorder().isPassingIntoBorderBoundaries(packet.getPosition(), true)) { - return; - } - if (isValidMove(session, entity.getPosition(), packet.getPosition())) { CollisionResult result = session.getCollisionManager().adjustBedrockPosition(packet.getPosition(), packet.getInputData().contains(PlayerAuthInputData.HANDLE_TELEPORT)); if (result != null) { // A null return value cancels the packet diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java index 5465de51c..0889579c2 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockPlayerAuthInputTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.bedrock.entity.player; +import org.cloudburstmc.math.vector.Vector2f; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.LevelEvent; @@ -36,19 +37,25 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket; import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket; 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.ItemFrameEntity; +import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity; +import org.geysermc.geyser.entity.type.living.animal.horse.LlamaEntity; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; +import org.geysermc.geyser.entity.vehicle.ClientVehicle; import org.geysermc.geyser.level.block.type.Block; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator; +import org.geysermc.geyser.util.MathUtils; import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction; import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState; +import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket; import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket; @@ -57,13 +64,17 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.Serv import java.util.Set; @Translator(packet = PlayerAuthInputPacket.class) -public class BedrockPlayerAuthInputTranslator extends PacketTranslator { +public final class BedrockPlayerAuthInputTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, PlayerAuthInputPacket packet) { SessionPlayerEntity entity = session.getPlayerEntity(); + + boolean wasJumping = session.getInputCache().wasJumping(); session.getInputCache().processInputs(packet); + processVehicleInput(session, packet, wasJumping); + BedrockMovePlayerTranslator.translate(session, packet); Set inputData = packet.getInputData(); @@ -202,4 +213,94 @@ public class BedrockPlayerAuthInputTranslator extends PacketTranslator truncated ? truncated + 1 : truncated; } + /** + * Round the given float to the previous whole number + * + * @param floatNumber Float to round + * @return Rounded number + */ + public static int floor(float floatNumber) { + int truncated = (int) floatNumber; + return floatNumber < truncated ? truncated - 1 : truncated; + } + /** * If number is greater than the max, set it to max, and if number is lower than low, set it to low. *