Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 15:00:11 +01:00
Improve code
Dieser Commit ist enthalten in:
Ursprung
98df97e863
Commit
6b2f315230
@ -76,6 +76,7 @@ import org.geysermc.geyser.erosion.UnixSocketClientListener;
|
||||
import org.geysermc.geyser.event.GeyserEventBus;
|
||||
import org.geysermc.geyser.extension.GeyserExtensionManager;
|
||||
import org.geysermc.geyser.impl.MinecraftVersionImpl;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.level.WorldManager;
|
||||
import org.geysermc.geyser.network.GameProtocol;
|
||||
import org.geysermc.geyser.network.netty.GeyserServer;
|
||||
@ -95,7 +96,6 @@ import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.AssetUtils;
|
||||
import org.geysermc.geyser.util.CooldownUtils;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
import org.geysermc.geyser.util.Metrics;
|
||||
import org.geysermc.geyser.util.MinecraftAuthLogger;
|
||||
import org.geysermc.geyser.util.NewsHandler;
|
||||
@ -421,7 +421,7 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
||||
}
|
||||
|
||||
CooldownUtils.setDefaultShowCooldown(config.getShowCooldown());
|
||||
DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
|
||||
BedrockDimension.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
|
||||
|
||||
Integer bedrockThreadCount = Integer.getInteger("Geyser.BedrockNetworkThreads");
|
||||
if (bedrockThreadCount == null) {
|
||||
|
@ -25,27 +25,86 @@
|
||||
|
||||
package org.geysermc.geyser.level;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* A data structure to represent what Bedrock believes are the height requirements for a specific dimension.
|
||||
* As of 1.18.30, biome count is representative of the height of the world, and out-of-bounds chunks can crash
|
||||
* the client.
|
||||
*
|
||||
* @param minY The minimum height Bedrock Edition will accept.
|
||||
* @param height The maximum chunk height Bedrock Edition will accept, from the lowest point to the highest.
|
||||
* @param doUpperHeightWarn whether to warn in the console if the Java dimension height exceeds Bedrock's.
|
||||
*/
|
||||
public record BedrockDimension(int minY, int height, boolean doUpperHeightWarn, int bedrockId) {
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class BedrockDimension {
|
||||
|
||||
public static final int OVERWORLD_ID = 0;
|
||||
public static final int DEFAULT_NETHER_ID = 1;
|
||||
public static final int END_ID = 2;
|
||||
|
||||
// Changes if the above-bedrock Nether building workaround is applied
|
||||
public static int BEDROCK_NETHER_ID = DEFAULT_NETHER_ID;
|
||||
|
||||
public static final BedrockDimension OVERWORLD = new BedrockDimension(-64, 384, true, OVERWORLD_ID);
|
||||
public static final BedrockDimension THE_NETHER = new BedrockDimension(0, 128, false, DEFAULT_NETHER_ID);
|
||||
public static final BedrockDimension THE_NETHER = new BedrockDimension(0, 128, false, -1) {
|
||||
@Override
|
||||
public int bedrockId() {
|
||||
return BEDROCK_NETHER_ID;
|
||||
}
|
||||
};
|
||||
public static final BedrockDimension THE_END = new BedrockDimension(0, 256, true, END_ID);
|
||||
public static final String NETHER_IDENTIFIER = "minecraft:the_nether";
|
||||
|
||||
private final int minY;
|
||||
private final int height;
|
||||
private final boolean doUpperHeightWarn;
|
||||
private final int bedrockId;
|
||||
|
||||
/**
|
||||
* @param minY The minimum height Bedrock Edition will accept.
|
||||
* @param height The maximum chunk height Bedrock Edition will accept, from the lowest point to the highest.
|
||||
* @param doUpperHeightWarn whether to warn in the console if the Java dimension height exceeds Bedrock's.
|
||||
* @param bedrockId the Bedrock dimension ID of this dimension.
|
||||
*/
|
||||
public BedrockDimension(int minY, int height, boolean doUpperHeightWarn, int bedrockId) {
|
||||
this.minY = minY;
|
||||
this.height = height;
|
||||
this.doUpperHeightWarn = doUpperHeightWarn;
|
||||
this.bedrockId = 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.
|
||||
*
|
||||
* @param isAboveNetherBedrockBuilding true if we should apply The End workaround
|
||||
*/
|
||||
public static void changeBedrockNetherId(boolean isAboveNetherBedrockBuilding) {
|
||||
// Change dimension ID to the End to allow for building above Bedrock
|
||||
BEDROCK_NETHER_ID = isAboveNetherBedrockBuilding ? END_ID : DEFAULT_NETHER_ID;
|
||||
}
|
||||
|
||||
public static boolean isCustomBedrockNetherId() {
|
||||
return BEDROCK_NETHER_ID == END_ID;
|
||||
}
|
||||
|
||||
public int maxY() {
|
||||
return minY + height;
|
||||
}
|
||||
|
||||
public int minY() {
|
||||
return minY;
|
||||
}
|
||||
|
||||
public int height() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public boolean doUpperHeightWarn() {
|
||||
return doUpperHeightWarn;
|
||||
}
|
||||
|
||||
public int bedrockId() {
|
||||
return bedrockId;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -63,12 +63,19 @@ public record JavaDimension(int minY, int maxY, boolean piglinSafe, boolean ultr
|
||||
if ("minecraft".equals(id.namespace())) {
|
||||
String identifier = id.asString();
|
||||
bedrockId = DimensionUtils.javaToBedrock(identifier);
|
||||
isNetherLike = DimensionUtils.NETHER_IDENTIFIER.equals(identifier);
|
||||
isNetherLike = BedrockDimension.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);
|
||||
isNetherLike = BedrockDimension.NETHER_IDENTIFIER.equals(effects);
|
||||
}
|
||||
|
||||
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!");
|
||||
}
|
||||
|
||||
return new JavaDimension(minY, maxY, piglinSafe, ultrawarm, coordinateScale, bedrockId, isNetherLike);
|
||||
|
@ -173,7 +173,6 @@ import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.ChunkUtils;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.LoginEncryptionUtils;
|
||||
import org.geysermc.geyser.util.MinecraftAuthLogger;
|
||||
@ -713,15 +712,15 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
* Send all necessary packets to load Bedrock into the server
|
||||
*/
|
||||
public void connect() {
|
||||
if (this.dimensionType.minY() < BedrockDimension.OVERWORLD.minY() || this.dimensionType.maxY() > BedrockDimension.OVERWORLD.maxY()) {
|
||||
final int minY = Math.max(this.dimensionType.minY(), -512);
|
||||
final int maxY = Math.min(this.dimensionType.maxY(), 512);
|
||||
if (this.dimensionType.bedrockId() == BedrockDimension.OVERWORLD_ID && this.dimensionType.minY() < BedrockDimension.OVERWORLD.minY() || this.dimensionType.maxY() > BedrockDimension.OVERWORLD.maxY()) {
|
||||
int minY = Math.max(this.dimensionType.minY(), -512);
|
||||
int maxY = Math.min(this.dimensionType.maxY(), 512);
|
||||
this.bedrockOverworldDimension = new BedrockDimension(minY, maxY - minY, true, BedrockDimension.OVERWORLD_ID);
|
||||
this.bedrockDimension = this.bedrockOverworldDimension;
|
||||
geyser.getLogger().debug("Extending overworld dimension to " + minY + " - " + maxY);
|
||||
|
||||
final DimensionDataPacket dimensionDataPacket = new DimensionDataPacket();
|
||||
dimensionDataPacket.getDefinitions().add(new DimensionDefinition("minecraft:overworld", maxY, minY, 5));
|
||||
DimensionDataPacket dimensionDataPacket = new DimensionDataPacket();
|
||||
dimensionDataPacket.getDefinitions().add(new DimensionDefinition("minecraft:overworld", maxY, minY, 5 /* Void */));
|
||||
upstream.sendPacket(dimensionDataPacket);
|
||||
}
|
||||
|
||||
@ -1597,7 +1596,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||
startGamePacket.setRotation(Vector2f.from(1, 1));
|
||||
|
||||
startGamePacket.setSeed(-1L);
|
||||
startGamePacket.setDimensionId(DimensionUtils.javaToBedrock(bedrockDimension));
|
||||
startGamePacket.setDimensionId(bedrockDimension.bedrockId());
|
||||
startGamePacket.setGeneratorId(1);
|
||||
startGamePacket.setLevelGameType(GameType.SURVIVAL);
|
||||
startGamePacket.setDifficulty(1);
|
||||
|
@ -34,6 +34,7 @@ import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
||||
import org.geysermc.geyser.api.network.AuthType;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.level.JavaDimension;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
@ -68,7 +69,7 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||
// If the player is already initialized and a join game packet is sent, they
|
||||
// are swapping servers
|
||||
if (session.isSpawned()) {
|
||||
int fakeDim = DimensionUtils.getTemporaryDimension(DimensionUtils.javaToBedrock(session.getBedrockDimension()), newDimension.bedrockId());
|
||||
int fakeDim = DimensionUtils.getTemporaryDimension(session.getBedrockDimension().bedrockId(), newDimension.bedrockId());
|
||||
if (fakeDim != newDimension.bedrockId()) {
|
||||
// The player's current dimension and new dimension are the same
|
||||
// We want a dimension switch to clear old chunks out, so switch to a dimension that isn't the one we're currently in.
|
||||
@ -127,9 +128,9 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||
}
|
||||
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(register, Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8)));
|
||||
|
||||
if (DimensionUtils.javaToBedrock(session.getBedrockDimension()) != newDimension.bedrockId()) {
|
||||
if (session.getBedrockDimension().bedrockId() != newDimension.bedrockId()) {
|
||||
DimensionUtils.switchDimension(session, newDimension);
|
||||
} else if (DimensionUtils.isCustomBedrockNetherId() && newDimension.isNetherLike()) {
|
||||
} else if (BedrockDimension.isCustomBedrockNetherId() && newDimension.isNetherLike()) {
|
||||
// If the player is spawning into the "fake" nether, send them some fog
|
||||
session.camera().sendFog(DimensionUtils.BEDROCK_FOG_HELL);
|
||||
}
|
||||
|
@ -29,7 +29,12 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntImmutableList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NBTOutputStream;
|
||||
@ -56,7 +61,6 @@ import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.BlockEntityUtils;
|
||||
import org.geysermc.geyser.util.ChunkUtils;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.BitStorage;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.ChunkSection;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.chunk.DataPalette;
|
||||
@ -509,7 +513,7 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||
levelChunkPacket.setChunkX(packet.getX());
|
||||
levelChunkPacket.setChunkZ(packet.getZ());
|
||||
levelChunkPacket.setData(Unpooled.wrappedBuffer(payload));
|
||||
levelChunkPacket.setDimension(DimensionUtils.javaToBedrock(session.getBedrockDimension()));
|
||||
levelChunkPacket.setDimension(session.getBedrockDimension().bedrockId());
|
||||
session.sendUpstreamPacket(levelChunkPacket);
|
||||
|
||||
for (Map.Entry<Vector3i, ItemFrameEntity> entry : session.getItemFrameCache().entrySet()) {
|
||||
|
@ -167,7 +167,7 @@ public class ChunkUtils {
|
||||
byteBuf.readBytes(payload);
|
||||
|
||||
LevelChunkPacket data = new LevelChunkPacket();
|
||||
data.setDimension(DimensionUtils.javaToBedrock(session.getBedrockDimension()));
|
||||
data.setDimension(session.getBedrockDimension().bedrockId());
|
||||
data.setChunkX(chunkX);
|
||||
data.setChunkZ(chunkZ);
|
||||
data.setSubChunksLength(0);
|
||||
@ -207,13 +207,6 @@ public class ChunkUtils {
|
||||
int minY = dimension.minY();
|
||||
int maxY = dimension.maxY();
|
||||
|
||||
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!");
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -46,13 +46,8 @@ import java.util.Set;
|
||||
|
||||
public class DimensionUtils {
|
||||
|
||||
// Changes if the above-bedrock Nether building workaround is applied
|
||||
private static int BEDROCK_NETHER_ID = 1;
|
||||
|
||||
public static final String BEDROCK_FOG_HELL = "minecraft:fog_hell";
|
||||
|
||||
public static final String NETHER_IDENTIFIER = "minecraft:the_nether";
|
||||
|
||||
public static void switchDimension(GeyserSession session, JavaDimension javaDimension) {
|
||||
switchDimension(session, javaDimension, javaDimension.bedrockId());
|
||||
}
|
||||
@ -103,7 +98,7 @@ public class DimensionUtils {
|
||||
// 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 (BedrockDimension.isCustomBedrockNetherId()) {
|
||||
if (javaDimension.isNetherLike()) {
|
||||
session.camera().sendFog(BEDROCK_FOG_HELL);
|
||||
} else if (previousDimension != null && previousDimension.isNetherLike()) {
|
||||
@ -182,14 +177,6 @@ public class DimensionUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static int javaToBedrock(BedrockDimension dimension) {
|
||||
if (dimension.bedrockId() == BedrockDimension.DEFAULT_NETHER_ID) {
|
||||
return BEDROCK_NETHER_ID;
|
||||
} else {
|
||||
return dimension.bedrockId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the Java edition dimension IDs to Bedrock edition
|
||||
*
|
||||
@ -198,7 +185,7 @@ public class DimensionUtils {
|
||||
*/
|
||||
public static int javaToBedrock(String javaDimension) {
|
||||
return switch (javaDimension) {
|
||||
case NETHER_IDENTIFIER -> BEDROCK_NETHER_ID;
|
||||
case BedrockDimension.NETHER_IDENTIFIER -> BedrockDimension.BEDROCK_NETHER_ID;
|
||||
case "minecraft:the_end" -> BedrockDimension.END_ID;
|
||||
default -> BedrockDimension.OVERWORLD_ID;
|
||||
};
|
||||
@ -215,17 +202,6 @@ public class DimensionUtils {
|
||||
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.
|
||||
*
|
||||
* @param isAboveNetherBedrockBuilding true if we should apply The End workaround
|
||||
*/
|
||||
public static void changeBedrockNetherId(boolean isAboveNetherBedrockBuilding) {
|
||||
// Change dimension ID to the End to allow for building above Bedrock
|
||||
BEDROCK_NETHER_ID = isAboveNetherBedrockBuilding ? BedrockDimension.END_ID : BedrockDimension.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.
|
||||
@ -235,7 +211,7 @@ public class DimensionUtils {
|
||||
* @return the Bedrock fake dimension to transfer to
|
||||
*/
|
||||
public static int getTemporaryDimension(int currentBedrockDimension, int newBedrockDimension) {
|
||||
if (isCustomBedrockNetherId()) {
|
||||
if (BedrockDimension.isCustomBedrockNetherId()) {
|
||||
// Prevents rare instances of Bedrock locking up
|
||||
return newBedrockDimension == BedrockDimension.END_ID ? BedrockDimension.OVERWORLD_ID : BedrockDimension.END_ID;
|
||||
}
|
||||
@ -244,7 +220,4 @@ public class DimensionUtils {
|
||||
return currentBedrockDimension == BedrockDimension.OVERWORLD_ID ? BedrockDimension.DEFAULT_NETHER_ID : BedrockDimension.OVERWORLD_ID;
|
||||
}
|
||||
|
||||
public static boolean isCustomBedrockNetherId() {
|
||||
return BEDROCK_NETHER_ID == BedrockDimension.END_ID;
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren