forked from GeyserMC/Geyser
		
	Dimension switching cleanup (#1694)
* Dimension switching cleanup Cleans up dimension switching logic that should no longer be needed. Also fixes above Nether Bedrock building dimension switching. * Clear thunder on dimension switch too * Clarify fake dimension switch function name * Javadoc that
This commit is contained in:
		
							parent
							
								
									3f7d669676
								
							
						
					
					
						commit
						50b80a64d3
					
				
					 7 changed files with 47 additions and 48 deletions
				
			
		| 
						 | 
				
			
			@ -37,7 +37,6 @@ import com.github.steveice10.mc.protocol.data.game.window.VillagerTrade;
 | 
			
		|||
import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket;
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket;
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket;
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.login.server.LoginSuccessPacket;
 | 
			
		||||
import com.github.steveice10.packetlib.BuiltinFlags;
 | 
			
		||||
import com.github.steveice10.packetlib.Client;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +94,6 @@ import java.security.spec.InvalidKeySpecException;
 | 
			
		|||
import java.util.*;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.ScheduledFuture;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
			
		||||
 | 
			
		||||
@Getter
 | 
			
		||||
public class GeyserSession implements CommandSender {
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +146,11 @@ public class GeyserSession implements CommandSender {
 | 
			
		|||
    @Setter
 | 
			
		||||
    private GameMode gameMode = GameMode.SURVIVAL;
 | 
			
		||||
 | 
			
		||||
    private final AtomicInteger pendingDimSwitches = new AtomicInteger(0);
 | 
			
		||||
    /**
 | 
			
		||||
     * Keeps track of the world name for respawning.
 | 
			
		||||
     */
 | 
			
		||||
    @Setter
 | 
			
		||||
    private String worldName = null;
 | 
			
		||||
 | 
			
		||||
    private boolean sneaking;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -185,9 +187,6 @@ public class GeyserSession implements CommandSender {
 | 
			
		|||
    @Setter
 | 
			
		||||
    private Vector3i lastInteractionPosition = Vector3i.ZERO;
 | 
			
		||||
 | 
			
		||||
    private boolean manyDimPackets = false;
 | 
			
		||||
    private ServerRespawnPacket lastDimPacket = null;
 | 
			
		||||
 | 
			
		||||
    @Setter
 | 
			
		||||
    private Entity ridingVehicleEntity;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -537,16 +536,6 @@ public class GeyserSession implements CommandSender {
 | 
			
		|||
                    @Override
 | 
			
		||||
                    public void packetReceived(PacketReceivedEvent event) {
 | 
			
		||||
                        if (!closed) {
 | 
			
		||||
                            //handle consecutive respawn packets
 | 
			
		||||
                            if (event.getPacket().getClass().equals(ServerRespawnPacket.class)) {
 | 
			
		||||
                                manyDimPackets = lastDimPacket != null;
 | 
			
		||||
                                lastDimPacket = event.getPacket();
 | 
			
		||||
                                return;
 | 
			
		||||
                            } else if (lastDimPacket != null) {
 | 
			
		||||
                                PacketTranslatorRegistry.JAVA_TRANSLATOR.translate(lastDimPacket.getClass(), lastDimPacket, GeyserSession.this);
 | 
			
		||||
                                lastDimPacket = null;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            // Required, or else Floodgate players break with Bukkit chunk caching
 | 
			
		||||
                            if (event.getPacket() instanceof LoginSuccessPacket) {
 | 
			
		||||
                                GameProfile profile = ((LoginSuccessPacket) event.getPacket()).getProfile();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,6 @@ import org.geysermc.connector.entity.Entity;
 | 
			
		|||
import org.geysermc.connector.network.session.GeyserSession;
 | 
			
		||||
import org.geysermc.connector.network.translators.PacketTranslator;
 | 
			
		||||
import org.geysermc.connector.network.translators.Translator;
 | 
			
		||||
import org.geysermc.connector.network.translators.collision.CollisionManager;
 | 
			
		||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
 | 
			
		||||
import org.geysermc.connector.utils.BlockUtils;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -157,14 +156,12 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
 | 
			
		|||
                // Handled in BedrockInventoryTransactionTranslator
 | 
			
		||||
                break;
 | 
			
		||||
            case DIMENSION_CHANGE_SUCCESS:
 | 
			
		||||
                if (session.getPendingDimSwitches().decrementAndGet() == 0) {
 | 
			
		||||
                    //sometimes the client doesn't feel like loading
 | 
			
		||||
                    PlayStatusPacket spawnPacket = new PlayStatusPacket();
 | 
			
		||||
                    spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
 | 
			
		||||
                    session.sendUpstreamPacket(spawnPacket);
 | 
			
		||||
                    entity.updateBedrockAttributes(session);
 | 
			
		||||
                    session.getEntityCache().updateBossBars();
 | 
			
		||||
                }
 | 
			
		||||
                //sometimes the client doesn't feel like loading
 | 
			
		||||
                PlayStatusPacket spawnPacket = new PlayStatusPacket();
 | 
			
		||||
                spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
 | 
			
		||||
                session.sendUpstreamPacket(spawnPacket);
 | 
			
		||||
                entity.updateBedrockAttributes(session);
 | 
			
		||||
                session.getEntityCache().updateBossBars();
 | 
			
		||||
                break;
 | 
			
		||||
            case JUMP:
 | 
			
		||||
                session.setJumping(true);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
 | 
			
		|||
    @Override
 | 
			
		||||
    public void translate(MovePlayerPacket packet, GeyserSession session) {
 | 
			
		||||
        PlayerEntity entity = session.getPlayerEntity();
 | 
			
		||||
        if (!session.isSpawned() || session.getPendingDimSwitches().get() > 0) return;
 | 
			
		||||
        if (!session.isSpawned()) return;
 | 
			
		||||
 | 
			
		||||
        if (!session.getUpstream().isInitialized()) {
 | 
			
		||||
            MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,12 +55,12 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
 | 
			
		|||
        // are swapping servers
 | 
			
		||||
        String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
 | 
			
		||||
        if (session.isSpawned()) {
 | 
			
		||||
            String fakeDim = session.getDimension().equals(DimensionUtils.OVERWORLD) ? DimensionUtils.NETHER : DimensionUtils.OVERWORLD;
 | 
			
		||||
            String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
 | 
			
		||||
            DimensionUtils.switchDimension(session, fakeDim);
 | 
			
		||||
            DimensionUtils.switchDimension(session, newDimension);
 | 
			
		||||
 | 
			
		||||
            session.getWorldCache().removeScoreboard();
 | 
			
		||||
        }
 | 
			
		||||
        session.setWorldName(packet.getWorldName());
 | 
			
		||||
 | 
			
		||||
        AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
 | 
			
		||||
        bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,8 +43,6 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
 | 
			
		|||
    @Override
 | 
			
		||||
    public void translate(ServerRespawnPacket packet, GeyserSession session) {
 | 
			
		||||
        Entity entity = session.getPlayerEntity();
 | 
			
		||||
        if (entity == null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        float maxHealth = entity.getAttributes().containsKey(AttributeType.MAX_HEALTH) ? entity.getAttributes().get(AttributeType.MAX_HEALTH).getValue() : 20f;
 | 
			
		||||
        // Max health must be divisible by two in bedrock
 | 
			
		||||
| 
						 | 
				
			
			@ -66,18 +64,24 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
 | 
			
		|||
            session.setRaining(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (session.isThunder()) {
 | 
			
		||||
            LevelEventPacket stopThunderPacket = new LevelEventPacket();
 | 
			
		||||
            stopThunderPacket.setType(LevelEventType.STOP_THUNDERSTORM);
 | 
			
		||||
            stopThunderPacket.setData(0);
 | 
			
		||||
            stopThunderPacket.setPosition(Vector3f.ZERO);
 | 
			
		||||
            session.sendUpstreamPacket(stopThunderPacket);
 | 
			
		||||
            session.setThunder(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
 | 
			
		||||
        if (!session.getDimension().equals(newDimension)) {
 | 
			
		||||
            DimensionUtils.switchDimension(session, newDimension);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (session.isManyDimPackets()) { //reloading world
 | 
			
		||||
                String fakeDim = session.getDimension().equals(DimensionUtils.OVERWORLD) ? DimensionUtils.NETHER : DimensionUtils.OVERWORLD;
 | 
			
		||||
        if (!session.getDimension().equals(newDimension) || !packet.getWorldName().equals(session.getWorldName())) {
 | 
			
		||||
            if (!packet.getWorldName().equals(session.getWorldName()) && session.getDimension().equals(newDimension)) {
 | 
			
		||||
                // Switching to a new world (based off the world name change); send a fake dimension change
 | 
			
		||||
                String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
 | 
			
		||||
                DimensionUtils.switchDimension(session, fakeDim);
 | 
			
		||||
                DimensionUtils.switchDimension(session, newDimension);
 | 
			
		||||
            } else {
 | 
			
		||||
                // Handled in JavaPlayerPositionRotationTranslator
 | 
			
		||||
                session.setSpawned(false);
 | 
			
		||||
            }
 | 
			
		||||
            session.setWorldName(packet.getWorldName());
 | 
			
		||||
            DimensionUtils.switchDimension(session, newDimension);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,13 +46,11 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
 | 
			
		|||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void translate(ServerPlayerPositionRotationPacket packet, GeyserSession session) {
 | 
			
		||||
        PlayerEntity entity = session.getPlayerEntity();
 | 
			
		||||
        if (entity == null)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!session.isLoggedIn())
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        PlayerEntity entity = session.getPlayerEntity();
 | 
			
		||||
 | 
			
		||||
        if (!session.isSpawned()) {
 | 
			
		||||
            Vector3f pos = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
 | 
			
		||||
            entity.setPosition(pos);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,8 +57,6 @@ public class DimensionUtils {
 | 
			
		|||
    public static void switchDimension(GeyserSession session, String javaDimension) {
 | 
			
		||||
        int bedrockDimension = javaToBedrock(javaDimension);
 | 
			
		||||
        Entity player = session.getPlayerEntity();
 | 
			
		||||
        if (javaDimension.equals(session.getDimension()))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (session.getMovementSendIfIdle() != null) {
 | 
			
		||||
            session.getMovementSendIfIdle().cancel(true);
 | 
			
		||||
| 
						 | 
				
			
			@ -67,9 +65,6 @@ public class DimensionUtils {
 | 
			
		|||
        session.getEntityCache().removeAllEntities();
 | 
			
		||||
        session.getItemFrameCache().clear();
 | 
			
		||||
        session.getSkullCache().clear();
 | 
			
		||||
        if (session.getPendingDimSwitches().getAndIncrement() > 0) {
 | 
			
		||||
            ChunkUtils.sendEmptyChunks(session, player.getPosition().toInt(), 3, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Vector3i pos = Vector3i.from(0, Short.MAX_VALUE, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,4 +145,20 @@ public class DimensionUtils {
 | 
			
		|||
        // Change dimension ID to the End to allow for building above Bedrock
 | 
			
		||||
        BEDROCK_NETHER_ID = isAboveNetherBedrockBuilding ? 2 : 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the fake, temporary dimension we send clients to so we aren't switching to the same dimension without an additional
 | 
			
		||||
     * dimension switch.
 | 
			
		||||
     *
 | 
			
		||||
     * @param currentDimension the current dimension of the player
 | 
			
		||||
     * @param newDimension the new dimension that the player will be transferred to
 | 
			
		||||
     * @return the fake dimension to transfer to
 | 
			
		||||
     */
 | 
			
		||||
    public static String getTemporaryDimension(String currentDimension, String newDimension) {
 | 
			
		||||
        if (BEDROCK_NETHER_ID == 2) {
 | 
			
		||||
            // Prevents rare instances of Bedrock locking up
 | 
			
		||||
            return javaToBedrock(newDimension) == 2 ? OVERWORLD : NETHER;
 | 
			
		||||
        }
 | 
			
		||||
        return currentDimension.equals(OVERWORLD) ? NETHER : OVERWORLD;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue