Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-25 15:50:14 +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.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;
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren