Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
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
Dieser Commit ist enthalten in:
Ursprung
3f7d669676
Commit
50b80a64d3
@ -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.handshake.client.HandshakePacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPositionRotationPacket;
|
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.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.mc.protocol.packet.login.server.LoginSuccessPacket;
|
||||||
import com.github.steveice10.packetlib.BuiltinFlags;
|
import com.github.steveice10.packetlib.BuiltinFlags;
|
||||||
import com.github.steveice10.packetlib.Client;
|
import com.github.steveice10.packetlib.Client;
|
||||||
@ -95,7 +94,6 @@ import java.security.spec.InvalidKeySpecException;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class GeyserSession implements CommandSender {
|
public class GeyserSession implements CommandSender {
|
||||||
@ -148,7 +146,11 @@ public class GeyserSession implements CommandSender {
|
|||||||
@Setter
|
@Setter
|
||||||
private GameMode gameMode = GameMode.SURVIVAL;
|
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;
|
private boolean sneaking;
|
||||||
|
|
||||||
@ -185,9 +187,6 @@ public class GeyserSession implements CommandSender {
|
|||||||
@Setter
|
@Setter
|
||||||
private Vector3i lastInteractionPosition = Vector3i.ZERO;
|
private Vector3i lastInteractionPosition = Vector3i.ZERO;
|
||||||
|
|
||||||
private boolean manyDimPackets = false;
|
|
||||||
private ServerRespawnPacket lastDimPacket = null;
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private Entity ridingVehicleEntity;
|
private Entity ridingVehicleEntity;
|
||||||
|
|
||||||
@ -537,16 +536,6 @@ public class GeyserSession implements CommandSender {
|
|||||||
@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)) {
|
|
||||||
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
|
// Required, or else Floodgate players break with Bukkit chunk caching
|
||||||
if (event.getPacket() instanceof LoginSuccessPacket) {
|
if (event.getPacket() instanceof LoginSuccessPacket) {
|
||||||
GameProfile profile = ((LoginSuccessPacket) event.getPacket()).getProfile();
|
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.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
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.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.utils.BlockUtils;
|
import org.geysermc.connector.utils.BlockUtils;
|
||||||
|
|
||||||
@ -157,14 +156,12 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
|||||||
// Handled in BedrockInventoryTransactionTranslator
|
// Handled in BedrockInventoryTransactionTranslator
|
||||||
break;
|
break;
|
||||||
case DIMENSION_CHANGE_SUCCESS:
|
case DIMENSION_CHANGE_SUCCESS:
|
||||||
if (session.getPendingDimSwitches().decrementAndGet() == 0) {
|
|
||||||
//sometimes the client doesn't feel like loading
|
//sometimes the client doesn't feel like loading
|
||||||
PlayStatusPacket spawnPacket = new PlayStatusPacket();
|
PlayStatusPacket spawnPacket = new PlayStatusPacket();
|
||||||
spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||||
session.sendUpstreamPacket(spawnPacket);
|
session.sendUpstreamPacket(spawnPacket);
|
||||||
entity.updateBedrockAttributes(session);
|
entity.updateBedrockAttributes(session);
|
||||||
session.getEntityCache().updateBossBars();
|
session.getEntityCache().updateBossBars();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case JUMP:
|
case JUMP:
|
||||||
session.setJumping(true);
|
session.setJumping(true);
|
||||||
|
@ -50,7 +50,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 (!session.isSpawned() || session.getPendingDimSwitches().get() > 0) return;
|
if (!session.isSpawned()) return;
|
||||||
|
|
||||||
if (!session.getUpstream().isInitialized()) {
|
if (!session.getUpstream().isInitialized()) {
|
||||||
MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket();
|
MoveEntityAbsolutePacket moveEntityBack = new MoveEntityAbsolutePacket();
|
||||||
|
@ -55,12 +55,12 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
|
|||||||
// are swapping servers
|
// are swapping servers
|
||||||
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
||||||
if (session.isSpawned()) {
|
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, fakeDim);
|
||||||
DimensionUtils.switchDimension(session, newDimension);
|
|
||||||
|
|
||||||
session.getWorldCache().removeScoreboard();
|
session.getWorldCache().removeScoreboard();
|
||||||
}
|
}
|
||||||
|
session.setWorldName(packet.getWorldName());
|
||||||
|
|
||||||
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
AdventureSettingsPacket bedrockPacket = new AdventureSettingsPacket();
|
||||||
bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId());
|
bedrockPacket.setUniqueEntityId(session.getPlayerEntity().getGeyserId());
|
||||||
|
@ -43,8 +43,6 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
|
|||||||
@Override
|
@Override
|
||||||
public void translate(ServerRespawnPacket packet, GeyserSession session) {
|
public void translate(ServerRespawnPacket packet, GeyserSession session) {
|
||||||
Entity entity = session.getPlayerEntity();
|
Entity entity = session.getPlayerEntity();
|
||||||
if (entity == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float maxHealth = entity.getAttributes().containsKey(AttributeType.MAX_HEALTH) ? entity.getAttributes().get(AttributeType.MAX_HEALTH).getValue() : 20f;
|
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
|
// Max health must be divisible by two in bedrock
|
||||||
@ -66,18 +64,24 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
|
|||||||
session.setRaining(false);
|
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());
|
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
||||||
if (!session.getDimension().equals(newDimension)) {
|
if (!session.getDimension().equals(newDimension) || !packet.getWorldName().equals(session.getWorldName())) {
|
||||||
DimensionUtils.switchDimension(session, newDimension);
|
if (!packet.getWorldName().equals(session.getWorldName()) && session.getDimension().equals(newDimension)) {
|
||||||
} else {
|
// Switching to a new world (based off the world name change); send a fake dimension change
|
||||||
if (session.isManyDimPackets()) { //reloading world
|
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
|
||||||
String fakeDim = session.getDimension().equals(DimensionUtils.OVERWORLD) ? DimensionUtils.NETHER : DimensionUtils.OVERWORLD;
|
|
||||||
DimensionUtils.switchDimension(session, fakeDim);
|
DimensionUtils.switchDimension(session, fakeDim);
|
||||||
|
}
|
||||||
|
session.setWorldName(packet.getWorldName());
|
||||||
DimensionUtils.switchDimension(session, newDimension);
|
DimensionUtils.switchDimension(session, newDimension);
|
||||||
} else {
|
|
||||||
// Handled in JavaPlayerPositionRotationTranslator
|
|
||||||
session.setSpawned(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,13 +46,11 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator<Serve
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(ServerPlayerPositionRotationPacket packet, GeyserSession session) {
|
public void translate(ServerPlayerPositionRotationPacket packet, GeyserSession session) {
|
||||||
PlayerEntity entity = session.getPlayerEntity();
|
|
||||||
if (entity == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!session.isLoggedIn())
|
if (!session.isLoggedIn())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
|
|
||||||
if (!session.isSpawned()) {
|
if (!session.isSpawned()) {
|
||||||
Vector3f pos = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
Vector3f pos = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||||
entity.setPosition(pos);
|
entity.setPosition(pos);
|
||||||
|
@ -57,8 +57,6 @@ public class DimensionUtils {
|
|||||||
public static void switchDimension(GeyserSession session, String javaDimension) {
|
public static void switchDimension(GeyserSession session, String javaDimension) {
|
||||||
int bedrockDimension = javaToBedrock(javaDimension);
|
int bedrockDimension = javaToBedrock(javaDimension);
|
||||||
Entity player = session.getPlayerEntity();
|
Entity player = session.getPlayerEntity();
|
||||||
if (javaDimension.equals(session.getDimension()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (session.getMovementSendIfIdle() != null) {
|
if (session.getMovementSendIfIdle() != null) {
|
||||||
session.getMovementSendIfIdle().cancel(true);
|
session.getMovementSendIfIdle().cancel(true);
|
||||||
@ -67,9 +65,6 @@ public class DimensionUtils {
|
|||||||
session.getEntityCache().removeAllEntities();
|
session.getEntityCache().removeAllEntities();
|
||||||
session.getItemFrameCache().clear();
|
session.getItemFrameCache().clear();
|
||||||
session.getSkullCache().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);
|
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
|
// Change dimension ID to the End to allow for building above Bedrock
|
||||||
BEDROCK_NETHER_ID = isAboveNetherBedrockBuilding ? 2 : 1;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren