From 7791c0d4418a5838cc45d4e76a50f3ea1b7e768b Mon Sep 17 00:00:00 2001 From: oryxel1 Date: Mon, 22 Sep 2025 22:22:05 +0700 Subject: [PATCH] Make this compile. --- .../type/player/SessionPlayerEntity.java | 6 +++ .../geyser/level/physics/BoundingBox.java | 41 +++++++++++++++ .../level/physics/CollisionManager.java | 32 +++--------- .../collision/DirtPathCollision.java | 51 ------------------- .../collision/fixes/ScaffoldingCollision.java | 5 +- .../player/input/BedrockMovePlayer.java | 10 ++-- .../protocol/java/JavaRespawnTranslator.java | 3 ++ .../geysermc/geyser/util/DimensionUtils.java | 2 + 8 files changed, 66 insertions(+), 84 deletions(-) delete mode 100644 core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java 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 145421a5f..8208fd02a 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 @@ -129,6 +129,12 @@ public class SessionPlayerEntity extends PlayerEntity { @Getter @Setter private float javaYaw; + /** + * If the player is colliding on the vertical axis or not according to the client. + */ + @Getter @Setter + private boolean collidingVertically; + public SessionPlayerEntity(GeyserSession session) { super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null); diff --git a/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java b/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java index 77aec1336..21c0d50af 100644 --- a/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java +++ b/core/src/main/java/org/geysermc/geyser/level/physics/BoundingBox.java @@ -142,6 +142,47 @@ public class BoundingBox implements Cloneable { }; } + public void pushOutOfBoundingBox(BoundingBox playerBox, Direction direction, double maxPushTolerance) { + switch (direction) { + case NORTH -> { + double distance = this.getMin(Axis.Z) - playerBox.getMax(Axis.Z); + if (Math.abs(distance) < maxPushTolerance) { + playerBox.translate(0, 0, distance); + } + } + case SOUTH -> { + double distance = this.getMax(Axis.Z) - playerBox.getMin(Axis.Z); + if (Math.abs(distance) < maxPushTolerance) { + playerBox.translate(0, 0, distance); + } + } + case EAST -> { + double distance = this.getMax(Axis.X) - playerBox.getMin(Axis.X); + if (Math.abs(distance) < maxPushTolerance) { + playerBox.translate(distance, 0, 0); + } + } + case WEST -> { + double distance = this.getMin(Axis.X) - playerBox.getMax(Axis.X); + if (Math.abs(distance) < maxPushTolerance) { + playerBox.translate(distance, 0, 0); + } + } + case UP -> { + double distance = this.getMax(Axis.Y) - playerBox.getMin(Axis.Y); + if (Math.abs(distance) < maxPushTolerance) { + playerBox.translate(0, distance, 0); + } + } + case DOWN -> { + double distance = this.getMin(Axis.Y) - playerBox.getMax(Axis.Y); + if (Math.abs(distance) < maxPushTolerance) { + playerBox.translate(0, distance, 0); + } + } + } + } + /** * Find the maximum offset of another bounding box in an axis that will not collide with this bounding box * 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 2b6107729..0e980029e 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 @@ -168,8 +168,7 @@ public class CollisionManager { // lose precision and thus, causes players to get stuck when walking near walls 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()))); + Vector3d position = Vector3d.from(Double.parseDouble(Float.toString(bedrockPosition.getX())), javaY, Double.parseDouble(Float.toString(bedrockPosition.getZ()))); // Don't correct position if controlling a vehicle if (session.getPlayerEntity().getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) { @@ -186,11 +185,8 @@ public class CollisionManager { playerBoundingBox.translate(adjustedMovement.getX(), adjustedMovement.getY(), adjustedMovement.getZ()); playerBoundingBox.translate(pistonCache.getPlayerMotion().getX(), pistonCache.getPlayerMotion().getY(), pistonCache.getPlayerMotion().getZ()); // Correct player position - if (!correctPlayerPosition()) { - // Cancel the movement if it needs to be cancelled - recalculatePosition(); - return null; - } + correctPlayerPosition(); + // The server can't complain about our movement if we never send it // TODO get rid of this and handle teleports smoothly if (pistonCache.isPlayerCollided()) { @@ -229,9 +225,7 @@ public class CollisionManager { } public BlockPositionIterator collidableBlocksIterator(BoundingBox box) { - Vector3d position = Vector3d.from(box.getMiddleX(), - box.getMiddleY() - (box.getSizeY() / 2), - box.getMiddleZ()); + Vector3d position = Vector3d.from(box.getMiddleX(), box.getMiddleY() - (box.getSizeY() / 2), box.getMiddleZ()); // Expand volume by 1 in each direction to include moving blocks double pistonExpand = session.getPistonCache().getPistons().isEmpty() ? 0 : 1; @@ -255,12 +249,10 @@ public class CollisionManager { } /** - * Returns false if the movement is invalid, and in this case it shouldn't be sent to the server and should be - * cancelled + * Silently compensate for movement problems due to collision and floating points errors on bedrock. * See {@link BlockCollision#correctPosition(GeyserSession, int, int, int, BoundingBox)} for more info */ - public boolean correctPlayerPosition() { - + public void correctPlayerPosition() { // These may be set to true by the correctPosition method in ScaffoldingCollision touchingScaffolding = false; onScaffolding = false; @@ -268,12 +260,6 @@ public class CollisionManager { // Used when correction code needs to be run before the main correction BlockPositionIterator iter = session.getCollisionManager().playerCollidableBlocksIterator(); int[] blocks = session.getGeyser().getWorldManager().getBlocksAt(session, iter); - for (iter.reset(); iter.hasNext(); iter.next()) { - BlockCollision blockCollision = BlockUtils.getCollision(blocks[iter.getIteration()]); - if (blockCollision != null) { - blockCollision.beforeCorrectPosition(iter.getX(), iter.getY(), iter.getZ(), playerBoundingBox); - } - } // Main correction code for (iter.reset(); iter.hasNext(); iter.next()) { @@ -287,15 +273,11 @@ public class CollisionManager { BlockCollision blockCollision = BlockUtils.getCollision(blockId); if (blockCollision != null) { - if (!blockCollision.correctPosition(session, iter.getX(), iter.getY(), iter.getZ(), playerBoundingBox)) { - return false; - } + blockCollision.correctPosition(session, iter.getX(), iter.getY(), iter.getZ(), playerBoundingBox); } } updateScaffoldingFlags(true); - - return true; } public Vector3d correctPlayerMovement(Vector3d movement, boolean checkWorld, boolean teleported) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java deleted file mode 100644 index d44187a0c..000000000 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/DirtPathCollision.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.translator.collision; - -import lombok.EqualsAndHashCode; -import org.geysermc.geyser.level.block.type.BlockState; -import org.geysermc.geyser.level.physics.BoundingBox; -import org.geysermc.geyser.level.physics.CollisionManager; - -@EqualsAndHashCode(callSuper = true) -@CollisionRemapper(regex = "^dirt_path$", passDefaultBoxes = true) -public class DirtPathCollision extends BlockCollision { - public DirtPathCollision(BlockState state, BoundingBox[] defaultBoxes) { - super(defaultBoxes); - } - - // Needs to run before the main correction code or it can move the player into blocks - // This is counteracted by the main collision code pushing them out - @Override - public void beforeCorrectPosition(int x, int y, int z, BoundingBox playerCollision) { - // In Bedrock, dirt paths are solid blocks, so the player must be pushed down. - double playerMinY = playerCollision.getMiddleY() - (playerCollision.getSizeY() / 2); - double blockMaxY = y + 1; - if (Math.abs(blockMaxY - playerMinY) <= CollisionManager.COLLISION_TOLERANCE) { - playerCollision.translate(0, -0.0625, 0); - } - } -} diff --git a/core/src/main/java/org/geysermc/geyser/translator/collision/fixes/ScaffoldingCollision.java b/core/src/main/java/org/geysermc/geyser/translator/collision/fixes/ScaffoldingCollision.java index 7a0265303..526b9dd09 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/collision/fixes/ScaffoldingCollision.java +++ b/core/src/main/java/org/geysermc/geyser/translator/collision/fixes/ScaffoldingCollision.java @@ -50,7 +50,7 @@ public class ScaffoldingCollision extends BlockCollision { } @Override - public boolean correctPosition(GeyserSession session, int x, int y, int z, BoundingBox playerCollision) { + public void correctPosition(GeyserSession session, int x, int y, int z, BoundingBox playerCollision) { // Hack to not check below the player playerCollision.setSizeY(playerCollision.getSizeY() - 0.001); playerCollision.setMiddleY(playerCollision.getMiddleY() + 0.002); @@ -86,8 +86,5 @@ public class ScaffoldingCollision extends BlockCollision { playerCollision.setSizeY(playerCollision.getSizeY() - 0.001); playerCollision.setMiddleY(playerCollision.getMiddleY() + 0.002); } - - // Normal move correction isn't really needed for scaffolding - return true; } } 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 195f5dcea..a78b46750 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 @@ -110,6 +110,8 @@ final class BedrockMovePlayer { entity.setLastTickEndVelocity(Vector3f.from(entity.getLastTickEndVelocity().getX(), 0.2F, entity.getLastTickEndVelocity().getZ())); } + entity.setCollidingVertically(packet.getInputData().contains(PlayerAuthInputData.VERTICAL_COLLISION)); + // Client is telling us it wants to move down, but something is blocking it from doing so. boolean isOnGround; if (hasVehicle || session.isNoClip()) { @@ -118,7 +120,7 @@ final class BedrockMovePlayer { // 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; + isOnGround = entity.isCollidingVertically() && 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. @@ -157,9 +159,6 @@ final class BedrockMovePlayer { session.setNoClip(!possibleOnGround); } - entity.setLastTickEndVelocity(packet.getDelta()); - entity.setMotion(packet.getDelta()); - // This takes into account no movement sent from the client, but the player is trying to move anyway. // (Press into a wall in a corner - you're trying to move but nothing actually happens) // This isn't sent when a player is riding a vehicle (as of 1.21.62) @@ -231,6 +230,9 @@ final class BedrockMovePlayer { session.getInputCache().setLastHorizontalCollision(horizontalCollision); entity.setOnGround(isOnGround); + entity.setLastTickEndVelocity(packet.getDelta()); + entity.setMotion(packet.getDelta()); + // Move parrots to match if applicable if (entity.getLeftParrot() != null) { entity.getLeftParrot().moveAbsolute(entity.getPosition(), entity.getYaw(), entity.getPitch(), entity.getHeadYaw(), true, false); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java index 7bcbb9c40..67eeea7cc 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaRespawnTranslator.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.translator.protocol.java; +import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket; import org.geysermc.geyser.entity.attribute.GeyserAttributeType; import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; @@ -57,6 +58,8 @@ public class JavaRespawnTranslator extends PacketTranslator