Skip to content

Commit

Permalink
Dimension switching cleanup (#1694)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Camotoy authored Jan 4, 2021
1 parent 3f7d669 commit 50b80a6
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
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;
Expand Down Expand Up @@ -95,7 +94,6 @@
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 {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -537,16 +536,6 @@ public void disconnected(DisconnectedEvent event) {
@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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
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;

Expand Down Expand Up @@ -157,14 +156,12 @@ public void translate(PlayerActionPacket packet, GeyserSession session) {
// 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ public void translate(ServerJoinGamePacket packet, GeyserSession session) {
// 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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -66,18 +64,24 @@ public void translate(ServerRespawnPacket packet, GeyserSession session) {
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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -67,9 +65,6 @@ public static void switchDimension(GeyserSession session, String javaDimension)
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);

Expand Down Expand Up @@ -150,4 +145,20 @@ public static void changeBedrockNetherId(boolean isAboveNetherBedrockBuilding) {
// 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;
}
}

0 comments on commit 50b80a6

Please sign in to comment.