From cc0b3293bf887c810a515b46b97f0d3fcdb8e105 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Fri, 27 Dec 2019 02:29:46 -0900 Subject: [PATCH] Start fixing dimension switching and respawning --- .../network/session/GeyserSession.java | 19 ++++ .../network/translators/TranslatorsInit.java | 1 + .../bedrock/BedrockActionTranslator.java | 10 +- .../bedrock/BedrockMovePlayerTranslator.java | 2 +- .../BedrockPlayerInitializedTranslator.java | 4 + .../bedrock/BedrockRespawnTranslator.java | 43 ++++++++ .../java/JavaJoinGameTranslator.java | 26 ++--- .../java/JavaRespawnTranslator.java | 36 ++----- .../player/JavaPlayerHealthTranslator.java | 14 +-- .../JavaPlayerPositionRotationTranslator.java | 26 ++++- .../connector/utils/DimensionUtils.java | 102 ++++++++++++++++++ 11 files changed, 224 insertions(+), 59 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockRespawnTranslator.java create mode 100644 connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 52ee3823..b12434c9 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -29,6 +29,7 @@ import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; +import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; import com.github.steveice10.packetlib.Client; import com.github.steveice10.packetlib.event.session.ConnectedEvent; import com.github.steveice10.packetlib.event.session.DisconnectedEvent; @@ -57,6 +58,7 @@ import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.network.session.cache.*; import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.TranslatorsInit; +import org.geysermc.connector.utils.DimensionUtils; import org.geysermc.connector.utils.Toolbox; import java.net.InetSocketAddress; @@ -97,6 +99,11 @@ public class GeyserSession implements Player { @Setter private GameMode gameMode = GameMode.SURVIVAL; + @Setter + private volatile boolean switchingDim = false; + private final Object dimensionLock = new Object(); + private ServerRespawnPacket lastDimPacket = null; + public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { this.connector = connector; this.upstream = new UpstreamSession(bedrockServerSession); @@ -198,6 +205,18 @@ public class GeyserSession implements Player { @Override public void packetReceived(PacketReceivedEvent event) { if (!closed) { + //handle consecutive respawn packets + if (event.getPacket().getClass().equals(ServerRespawnPacket.class)) { + if (lastDimPacket != null) { + DimensionUtils.switchDimension(GeyserSession.this, lastDimPacket.getDimension(), true); + } + lastDimPacket = event.getPacket(); + return; + } else if (lastDimPacket != null) { + Registry.JAVA.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this); + lastDimPacket = null; + } + Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java index a19de3f2..aa769283 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/TranslatorsInit.java @@ -156,6 +156,7 @@ public class TranslatorsInit { Registry.registerBedrock(SetLocalPlayerAsInitializedPacket.class, new BedrockPlayerInitializedTranslator()); Registry.registerBedrock(InteractPacket.class, new BedrockInteractTranslator()); Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator()); + Registry.registerBedrock(RespawnPacket.class, new BedrockRespawnTranslator()); itemTranslator = new ItemTranslator(); blockTranslator = new BlockTranslator(); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java index 33467934..8f99b5cc 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockActionTranslator.java @@ -34,7 +34,9 @@ import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlaye import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket; +import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; @@ -53,7 +55,7 @@ public class BedrockActionTranslator extends PacketTranslator { + + @Override + public void translate(RespawnPacket packet, GeyserSession session) { + if (packet.getSpawnState() == RespawnPacket.State.CLIENT_READY) { + ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN); + session.getDownstream().getSession().send(javaRespawnPacket); + } + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java index 87bb62e0..6e4228f2 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/JavaJoinGameTranslator.java @@ -26,22 +26,29 @@ package org.geysermc.connector.network.translators.java; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; -import com.nukkitx.math.vector.Vector3i; -import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; -import com.nukkitx.protocol.bedrock.packet.ChunkRadiusUpdatedPacket; -import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; -import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; -import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; +import com.nukkitx.protocol.bedrock.packet.*; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; -import org.geysermc.connector.world.chunk.ChunkPosition; +import org.geysermc.connector.utils.DimensionUtils; public class JavaJoinGameTranslator extends PacketTranslator { @Override public void translate(ServerJoinGamePacket packet, GeyserSession session) { + PlayerEntity entity = session.getPlayerEntity(); + entity.setEntityId(packet.getEntityId()); + + if (DimensionUtils.javaToBedrock(packet.getDimension()) != entity.getDimension()) { + if (!session.getUpstream().isInitialized()) { + session.setSwitchingDim(true); + DimensionUtils.sendEmptyChunks(session, entity.getPosition().toInt()); + DimensionUtils.waitForAck(session); + } + DimensionUtils.switchDimension(session, packet.getDimension(), false); + } + AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket(); bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId()); bedrockPacket.setPlayerPermission(1); @@ -51,9 +58,6 @@ public class JavaJoinGameTranslator extends PacketTranslator { @@ -41,37 +40,16 @@ public class JavaRespawnTranslator extends PacketTranslator if (entity == null) return; - if (entity.getDimension() == getDimension(packet.getDimension())) - return; - - entity.setDimension(getDimension(packet.getDimension())); - - ChangeDimensionPacket changeDimensionPacket = new ChangeDimensionPacket(); - changeDimensionPacket.setDimension(getDimension(packet.getDimension())); - changeDimensionPacket.setRespawn(false); - changeDimensionPacket.setPosition(entity.getPosition()); - session.getUpstream().sendPacket(changeDimensionPacket); - SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); playerGameTypePacket.setGamemode(packet.getGamemode().ordinal()); session.getUpstream().sendPacket(playerGameTypePacket); session.setGameMode(packet.getGamemode()); - /* - PlayStatusPacket playStatusPacket = new PlayStatusPacket(); - playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); - session.getUpstream().sendPacket(playStatusPacket); - */ - } - - private int getDimension(int javaDimension) { - switch (javaDimension) { - case -1: - return 1; - case 1: - return 2; + if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) { + DimensionUtils.switchDimension(session, packet.getDimension(), false); + } else { + // Handled in JavaPlayerPositionRotationTranslator + session.setSpawned(false); } - - return javaDimension; } } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerHealthTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerHealthTranslator.java index 73376385..077ca9e8 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerHealthTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerHealthTranslator.java @@ -25,11 +25,7 @@ package org.geysermc.connector.network.translators.java.entity.player; -import com.github.steveice10.mc.protocol.data.game.ClientRequest; -import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket; -import com.nukkitx.math.vector.Vector3f; -import com.nukkitx.protocol.bedrock.packet.RespawnPacket; import com.nukkitx.protocol.bedrock.packet.SetHealthPacket; import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.attribute.AttributeType; @@ -60,14 +56,8 @@ public class JavaPlayerHealthTranslator extends PacketTranslator> 4; + int chunkZ = position.getZ() >> 4; + NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket(); + chunkPublisherUpdatePacket.setPosition(position); + chunkPublisherUpdatePacket.setRadius(session.getRenderDistance() << 4); + session.getUpstream().sendPacket(chunkPublisherUpdatePacket); + session.setLastChunkPosition(null); + for (int x = -5; x < 5; x++) { + for (int z = -5; z < 5; z++) { + LevelChunkPacket data = new LevelChunkPacket(); + data.setChunkX(chunkX + x); + data.setChunkZ(chunkZ + z); + data.setSubChunksLength(0); + data.setData(TranslatorsInit.EMPTY_LEVEL_CHUNK_DATA); + data.setCachingEnabled(false); + session.getUpstream().sendPacket(data); + } + } + } + + public static int javaToBedrock(int javaDimension) { + switch (javaDimension) { + case -1: + return 1; + case 1: + return 2; + default: + return javaDimension; + } + } +}