Fix #4837 by not hardcoding dimension IDs

This commit is contained in:
Camotoy 2024-07-13 15:11:22 -04:00
parent 93b0a61265
commit 6e0bad3c40
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
12 changed files with 135 additions and 98 deletions

View file

@ -30,7 +30,11 @@ import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
import org.cloudburstmc.protocol.bedrock.packet.*;
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Tickable;
import org.geysermc.geyser.entity.type.living.MobEntity;
@ -260,7 +264,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
// so we need to manually spawn particles
for (int i = 0; i < 8; i++) {
SpawnParticleEffectPacket spawnParticleEffectPacket = new SpawnParticleEffectPacket();
spawnParticleEffectPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getDimension()));
spawnParticleEffectPacket.setDimensionId(DimensionUtils.javaToBedrock(session));
spawnParticleEffectPacket.setPosition(head.getPosition().add(random.nextGaussian() / 2f, random.nextGaussian() / 2f, random.nextGaussian() / 2f));
spawnParticleEffectPacket.setIdentifier("minecraft:dragon_breath_fire");
spawnParticleEffectPacket.setMolangVariablesJson(Optional.empty());

View file

@ -25,15 +25,17 @@
package org.geysermc.geyser.level;
import net.kyori.adventure.key.Key;
import org.cloudburstmc.nbt.NbtMap;
import org.geysermc.geyser.session.cache.registry.RegistryEntryContext;
import org.geysermc.geyser.util.DimensionUtils;
/**
* Represents the information we store from the current Java dimension
* @param piglinSafe Whether piglins and hoglins are safe from conversion in this dimension.
* This controls if they have the shaking effect applied in the dimension.
*/
public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale) {
public record JavaDimension(int minY, int maxY, boolean piglinSafe, double worldCoordinateScale, int bedrockId, boolean isNetherLike) {
public static JavaDimension read(RegistryEntryContext entry) {
NbtMap dimension = entry.data();
@ -46,6 +48,22 @@ public record JavaDimension(int minY, int maxY, boolean piglinSafe, double world
// Load world coordinate scale for the world border
double coordinateScale = dimension.getDouble("coordinate_scale");
return new JavaDimension(minY, maxY, piglinSafe, coordinateScale);
boolean isNetherLike;
// Cache the Bedrock version of this dimension, and base it off the ID - THE ID CAN CHANGE!!!
// https://github.com/GeyserMC/Geyser/issues/4837
int bedrockId;
Key id = entry.id();
if ("minecraft".equals(id.namespace())) {
String identifier = id.asString();
bedrockId = DimensionUtils.javaToBedrock(identifier);
isNetherLike = DimensionUtils.NETHER_IDENTIFIER.equals(identifier);
} else {
// Effects should give is a clue on how this (custom) dimension is supposed to look like
String effects = dimension.getString("effects");
bedrockId = DimensionUtils.javaToBedrock(effects);
isNetherLike = DimensionUtils.NETHER_IDENTIFIER.equals(effects);
}
return new JavaDimension(minY, maxY, piglinSafe, coordinateScale, bedrockId, isNetherLike);
}
}

View file

@ -312,8 +312,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
* The dimension of the player.
* As all entities are in the same world, this can be safely applied to all other entities.
*/
@Setter
private int dimension = DimensionUtils.OVERWORLD;
@MonotonicNonNull
@Setter
private JavaDimension dimensionType = null;

View file

@ -27,6 +27,7 @@ package org.geysermc.geyser.translator.protocol.java;
import net.kyori.adventure.key.Key;
import org.geysermc.erosion.Constants;
import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.util.MinecraftKey;
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerSpawnInfo;
import org.geysermc.mcprotocollib.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
@ -65,12 +66,15 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
}
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
boolean forceDimSwitch = false;
// If the player is already initialized and a join game packet is sent, they
// are swapping servers
if (session.isSpawned()) {
int fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), spawnInfo.getDimension());
DimensionUtils.switchDimension(session, fakeDim);
int fakeDim = DimensionUtils.getTemporaryDimension(session.getDimensionType().bedrockId(), newDimension.bedrockId());
DimensionUtils.fastSwitchDimension(session, fakeDim);
forceDimSwitch = true;
session.getWorldCache().removeScoreboard();
@ -103,13 +107,12 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
session.setWorldName(spawnInfo.getWorldName());
session.setLevels(Arrays.stream(packet.getWorldNames()).map(Key::asString).toArray(String[]::new));
session.setGameMode(spawnInfo.getGameMode());
int newDimension = spawnInfo.getDimension();
boolean needsSpawnPacket = !session.isSentSpawnPacket();
if (needsSpawnPacket) {
// The player has yet to spawn so let's do that using some of the information in this Java packet
session.setDimension(newDimension);
DimensionUtils.setBedrockDimension(session, newDimension);
session.setDimensionType(newDimension);
DimensionUtils.setBedrockDimension(session, newDimension.bedrockId());
session.connect();
// It is now safe to send these packets
@ -143,9 +146,9 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
}
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(register, Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8)));
if (newDimension != session.getDimension()) {
if (newDimension != session.getDimensionType() || forceDimSwitch) {
DimensionUtils.switchDimension(session, newDimension);
} else if (DimensionUtils.isCustomBedrockNetherId() && newDimension == DimensionUtils.NETHER) {
} else if (DimensionUtils.isCustomBedrockNetherId() && newDimension.isNetherLike()) {
// If the player is spawning into the "fake" nether, send them some fog
session.camera().sendFog(DimensionUtils.BEDROCK_FOG_HELL);
}

View file

@ -31,6 +31,7 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -92,12 +93,12 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
session.setThunder(false);
}
int newDimension = spawnInfo.getDimension();
if (session.getDimension() != newDimension || !spawnInfo.getWorldName().equals(session.getWorldName())) {
JavaDimension newDimension = session.getRegistryCache().dimensions().byId(spawnInfo.getDimension());
if (session.getDimensionType() != newDimension || !spawnInfo.getWorldName().equals(session.getWorldName())) {
// Switching to a new world (based off the world name change or new dimension); send a fake dimension change
if (DimensionUtils.javaToBedrock(session.getDimension()) == DimensionUtils.javaToBedrock(newDimension)) {
int fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
DimensionUtils.switchDimension(session, fakeDim);
if (session.getDimensionType().bedrockId() == newDimension.bedrockId()) {
int fakeDim = DimensionUtils.getTemporaryDimension(session.getDimensionType().bedrockId(), newDimension.bedrockId());
DimensionUtils.fastSwitchDimension(session, fakeDim);
}
session.setWorldName(spawnInfo.getWorldName());
DimensionUtils.switchDimension(session, newDimension);

View file

@ -92,7 +92,7 @@ public class JavaAnimateTranslator extends PacketTranslator<ClientboundAnimatePa
// Spawn custom particle
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
stringPacket.setIdentifier("geyseropt:enchanted_hit_multiple");
stringPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getDimension()));
stringPacket.setDimensionId(DimensionUtils.javaToBedrock(session));
stringPacket.setPosition(Vector3f.ZERO);
stringPacket.setUniqueEntityId(entity.getGeyserId());
stringPacket.setMolangVariablesJson(Optional.empty());

View file

@ -28,7 +28,6 @@ package org.geysermc.geyser.translator.protocol.java.level;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.nbt.NbtMap;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
@ -481,7 +480,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
}
private static void spawnOminousTrialSpawnerParticles(GeyserSession session, Vector3f pos) {
int dimensionId = DimensionUtils.javaToBedrock(session.getDimension());
int dimensionId = DimensionUtils.javaToBedrock(session);
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
stringPacket.setIdentifier("minecraft:trial_spawner_detection_ominous");
stringPacket.setDimensionId(dimensionId);

View file

@ -191,7 +191,7 @@ public class JavaLevelParticlesTranslator extends PacketTranslator<ClientboundLe
return packet;
};
} else if (particleMapping.identifier() != null) {
int dimensionId = DimensionUtils.javaToBedrock(session.getDimension());
int dimensionId = DimensionUtils.javaToBedrock(session);
return (position) -> {
SpawnParticleEffectPacket stringPacket = new SpawnParticleEffectPacket();
stringPacket.setIdentifier(particleMapping.identifier());

View file

@ -46,7 +46,7 @@ public class JavaMapItemDataTranslator extends PacketTranslator<ClientboundMapIt
org.cloudburstmc.protocol.bedrock.packet.ClientboundMapItemDataPacket mapItemDataPacket = new org.cloudburstmc.protocol.bedrock.packet.ClientboundMapItemDataPacket();
mapItemDataPacket.setUniqueMapId(packet.getMapId());
mapItemDataPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getDimension()));
mapItemDataPacket.setDimensionId(DimensionUtils.javaToBedrock(session));
mapItemDataPacket.setLocked(packet.isLocked());
mapItemDataPacket.setOrigin(Vector3i.ZERO); // Required since 1.19.20
mapItemDataPacket.setScale(packet.getScale());

