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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user