Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dimension switching cleanup #1694

Merged
merged 5 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.Client;
import com.github.steveice10.packetlib.event.session.*;
Expand Down Expand Up @@ -94,7 +93,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 @@ -147,7 +145,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 @@ -184,9 +186,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 @@ -526,16 +525,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,19 @@ 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 dimension we send clients to so we aren't switching to the same dimension without an additional
* dimension switch.
*
* @param currentDimension the current
* @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;
}
}