View file

@ -39,7 +39,7 @@ public class JavaSetDefaultSpawnPositionTranslator extends PacketTranslator<Clie
public void translate(GeyserSession session, ClientboundSetDefaultSpawnPositionPacket packet) {
SetSpawnPositionPacket spawnPositionPacket = new SetSpawnPositionPacket();
spawnPositionPacket.setBlockPosition(packet.getPosition());
spawnPositionPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getDimension()));
spawnPositionPacket.setDimensionId(DimensionUtils.javaToBedrock(session));
spawnPositionPacket.setSpawnType(SetSpawnPositionPacket.Type.WORLD_SPAWN);
session.sendUpstreamPacket(spawnPositionPacket);
}

View file

@ -203,8 +203,7 @@ public class ChunkUtils {
* This must be done after the player has switched dimensions so we know what their dimension is
*/
public static void loadDimension(GeyserSession session) {
JavaDimension dimension = session.getRegistryCache().dimensions().byId(session.getDimension());
session.setDimensionType(dimension);
JavaDimension dimension = session.getDimensionType();
int minY = dimension.minY();
int maxY = dimension.maxY();
@ -223,7 +222,7 @@ public class ChunkUtils {
session.getGeyser().getLogger().warning(GeyserLocale.getLocaleStringLog("geyser.network.translator.chunk.out_of_bounds",
String.valueOf(bedrockDimension.minY()),
String.valueOf(bedrockDimension.height()),
session.getDimension()));
session.getRegistryCache().dimensions().byValue(session.getDimensionType())));
}
session.getChunkCache().setMinY(minY);

