forked from GeyserMC/Geyser
Send position update every 3 seconds if idle (#1421)
* Send position update every 3 seconds if idle Prevents timeouts in certain instances when AFK. * Cancel position sending on dimension switching * Remove debug lines * Create function to centralize movement translation
This commit is contained in:
parent
3e0d898b6a
commit
69d4d9f0d6
3 changed files with 55 additions and 11 deletions
|
@ -221,6 +221,12 @@ public class GeyserSession implements CommandSender {
|
||||||
@Setter
|
@Setter
|
||||||
private ScheduledFuture<?> bucketScheduledFuture;
|
private ScheduledFuture<?> bucketScheduledFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a movement packet every three seconds if the player hasn't moved. Prevents timeouts when AFK in certain instances.
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
private ScheduledFuture<?> movementSendIfIdle;
|
||||||
|
|
||||||
private boolean reducedDebugInfo = false;
|
private boolean reducedDebugInfo = false;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
|
|
|
@ -25,7 +25,13 @@
|
||||||
|
|
||||||
package org.geysermc.connector.network.translators.bedrock.entity.player;
|
package org.geysermc.connector.network.translators.bedrock.entity.player;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionPacket;
|
||||||
|
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
|
||||||
import com.nukkitx.math.vector.Vector3d;
|
import com.nukkitx.math.vector.Vector3d;
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||||
import org.geysermc.connector.common.ChatColor;
|
import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.PlayerEntity;
|
import org.geysermc.connector.entity.PlayerEntity;
|
||||||
|
@ -34,11 +40,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
import org.geysermc.connector.network.translators.Translator;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
|
import java.util.concurrent.TimeUnit;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
|
||||||
|
|
||||||
@Translator(packet = MovePlayerPacket.class)
|
@Translator(packet = MovePlayerPacket.class)
|
||||||
public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPacket> {
|
public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPacket> {
|
||||||
|
@ -59,13 +61,11 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to parse the float as a string since casting a float to a double causes us to
|
if (session.getMovementSendIfIdle() != null) {
|
||||||
// lose precision and thus, causes players to get stuck when walking near walls
|
session.getMovementSendIfIdle().cancel(true);
|
||||||
double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset();
|
}
|
||||||
if (packet.isOnGround()) javaY = Math.ceil(javaY * 2) / 2;
|
|
||||||
|
|
||||||
Vector3d position = Vector3d.from(Double.parseDouble(Float.toString(packet.getPosition().getX())), javaY,
|
Vector3d position = adjustBedrockPosition(packet.getPosition(), packet.isOnGround());
|
||||||
Double.parseDouble(Float.toString(packet.getPosition().getZ())));
|
|
||||||
|
|
||||||
if(!session.confirmTeleport(position)){
|
if(!session.confirmTeleport(position)){
|
||||||
return;
|
return;
|
||||||
|
@ -106,6 +106,28 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
||||||
if (!colliding)
|
if (!colliding)
|
||||||
*/
|
*/
|
||||||
session.sendDownstreamPacket(playerPositionRotationPacket);
|
session.sendDownstreamPacket(playerPositionRotationPacket);
|
||||||
|
|
||||||
|
// Schedule a position send loop if the player is idle
|
||||||
|
session.setMovementSendIfIdle(session.getConnector().getGeneralThreadPool().schedule(() -> sendPositionIfIdle(session),
|
||||||
|
3, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the Bedrock position before sending to the Java server to account for inaccuracies in movement between
|
||||||
|
* the two versions.
|
||||||
|
*
|
||||||
|
* @param position the current Bedrock position of the client
|
||||||
|
* @param onGround whether the Bedrock player is on the ground
|
||||||
|
* @return the position to send to the Java server.
|
||||||
|
*/
|
||||||
|
private Vector3d adjustBedrockPosition(Vector3f position, boolean onGround) {
|
||||||
|
// 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 = position.getY() - EntityType.PLAYER.getOffset();
|
||||||
|
if (onGround) javaY = Math.ceil(javaY * 2) / 2;
|
||||||
|
|
||||||
|
return Vector3d.from(Double.parseDouble(Float.toString(position.getX())), javaY,
|
||||||
|
Double.parseDouble(Float.toString(position.getZ())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValidMove(GeyserSession session, MovePlayerPacket.Mode mode, Vector3f currentPosition, Vector3f newPosition) {
|
public boolean isValidMove(GeyserSession session, MovePlayerPacket.Mode mode, Vector3f currentPosition, Vector3f newPosition) {
|
||||||
|
@ -147,4 +169,16 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
||||||
movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN);
|
movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN);
|
||||||
session.sendUpstreamPacket(movePlayerPacket);
|
session.sendUpstreamPacket(movePlayerPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendPositionIfIdle(GeyserSession session) {
|
||||||
|
if (session.isClosed()) return;
|
||||||
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
|
// Recalculate in case something else changed position
|
||||||
|
Vector3d position = adjustBedrockPosition(entity.getPosition(), entity.isOnGround());
|
||||||
|
ClientPlayerPositionPacket packet = new ClientPlayerPositionPacket(session.getPlayerEntity().isOnGround(),
|
||||||
|
position.getX(), position.getY(), position.getZ());
|
||||||
|
session.sendDownstreamPacket(packet);
|
||||||
|
session.setMovementSendIfIdle(session.getConnector().getGeneralThreadPool().schedule(() -> sendPositionIfIdle(session),
|
||||||
|
3, TimeUnit.SECONDS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,10 @@ public class DimensionUtils {
|
||||||
if (javaDimension.equals(player.getDimension()))
|
if (javaDimension.equals(player.getDimension()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (session.getMovementSendIfIdle() != null) {
|
||||||
|
session.getMovementSendIfIdle().cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
session.getEntityCache().removeAllEntities();
|
session.getEntityCache().removeAllEntities();
|
||||||
session.getItemFrameCache().clear();
|
session.getItemFrameCache().clear();
|
||||||
if (session.getPendingDimSwitches().getAndIncrement() > 0) {
|
if (session.getPendingDimSwitches().getAndIncrement() > 0) {
|
||||||
|
|
Loading…
Reference in a new issue