forked from GeyserMC/Geyser
		
	Start fixing dimension switching and respawning
This commit is contained in:
		
							parent
							
								
									2ed492edb8
								
							
						
					
					
						commit
						cc0b3293bf
					
				
					 11 changed files with 224 additions and 59 deletions
				
			
		|  | @ -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.auth.exception.request.RequestException; | ||||||
| import com.github.steveice10.mc.protocol.MinecraftProtocol; | import com.github.steveice10.mc.protocol.MinecraftProtocol; | ||||||
| import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; | 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.Client; | ||||||
| import com.github.steveice10.packetlib.event.session.ConnectedEvent; | import com.github.steveice10.packetlib.event.session.ConnectedEvent; | ||||||
| import com.github.steveice10.packetlib.event.session.DisconnectedEvent; | 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.session.cache.*; | ||||||
| import org.geysermc.connector.network.translators.Registry; | import org.geysermc.connector.network.translators.Registry; | ||||||
| import org.geysermc.connector.network.translators.TranslatorsInit; | import org.geysermc.connector.network.translators.TranslatorsInit; | ||||||
|  | import org.geysermc.connector.utils.DimensionUtils; | ||||||
| import org.geysermc.connector.utils.Toolbox; | import org.geysermc.connector.utils.Toolbox; | ||||||
| 
 | 
 | ||||||