View file

@ -28,9 +28,14 @@ package org.geysermc.geyser.util;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.PlayerActionType;
import org.cloudburstmc.protocol.bedrock.packet.*;
import org.cloudburstmc.protocol.bedrock.packet.ChangeDimensionPacket;
import org.cloudburstmc.protocol.bedrock.packet.ChunkRadiusUpdatedPacket;
import org.cloudburstmc.protocol.bedrock.packet.MobEffectPacket;
import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket;
import org.cloudburstmc.protocol.bedrock.packet.StopSoundPacket;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.level.BedrockDimension;
import org.geysermc.geyser.level.JavaDimension;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
@ -43,22 +48,18 @@ public class DimensionUtils {
public static final String BEDROCK_FOG_HELL = "minecraft:fog_hell";
/**
* String reference to vanilla Java overworld dimension identifier
*/
public static final int OVERWORLD = 0;
/**
* String reference to vanilla Java nether dimension identifier
*/
public static final int NETHER = 3;
/**
* String reference to vanilla Java end dimension identifier
*/
public static final int THE_END = 2;
public static final String NETHER_IDENTIFIER = "minecraft:the_nether";
public static void switchDimension(GeyserSession session, int javaDimension) {
int bedrockDimension = javaToBedrock(javaDimension); // new bedrock dimension
int previousDimension = session.getDimension(); // previous java dimension
private static final int BEDROCK_OVERWORLD_ID = 0;
private static final int BEDROCK_DEFAULT_NETHER_ID = 1;
private static final int BEDROCK_END_ID = 2;
public static void switchDimension(GeyserSession session, JavaDimension javaDimension) {
switchDimension(session, javaDimension, javaDimension.bedrockId());
}
public static void switchDimension(GeyserSession session, JavaDimension javaDimension, int bedrockDimension) {
JavaDimension previousDimension = session.getDimensionType(); // previous java dimension
Entity player = session.getPlayerEntity();
@ -69,6 +70,44 @@ public class DimensionUtils {
session.getPistonCache().clear();
session.getSkullCache().clear();
changeDimension(session, bedrockDimension);
session.setDimensionType(javaDimension);
Set<Effect> entityEffects = session.getEffectCache().getEntityEffects();
for (Effect effect : entityEffects) {
MobEffectPacket mobEffectPacket = new MobEffectPacket();
mobEffectPacket.setEvent(MobEffectPacket.Event.REMOVE);
mobEffectPacket.setRuntimeEntityId(player.getGeyserId());
mobEffectPacket.setEffectId(EntityUtils.toBedrockEffectId(effect));
session.sendUpstreamPacket(mobEffectPacket);
}
// Effects are re-sent from server
entityEffects.clear();
finalizeDimensionSwitch(session, player);
// If the bedrock nether height workaround is enabled, meaning the client is told it's in the end dimension,
// we check if the player is entering the nether and apply the nether fog to fake the fact that the client
// thinks they are in the end dimension.
if (isCustomBedrockNetherId()) {
if (javaDimension.isNetherLike()) {
session.camera().sendFog(BEDROCK_FOG_HELL);
} else if (previousDimension.isNetherLike()) {
session.camera().removeFog(BEDROCK_FOG_HELL);
}
}
}
/**
* Switch dimensions without clearing internal logic.
*/
public static void fastSwitchDimension(GeyserSession session, int bedrockDimension) {
changeDimension(session, bedrockDimension);
finalizeDimensionSwitch(session, session.getPlayerEntity());
}
private static void changeDimension(GeyserSession session, int bedrockDimension) {
if (session.getServerRenderDistance() > 32 && !session.isEmulatePost1_13Logic()) {
// The server-sided view distance wasn't a thing until Minecraft Java 1.14
// So ViaVersion compensates by sending a "view distance" of 64
@ -77,7 +116,7 @@ public class DimensionUtils {
// To solve this, we cap at 32 unless we know that the render distance actually exceeds 32
// Also, as of 1.19: PS4 crashes with a ChunkRadiusUpdatedPacket too large
session.getGeyser().getLogger().debug("Applying dimension switching workaround for Bedrock render distance of "
+ session.getServerRenderDistance());
+ session.getServerRenderDistance());
ChunkRadiusUpdatedPacket chunkRadiusUpdatedPacket = new ChunkRadiusUpdatedPacket();
chunkRadiusUpdatedPacket.setRadius(32);
session.sendUpstreamPacket(chunkRadiusUpdatedPacket);
@ -92,24 +131,14 @@ public class DimensionUtils {
changeDimensionPacket.setPosition(pos);
session.sendUpstreamPacket(changeDimensionPacket);
session.setDimension(javaDimension);
setBedrockDimension(session, javaDimension);
setBedrockDimension(session, bedrockDimension);
player.setPosition(pos);
session.getPlayerEntity().setPosition(pos);
session.setSpawned(false);
session.setLastChunkPosition(null);
}
Set<Effect> entityEffects = session.getEffectCache().getEntityEffects();
for (Effect effect : entityEffects) {
MobEffectPacket mobEffectPacket = new MobEffectPacket();
mobEffectPacket.setEvent(MobEffectPacket.Event.REMOVE);
mobEffectPacket.setRuntimeEntityId(player.getGeyserId());
mobEffectPacket.setEffectId(EntityUtils.toBedrockEffectId(effect));
session.sendUpstreamPacket(mobEffectPacket);
}
// Effects are re-sent from server
entityEffects.clear();
private static void finalizeDimensionSwitch(GeyserSession session, Entity player) {
//let java server handle portal travel sound
StopSoundPacket stopSoundPacket = new StopSoundPacket();
stopSoundPacket.setStoppingAllSound(true);
@ -130,23 +159,12 @@ public class DimensionUtils {
// TODO - fix this hack of a fix by sending the final dimension switching logic after sections have been sent.
// The client wants sections sent to it before it can successfully respawn.
ChunkUtils.sendEmptyChunks(session, player.getPosition().toInt(), 3, true);
// If the bedrock nether height workaround is enabled, meaning the client is told it's in the end dimension,
// we check if the player is entering the nether and apply the nether fog to fake the fact that the client
// thinks they are in the end dimension.
if (isCustomBedrockNetherId()) {
if (NETHER == javaDimension) {
session.camera().sendFog(BEDROCK_FOG_HELL);
} else if (NETHER == previousDimension) {
session.camera().removeFog(BEDROCK_FOG_HELL);
}
}
}
public static void setBedrockDimension(GeyserSession session, int javaDimension) {
session.getChunkCache().setBedrockDimension(switch (javaDimension) {
case DimensionUtils.THE_END -> BedrockDimension.THE_END;
case DimensionUtils.NETHER -> DimensionUtils.isCustomBedrockNetherId() ? BedrockDimension.THE_END : BedrockDimension.THE_NETHER;
public static void setBedrockDimension(GeyserSession session, int bedrockDimension) {
session.getChunkCache().setBedrockDimension(switch (bedrockDimension) {
case BEDROCK_END_ID -> BedrockDimension.THE_END;
case BEDROCK_DEFAULT_NETHER_ID -> BedrockDimension.THE_NETHER; // JavaDimension *should* be set to BEDROCK_END_ID if the Nether workaround is enabled.
default -> BedrockDimension.OVERWORLD;
});
}
@ -155,26 +173,12 @@ public class DimensionUtils {
if (dimension == BedrockDimension.THE_NETHER) {
return BEDROCK_NETHER_ID;
} else if (dimension == BedrockDimension.THE_END) {
return 2;
return BEDROCK_END_ID;
} else {
return 0;
return BEDROCK_OVERWORLD_ID;
}
}
/**
* Map the Java edition dimension IDs to Bedrock edition
*
* @param javaDimension Dimension ID to convert
* @return Converted Bedrock edition dimension ID
*/
public static int javaToBedrock(int javaDimension) {
return switch (javaDimension) {
case NETHER -> BEDROCK_NETHER_ID;
case THE_END -> 2;
default -> 0;
};
}
/**
* Map the Java edition dimension IDs to Bedrock edition
*
@ -183,12 +187,23 @@ public class DimensionUtils {
*/
public static int javaToBedrock(String javaDimension) {
return switch (javaDimension) {
case "minecraft:the_nether" -> BEDROCK_NETHER_ID;
case NETHER_IDENTIFIER -> BEDROCK_NETHER_ID;
case "minecraft:the_end" -> 2;
default -> 0;
};
}
/**
* Gets the Bedrock dimension ID, with a safety check if a packet is created before the player is logged/spawned in.
*/
public static int javaToBedrock(GeyserSession session) {
JavaDimension dimension = session.getDimensionType();
if (dimension == null) {
return BEDROCK_OVERWORLD_ID;
}
return dimension.bedrockId();
}
/**
* The Nether dimension in Bedrock does not permit building above Y128 - the Bedrock above the dimension.
* This workaround sets the Nether as the End dimension to ignore this limit.
@ -197,28 +212,28 @@ public class DimensionUtils {
*/
public static void changeBedrockNetherId(boolean isAboveNetherBedrockBuilding) {
// Change dimension ID to the End to allow for building above Bedrock
BEDROCK_NETHER_ID = isAboveNetherBedrockBuilding ? 2 : 1;
BEDROCK_NETHER_ID = isAboveNetherBedrockBuilding ? BEDROCK_END_ID : BEDROCK_DEFAULT_NETHER_ID;
}
/**
* 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
* @param currentBedrockDimension the current dimension of the player
* @param newBedrockDimension the new dimension that the player will be transferred to
* @return the Bedrock fake dimension to transfer to
*/
public static int getTemporaryDimension(int currentDimension, int newDimension) {
public static int getTemporaryDimension(int currentBedrockDimension, int newBedrockDimension) {
if (isCustomBedrockNetherId()) {
// Prevents rare instances of Bedrock locking up
return javaToBedrock(newDimension) == 2 ? OVERWORLD : NETHER;
return newBedrockDimension == BEDROCK_END_ID ? BEDROCK_OVERWORLD_ID : BEDROCK_END_ID;
}
// Check current Bedrock dimension and not just the Java dimension.
// Fixes rare instances like https://github.com/GeyserMC/Geyser/issues/3161
return javaToBedrock(currentDimension) == 0 ? NETHER : OVERWORLD;
return currentBedrockDimension == BEDROCK_OVERWORLD_ID ? BEDROCK_DEFAULT_NETHER_ID : BEDROCK_OVERWORLD_ID;
}
public static boolean isCustomBedrockNetherId() {
return BEDROCK_NETHER_ID == 2;
return BEDROCK_NETHER_ID == BEDROCK_END_ID;
}
}