1
0
mirror of https://github.com/GeyserMC/Geyser.git synced 2025-12-28 11:19:11 +00:00

Fix issues with custom dimension heights (#5492)

* Fix java maxY and java height getting mixed up

* Fix incorrect size for bedrock chunk section array
This commit is contained in:
booky
2025-04-17 21:06:38 +02:00
committed by GitHub
parent 6e162c2cf5
commit efd4dccb60
4 changed files with 17 additions and 13 deletions

View File

@@ -40,12 +40,12 @@ import org.geysermc.geyser.util.DimensionUtils;
* As a Java dimension can be null in some login cases (e.g. GeyserConnect), make sure the player
* is logged in before utilizing this field.
*/
public record JavaDimension(int minY, int maxY, boolean piglinSafe, boolean ultrawarm, double worldCoordinateScale, int bedrockId, boolean isNetherLike) {
public record JavaDimension(int minY, int height, boolean piglinSafe, boolean ultrawarm, double worldCoordinateScale, int bedrockId, boolean isNetherLike) {
public static JavaDimension read(RegistryEntryContext entry) {
NbtMap dimension = entry.data();
int minY = dimension.getInt("min_y");
int maxY = dimension.getInt("height");
int height = dimension.getInt("height");
// Logical height can be ignored probably - seems to be for artificial limits like the Nether.
// Set if piglins/hoglins should shake
@@ -74,10 +74,10 @@ public record JavaDimension(int minY, int maxY, boolean piglinSafe, boolean ultr
if (minY % 16 != 0) {
throw new RuntimeException("Minimum Y must be a multiple of 16!");
}
if (maxY % 16 != 0) {
throw new RuntimeException("Maximum Y must be a multiple of 16!");
if (height % 16 != 0) {
throw new RuntimeException("Height must be a multiple of 16!");
}
return new JavaDimension(minY, maxY, piglinSafe, ultrawarm, coordinateScale, bedrockId, isNetherLike);
return new JavaDimension(minY, height, piglinSafe, ultrawarm, coordinateScale, bedrockId, isNetherLike);
}
}

View File

@@ -178,7 +178,6 @@ import org.geysermc.geyser.session.cache.WorldCache;
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.ChunkUtils;
import org.geysermc.geyser.util.EntityUtils;
@@ -752,7 +751,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
for (JavaDimension javaDimension : this.registryCache.registry(JavaRegistries.DIMENSION_TYPE).values()) {
if (javaDimension.bedrockId() == BedrockDimension.OVERWORLD_ID) {
minY = Math.min(minY, javaDimension.minY());
maxY = Math.max(maxY, javaDimension.maxY());
maxY = Math.max(maxY, javaDimension.minY() + javaDimension.height());
}
}
minY = Math.max(minY, -512);

View File

@@ -110,7 +110,11 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
int sectionCount;
byte[] payload;
ByteBuf byteBuf = null;
GeyserChunkSection[] sections = new GeyserChunkSection[javaChunks.length - (yOffset + (bedrockDimension.minY() >> 4))];
// calculate the difference between the java dimension minY and the bedrock dimension minY as
// the java chunk sections may need to be placed higher up in the bedrock chunk section array
int sectionCountDiff = yOffset - (bedrockDimension.minY() >> 4);
GeyserChunkSection[] sections = new GeyserChunkSection[chunkSize + sectionCountDiff];
try {
ByteBuf in = Unpooled.wrappedBuffer(packet.getChunkData());
@@ -122,7 +126,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
boolean extendedCollision = extendedCollisionNextSection;
boolean thisExtendedCollisionNextSection = false;
int bedrockSectionY = sectionY + (yOffset - (bedrockDimension.minY() >> 4));
int bedrockSectionY = sectionY + sectionCountDiff;
int subChunkIndex = sectionY + yOffset;
if (bedrockSectionY < 0 || maxBedrockSectionY < bedrockSectionY) {
// Ignore this chunk section since it goes outside the bounds accepted by the Bedrock client

View File

@@ -213,21 +213,22 @@ public class ChunkUtils {
public static void loadDimension(GeyserSession session) {
JavaDimension dimension = session.getDimensionType();
int minY = dimension.minY();
int maxY = dimension.maxY();
int height = dimension.height();
int maxY = minY + height;
BedrockDimension bedrockDimension = session.getBedrockDimension();
// Yell in the console if the world height is too height in the current scenario
// The constraints change depending on if the player is in the overworld or not, and if experimental height is enabled
// (Ignore this for the Nether. We can't change that at the moment without the workaround. :/ )
if (minY < bedrockDimension.minY() || (bedrockDimension.doUpperHeightWarn() && maxY > bedrockDimension.height())) {
if (minY < bedrockDimension.minY() || (bedrockDimension.doUpperHeightWarn() && maxY > bedrockDimension.maxY())) {
session.getGeyser().getLogger().warning(GeyserLocale.getLocaleStringLog("geyser.network.translator.chunk.out_of_bounds",
String.valueOf(bedrockDimension.minY()),
String.valueOf(bedrockDimension.height()),
String.valueOf(bedrockDimension.maxY()),
session.getRegistryCache().registry(JavaRegistries.DIMENSION_TYPE).byValue(session.getDimensionType())));
}
session.getChunkCache().setMinY(minY);
session.getChunkCache().setHeightY(maxY);
session.getChunkCache().setHeightY(height);
session.getWorldBorder().setWorldCoordinateScale(dimension.worldCoordinateScale());
}