| import java.net.InetSocketAddress; | import java.net.InetSocketAddress; | ||||||
|  | @ -97,6 +99,11 @@ public class GeyserSession implements Player { | ||||||
|     @Setter |     @Setter | ||||||
|     private GameMode gameMode = GameMode.SURVIVAL; |     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) { |     public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { | ||||||
|         this.connector = connector; |         this.connector = connector; | ||||||
|         this.upstream = new UpstreamSession(bedrockServerSession); |         this.upstream = new UpstreamSession(bedrockServerSession); | ||||||
|  | @ -198,6 +205,18 @@ public class GeyserSession implements Player { | ||||||
|                     @Override |                     @Override | ||||||
|                     public void packetReceived(PacketReceivedEvent event) { |                     public void packetReceived(PacketReceivedEvent event) { | ||||||
|                         if (!closed) { |                         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); |                             Registry.JAVA.translate(event.getPacket().getClass(), event.getPacket(), GeyserSession.this); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|  | @ -156,6 +156,7 @@ public class TranslatorsInit { | ||||||
|         Registry.registerBedrock(SetLocalPlayerAsInitializedPacket.class, new BedrockPlayerInitializedTranslator()); |         Registry.registerBedrock(SetLocalPlayerAsInitializedPacket.class, new BedrockPlayerInitializedTranslator()); | ||||||
|         Registry.registerBedrock(InteractPacket.class, new BedrockInteractTranslator()); |         Registry.registerBedrock(InteractPacket.class, new BedrockInteractTranslator()); | ||||||
|         Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator()); |         Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator()); | ||||||
|  |         Registry.registerBedrock(RespawnPacket.class, new BedrockRespawnTranslator()); | ||||||
| 
 | 
 | ||||||
|         itemTranslator = new ItemTranslator(); |         itemTranslator = new ItemTranslator(); | ||||||
|         blockTranslator = new BlockTranslator(); |         blockTranslator = new BlockTranslator(); | ||||||
|  |  | ||||||
|  | @ -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.ClientPlayerPlaceBlockPacket; | ||||||
| import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; | import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerStatePacket; | ||||||
| import com.nukkitx.math.vector.Vector3i; | 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.PlayerActionPacket; | ||||||
|  | import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket; | ||||||
| import org.geysermc.connector.entity.Entity; | import org.geysermc.connector.entity.Entity; | ||||||
| import org.geysermc.connector.network.session.GeyserSession; | import org.geysermc.connector.network.session.GeyserSession; | ||||||
| import org.geysermc.connector.network.translators.PacketTranslator; | import org.geysermc.connector.network.translators.PacketTranslator; | ||||||
|  | @ -53,7 +55,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket | ||||||
|         switch (packet.getAction()) { |         switch (packet.getAction()) { | ||||||
|             case RESPAWN: |             case RESPAWN: | ||||||
|                 // Don't put anything here as respawn is already handled |                 // Don't put anything here as respawn is already handled | ||||||
|                 // in JavaPlayerSetHealthTranslator |                 // in BedrockRespawnTranslator | ||||||
|                 break; |                 break; | ||||||
|             case START_GLIDE: |             case START_GLIDE: | ||||||
|             case STOP_GLIDE: |             case STOP_GLIDE: | ||||||
|  | @ -105,6 +107,12 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket | ||||||
|             case STOP_BREAK: |             case STOP_BREAK: | ||||||
|                 // Handled in BedrockInventoryTransactionTranslator |                 // Handled in BedrockInventoryTransactionTranslator | ||||||
|                 break; |                 break; | ||||||
|  |             case DIMENSION_CHANGE_SUCCESS: | ||||||
|  |                 synchronized (session.getDimensionLock()) { | ||||||
|  |                     session.setSwitchingDim(false); | ||||||
|  |                     session.getDimensionLock().notifyAll(); | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack | ||||||
|     @Override |     @Override | ||||||
|     public void translate(MovePlayerPacket packet, GeyserSession session) { |     public void translate(MovePlayerPacket packet, GeyserSession session) { | ||||||
|         PlayerEntity entity = session.getPlayerEntity(); |         PlayerEntity entity = session.getPlayerEntity(); | ||||||
|         if (entity == null || !session.isSpawned()) return; |         if (entity == null || !session.isSpawned() || session.isSwitchingDim()) return; | ||||||
| 
 | 
 | ||||||
|         if (!session.getUpstream().isInitialized()) { |         if (!session.getUpstream().isInitialized()) { | ||||||
|             MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket(); |             MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket(); | ||||||
|  |  | ||||||
|  | @ -21,5 +21,9 @@ public class BedrockPlayerInitializedTranslator extends PacketTranslator<SetLoca | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         synchronized (session.getDimensionLock()) { | ||||||
|  |             session.setSwitchingDim(false); | ||||||
|  |             session.getDimensionLock().notifyAll(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2019 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.connector.network.translators.bedrock; | ||||||
|  | 
 | ||||||
|  | import com.github.steveice10.mc.protocol.data.game.ClientRequest; | ||||||
|  | import com.github.steveice10.mc.protocol.packet.ingame.client.ClientRequestPacket; | ||||||
|  | import com.nukkitx.protocol.bedrock.packet.RespawnPacket; | ||||||
|  | import org.geysermc.connector.network.session.GeyserSession; | ||||||
|  | import org.geysermc.connector.network.translators.PacketTranslator; | ||||||
|  | 
 | ||||||
|  | public class BedrockRespawnTranslator extends PacketTranslator<RespawnPacket> { | ||||||
|  | 
 | ||||||
|  |     @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); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -26,22 +26,29 @@ | ||||||
| package org.geysermc.connector.network.translators.java; | package org.geysermc.connector.network.translators.java; | ||||||
| 
 | 
 | ||||||
| import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; | 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.entity.PlayerEntity; | ||||||
| import org.geysermc.connector.network.session.GeyserSession; | 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.world.chunk.ChunkPosition; | import org.geysermc.connector.utils.DimensionUtils; | ||||||
| 
 | 
 | ||||||
| public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacket> { | public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacket> { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void translate(ServerJoinGamePacket packet, GeyserSession session) { |     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(); |         AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket(); | ||||||
|         bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId()); |         bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId()); | ||||||
|         bedrockPacket.setPlayerPermission(1); |         bedrockPacket.setPlayerPermission(1); | ||||||
|  | @ -51,9 +58,6 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke | ||||||
|         playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); |         playStatus.setStatus(PlayStatusPacket.Status.LOGIN_SUCCESS); | ||||||
|         // session.getUpstream().sendPacket(playStatus); |         // session.getUpstream().sendPacket(playStatus); | ||||||
| 
 | 
 | ||||||
|         PlayerEntity entity = session.getPlayerEntity(); |  | ||||||
|         entity.setEntityId(packet.getEntityId()); |  | ||||||
| 
 |  | ||||||
|         SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); |         SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); | ||||||
|         playerGameTypePacket.setGamemode(packet.getGameMode().ordinal()); |         playerGameTypePacket.setGamemode(packet.getGameMode().ordinal()); | ||||||
|         session.getUpstream().sendPacket(playerGameTypePacket); |         session.getUpstream().sendPacket(playerGameTypePacket); | ||||||
|  | @ -70,7 +74,5 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke | ||||||
|         ChunkRadiusUpdatedPacket chunkRadiusPacket = new ChunkRadiusUpdatedPacket(); |         ChunkRadiusUpdatedPacket chunkRadiusPacket = new ChunkRadiusUpdatedPacket(); | ||||||
|         chunkRadiusPacket.setRadius(session.getRenderDistance()); |         chunkRadiusPacket.setRadius(session.getRenderDistance()); | ||||||
|         session.getUpstream().sendPacket(chunkRadiusPacket); |         session.getUpstream().sendPacket(chunkRadiusPacket); | ||||||
| 
 |  | ||||||
|         session.setSpawned(true); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -26,12 +26,11 @@ | ||||||
| package org.geysermc.connector.network.translators.java; | package org.geysermc.connector.network.translators.java; | ||||||
| 
 | 
 | ||||||
| import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; | import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket; | ||||||
| import com.nukkitx.protocol.bedrock.packet.ChangeDimensionPacket; | import com.nukkitx.protocol.bedrock.packet.*; | ||||||
| import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; |  | ||||||
| import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket; |  | ||||||
| import org.geysermc.connector.entity.Entity; | import org.geysermc.connector.entity.Entity; | ||||||
| import org.geysermc.connector.network.session.GeyserSession; | 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.utils.DimensionUtils; | ||||||
| 
 | 
 | ||||||
| public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> { | public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> { | ||||||
| 
 | 
 | ||||||
|  | @ -41,37 +40,16 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket> | ||||||
|         if (entity == null) |         if (entity == null) | ||||||
|             return; |             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(); |         SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket(); | ||||||
|         playerGameTypePacket.setGamemode(packet.getGamemode().ordinal()); |         playerGameTypePacket.setGamemode(packet.getGamemode().ordinal()); | ||||||
|         session.getUpstream().sendPacket(playerGameTypePacket); |         session.getUpstream().sendPacket(playerGameTypePacket); | ||||||
|         session.setGameMode(packet.getGamemode()); |         session.setGameMode(packet.getGamemode()); | ||||||
| 
 | 
 | ||||||
|         /* |         if (entity.getDimension() != DimensionUtils.javaToBedrock(packet.getDimension())) { | ||||||
|         PlayStatusPacket playStatusPacket = new PlayStatusPacket(); |             DimensionUtils.switchDimension(session, packet.getDimension(), false); | ||||||
|         playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); |         } else { | ||||||
|         session.getUpstream().sendPacket(playStatusPacket); |             // Handled in JavaPlayerPositionRotationTranslator | ||||||
|         */ |             session.setSpawned(false); | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private int getDimension(int javaDimension) { |  | ||||||
|         switch (javaDimension) { |  | ||||||
|             case -1: |  | ||||||
|                 return 1; |  | ||||||
|             case 1: |  | ||||||
|                 return 2; |  | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         return javaDimension; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,11 +25,7 @@ | ||||||
| 
 | 
 | ||||||
| package org.geysermc.connector.network.translators.java.entity.player; | 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.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 com.nukkitx.protocol.bedrock.packet.SetHealthPacket; | ||||||
| import org.geysermc.connector.entity.Entity; | import org.geysermc.connector.entity.Entity; | ||||||
| import org.geysermc.connector.entity.attribute.AttributeType; | import org.geysermc.connector.entity.attribute.AttributeType; | ||||||
|  | @ -60,14 +56,8 @@ public class JavaPlayerHealthTranslator extends PacketTranslator<ServerPlayerHea | ||||||
|         entity.updateBedrockAttributes(session); |         entity.updateBedrockAttributes(session); | ||||||
| 
 | 
 | ||||||
|         if (packet.getHealth() <= 0) { |         if (packet.getHealth() <= 0) { | ||||||
|             RespawnPacket respawnPacket = new RespawnPacket(); |             entity.getAttributes().remove(AttributeType.HEALTH); | ||||||
|             respawnPacket.setRuntimeEntityId(entity.getGeyserId()); |             entity.updateBedrockAttributes(session); | ||||||
|             respawnPacket.setPosition(Vector3f.from(0, 72, 0)); |  | ||||||
|             respawnPacket.setSpawnState(RespawnPacket.State.SERVER_SEARCHING); |  | ||||||
|             session.getUpstream().sendPacket(respawnPacket); |  | ||||||
| 
 |  | ||||||
|             ClientRequestPacket javaRespawnPacket = new ClientRequestPacket(ClientRequest.RESPAWN); |  | ||||||
|             session.getDownstream().getSession().send(javaRespawnPacket); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -28,8 +28,7 @@ package org.geysermc.connector.network.translators.java.entity.player; | ||||||
| import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; | import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; | ||||||
| import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; | import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; | ||||||
| import com.nukkitx.math.vector.Vector3f; | import com.nukkitx.math.vector.Vector3f; | ||||||
| import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket; | import com.nukkitx.protocol.bedrock.packet.*; | ||||||
| import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket; |  | ||||||
| import org.geysermc.connector.console.GeyserLogger; | import org.geysermc.connector.console.GeyserLogger; | ||||||
| import org.geysermc.connector.entity.Entity; | import org.geysermc.connector.entity.Entity; | ||||||
| import org.geysermc.connector.entity.type.EntityType; | import org.geysermc.connector.entity.type.EntityType; | ||||||
|  | @ -48,7 +47,26 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve | ||||||
|             return; |             return; | ||||||
| 
 | 
 | ||||||
|         if (!session.isSpawned()) { |         if (!session.isSpawned()) { | ||||||
|             entity.moveAbsolute(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()), packet.getYaw(), packet.getPitch()); |             Vector3f pos = Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ()); | ||||||
|  |             entity.moveAbsolute(pos, packet.getYaw(), packet.getPitch()); | ||||||
|  | 
 | ||||||
|  |             RespawnPacket respawnPacket = new RespawnPacket(); | ||||||
|  |             respawnPacket.setRuntimeEntityId(0); | ||||||
|  |             respawnPacket.setPosition(Vector3f.from(0, 32767, 0)); | ||||||
|  |             respawnPacket.setSpawnState(RespawnPacket.State.SERVER_SEARCHING); | ||||||
|  |             session.getUpstream().sendPacket(respawnPacket); | ||||||
|  | 
 | ||||||
|  |             respawnPacket = new RespawnPacket(); | ||||||
|  |             respawnPacket.setRuntimeEntityId(0); | ||||||
|  |             respawnPacket.setPosition(pos); | ||||||
|  |             respawnPacket.setSpawnState(RespawnPacket.State.SERVER_READY); | ||||||
|  |             session.getUpstream().sendPacket(respawnPacket); | ||||||
|  | 
 | ||||||
|  |             EntityEventPacket eventPacket = new EntityEventPacket(); | ||||||
|  |             eventPacket.setRuntimeEntityId(entity.getGeyserId()); | ||||||
|  |             eventPacket.setEvent(EntityEventPacket.Event.RESPAWN); | ||||||
|  |             eventPacket.setData(0); | ||||||
|  |             session.getUpstream().sendPacket(eventPacket); | ||||||
| 
 | 
 | ||||||
|             SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); |             SetEntityDataPacket entityDataPacket = new SetEntityDataPacket(); | ||||||
|             entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); |             entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); | ||||||
|  | @ -57,7 +75,7 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve | ||||||
| 
 | 
 | ||||||
|             MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); |             MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); | ||||||
|             movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); |             movePlayerPacket.setRuntimeEntityId(entity.getGeyserId()); | ||||||
|             movePlayerPacket.setPosition(Vector3f.from(packet.getX(), packet.getY() + EntityType.PLAYER.getOffset() + 0.1f, packet.getZ())); |             movePlayerPacket.setPosition(pos); | ||||||
|             movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0)); |             movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0)); | ||||||
|             movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET); |             movePlayerPacket.setMode(MovePlayerPacket.Mode.RESET); | ||||||
|             movePlayerPacket.setOnGround(true); |             movePlayerPacket.setOnGround(true); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,102 @@ | ||||||
|  | package org.geysermc.connector.utils; | ||||||
|  | 
 | ||||||
|  | import com.nukkitx.math.vector.Vector3i; | ||||||
|  | import com.nukkitx.protocol.bedrock.packet.*; | ||||||
|  | import org.geysermc.connector.entity.Entity; | ||||||
|  | import org.geysermc.connector.network.session.GeyserSession; | ||||||
|  | import org.geysermc.connector.network.translators.TranslatorsInit; | ||||||
|  | 
 | ||||||
|  | public class DimensionUtils { | ||||||
|  |     public static void switchDimension(GeyserSession session, int javaDimension, boolean fake) { | ||||||
|  |         int bedrockDimension = javaToBedrock(javaDimension); | ||||||
|  |         Entity player = session.getPlayerEntity(); | ||||||
|  |         if (bedrockDimension == player.getDimension()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         Vector3i pos = Vector3i.from(0, 32767, 0); | ||||||
|  | 
 | ||||||
|  |         //FIXME: chance of exception while iterating | ||||||
|  |         try { | ||||||
|  |             for (Entity entity : session.getEntityCache().getEntities().values()) { | ||||||
|  |                 session.getEntityCache().removeEntity(entity, false); | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ChangeDimensionPacket changeDimensionPacket = new ChangeDimensionPacket(); | ||||||
|  |         changeDimensionPacket.setDimension(bedrockDimension); | ||||||
|  |         changeDimensionPacket.setRespawn(true); | ||||||
|  |         changeDimensionPacket.setPosition(pos.toFloat()); | ||||||
|  |         session.getUpstream().sendPacket(changeDimensionPacket); | ||||||
|  |         player.setDimension(bedrockDimension); | ||||||
|  | 
 | ||||||
|  |         //let java server handle portal travel sound | ||||||
|  |         StopSoundPacket stopSoundPacket = new StopSoundPacket(); | ||||||
|  |         stopSoundPacket.setStoppingAllSound(true); | ||||||
|  |         stopSoundPacket.setSoundName(""); | ||||||
|  |         session.getUpstream().sendPacket(stopSoundPacket); | ||||||
|  | 
 | ||||||
|  |         EntityEventPacket eventPacket = new EntityEventPacket(); | ||||||
|  |         eventPacket.setRuntimeEntityId(player.getGeyserId()); | ||||||
|  |         eventPacket.setEvent(EntityEventPacket.Event.RESPAWN); | ||||||
|  |         eventPacket.setData(0); | ||||||
|  |         session.getUpstream().sendPacket(eventPacket); | ||||||
|  | 
 | ||||||
|  |         session.setSpawned(false); | ||||||
|  |         session.setSwitchingDim(true); | ||||||
|  | 
 | ||||||
|  |         if (fake) { | ||||||
|  |             try { | ||||||
|  |                 Thread.sleep(250); | ||||||
|  |             } catch (InterruptedException e) { | ||||||
|  |                 Thread.currentThread().interrupt(); | ||||||
|  |             } | ||||||
|  |             sendEmptyChunks(session, pos.toInt()); | ||||||
|  |             waitForAck(session); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void waitForAck(GeyserSession session) { | ||||||
|  |         synchronized (session.getDimensionLock()) { | ||||||
|  |             try { | ||||||
|  |                 while (session.isSwitchingDim()) | ||||||
|  |                     session.getDimensionLock().wait(); | ||||||
|  |             } catch (InterruptedException e) { | ||||||
|  |                 Thread.currentThread().interrupt(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void sendEmptyChunks(GeyserSession session, Vector3i position) { | ||||||
|  |         int chunkX = position.getX() >> 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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue