mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Warn if server is using high/low dimension heights and remove translations on some strings
This commit is contained in:
parent
6b681213ed
commit
bb20afb123
10 changed files with 63 additions and 17 deletions
|
@ -89,7 +89,7 @@ public class ChunkCache {
|
|||
return;
|
||||
}
|
||||
|
||||
Chunk chunk = column.getChunks()[y >> 4];
|
||||
Chunk chunk = column.getChunks()[(y >> 4) - getChunkMinY()];
|
||||
if (chunk != null) {
|
||||
chunk.set(x & 0xF, y & 0xF, z & 0xF, block);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class ChunkCache {
|
|||
return BlockTranslator.JAVA_AIR_ID;
|
||||
}
|
||||
|
||||
Chunk chunk = column.getChunks()[y >> 4];
|
||||
Chunk chunk = column.getChunks()[(y >> 4) - getChunkMinY()];
|
||||
if (chunk != null) {
|
||||
return chunk.get(x & 0xF, y & 0xF, z & 0xF);
|
||||
}
|
||||
|
@ -126,4 +126,8 @@ public class ChunkCache {
|
|||
long chunkPosition = MathUtils.chunkPositionToLong(chunkX, chunkZ);
|
||||
chunks.remove(chunkPosition);
|
||||
}
|
||||
|
||||
public int getChunkMinY() {
|
||||
return minY >> 4;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import com.nukkitx.nbt.NbtMap;
|
|||
import com.nukkitx.nbt.NbtUtils;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
@ -59,7 +58,7 @@ public class BiomeTranslator {
|
|||
biomesTag = (NbtMap) biomenbtInputStream.readTag();
|
||||
BIOMES = biomesTag;
|
||||
} catch (Exception ex) {
|
||||
GeyserConnector.getInstance().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.biome_read"));
|
||||
GeyserConnector.getInstance().getLogger().warning("Failed to get biomes from biome definitions, is there something wrong with the file?");
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import com.nukkitx.nbt.NBTInputStream;
|
|||
import com.nukkitx.nbt.NbtMap;
|
||||
import com.nukkitx.nbt.NbtUtils;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
|
@ -54,7 +53,7 @@ public class EntityIdentifierRegistry {
|
|||
try (NBTInputStream nbtInputStream = NbtUtils.createNetworkReader(stream)) {
|
||||
ENTITY_IDENTIFIERS = (NbtMap) nbtInputStream.readTag();
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.entity"), e);
|
||||
throw new AssertionError("Unable to get entities from entity identifiers", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@ public class ItemRegistry {
|
|||
try {
|
||||
itemEntries = GeyserConnector.JSON_MAPPER.readValue(stream, itemEntriesType);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_bedrock"), e);
|
||||
throw new AssertionError("Unable to load Bedrock runtime item IDs", e);
|
||||
}
|
||||
|
||||
int lodestoneCompassId = 0;
|
||||
|
@ -172,7 +172,7 @@ public class ItemRegistry {
|
|||
try {
|
||||
creativeItemEntries = GeyserConnector.JSON_MAPPER.readTree(stream).get("items");
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
|
||||
throw new AssertionError("Unable to load creative items", e);
|
||||
}
|
||||
|
||||
int netId = 1;
|
||||
|
@ -247,7 +247,7 @@ public class ItemRegistry {
|
|||
try {
|
||||
items = GeyserConnector.JSON_MAPPER.readTree(stream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e);
|
||||
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
||||
}
|
||||
|
||||
BlockTranslator blockTranslator = BlockTranslator1_17_0.INSTANCE;
|
||||
|
|
|
@ -41,7 +41,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.utils.FileUtils;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -144,7 +143,7 @@ public class RecipeRegistry {
|
|||
try {
|
||||
items = GeyserConnector.JSON_MAPPER.readTree(stream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.runtime_java"), e);
|
||||
throw new AssertionError("Unable to load Java runtime item IDs", e);
|
||||
}
|
||||
|
||||
for (JsonNode entry : items.get("leather_armor")) {
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.geysermc.connector.entity.player.PlayerEntity;
|
|||
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.utils.ChunkUtils;
|
||||
import org.geysermc.connector.utils.DimensionUtils;
|
||||
import org.geysermc.connector.utils.PluginMessageUtils;
|
||||
|
||||
|
@ -53,6 +54,9 @@ public class JavaJoinGameTranslator extends PacketTranslator<ServerJoinGamePacke
|
|||
public void translate(ServerJoinGamePacket packet, GeyserSession session) {
|
||||
PlayerEntity entity = session.getPlayerEntity();
|
||||
entity.setEntityId(packet.getEntityId());
|
||||
|
||||
ChunkUtils.applyDimensionHeight(session, packet.getDimension());
|
||||
|
||||
// If the player is already initialized and a join game packet is sent, they
|
||||
// are swapping servers
|
||||
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
||||
|
|
|
@ -36,6 +36,7 @@ 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.inventory.InventoryTranslator;
|
||||
import org.geysermc.connector.utils.ChunkUtils;
|
||||
import org.geysermc.connector.utils.DimensionUtils;
|
||||
|
||||
@Translator(packet = ServerRespawnPacket.class)
|
||||
|
@ -78,6 +79,8 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
|
|||
session.setThunder(false);
|
||||
}
|
||||
|
||||
ChunkUtils.applyDimensionHeight(session, packet.getDimension());
|
||||
|
||||
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
||||
if (!session.getDimension().equals(newDimension) || !packet.getWorldName().equals(session.getWorldName())) {
|
||||
if (!packet.getWorldName().equals(session.getWorldName()) && session.getDimension().equals(newDimension)) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import com.github.steveice10.mc.protocol.data.game.chunk.palette.GlobalPalette;
|
|||
import com.github.steveice10.mc.protocol.data.game.chunk.palette.Palette;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import com.nukkitx.math.vector.Vector2i;
|
||||
|
@ -67,6 +68,14 @@ import static org.geysermc.connector.network.translators.world.block.BlockTransl
|
|||
|
||||
@UtilityClass
|
||||
public class ChunkUtils {
|
||||
/**
|
||||
* The minimum height Bedrock Edition will accept.
|
||||
*/
|
||||
private static final int MINIMUM_ACCEPTED_HEIGHT = 0;
|
||||
/**
|
||||
* The maximum height Bedrock Edition will accept.
|
||||
*/
|
||||
private static final int MAXIMUM_ACCEPTED_HEIGHT = 256;
|
||||
|
||||
private static int indexYZXtoXZY(int yzx) {
|
||||
return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8);
|
||||
|
@ -74,7 +83,9 @@ public class ChunkUtils {
|
|||
|
||||
public static ChunkData translateToBedrock(GeyserSession session, Column column) {
|
||||
Chunk[] javaSections = column.getChunks();
|
||||
ChunkSection[] sections = new ChunkSection[javaSections.length];
|
||||
// Ensure that, if the player is using lower world heights, the position is not offset
|
||||
int yOffset = session.getChunkCache().getChunkMinY();
|
||||
ChunkSection[] sections = new ChunkSection[javaSections.length - yOffset];
|
||||
|
||||
// Temporarily stores compound tags of Bedrock-only block entities
|
||||
List<NbtMap> bedrockOnlyBlockEntities = new ArrayList<>();
|
||||
|
@ -83,6 +94,11 @@ public class ChunkUtils {
|
|||
BitSet pistonOrFlowerPaletteIds = new BitSet();
|
||||
|
||||
for (int sectionY = 0; sectionY < javaSections.length; sectionY++) {
|
||||
if (yOffset < 0 && sectionY < -yOffset) {
|
||||
// Ignore this chunk since it goes below the accepted height limit
|
||||
continue;
|
||||
}
|
||||
|
||||
Chunk javaSection = javaSections[sectionY];
|
||||
|
||||
// No need to encode an empty section...
|
||||
|
@ -114,7 +130,7 @@ public class ChunkUtils {
|
|||
));
|
||||
}
|
||||
}
|
||||
sections[sectionY] = section;
|
||||
sections[sectionY + yOffset] = section;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -187,7 +203,7 @@ public class ChunkUtils {
|
|||
layers = new BlockStorage[]{ layer0, new BlockStorage(BitArrayVersion.V1.createArray(BlockStorage.SIZE, layer1Data), layer1Palette) };
|
||||
}
|
||||
|
||||
sections[sectionY] = new ChunkSection(layers);
|
||||
sections[sectionY + yOffset] = new ChunkSection(layers);
|
||||
}
|
||||
|
||||
CompoundTag[] blockEntities = column.getTileEntities();
|
||||
|
@ -220,7 +236,7 @@ public class ChunkUtils {
|
|||
|
||||
// Get Java blockstate ID from block entity position
|
||||
int blockState = 0;
|
||||
Chunk section = column.getChunks()[pos.getY() >> 4];
|
||||
Chunk section = column.getChunks()[(pos.getY() >> 4) - yOffset];
|
||||
if (section != null) {
|
||||
blockState = section.get(pos.getX() & 0xF, pos.getY() & 0xF, pos.getZ() & 0xF);
|
||||
}
|
||||
|
@ -385,6 +401,28 @@ public class ChunkUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the minimum and maximum heights for this dimension
|
||||
*/
|
||||
public static void applyDimensionHeight(GeyserSession session, CompoundTag dimensionTag) {
|
||||
int minY = ((IntTag) dimensionTag.get("min_y")).getValue();
|
||||
int maxY = ((IntTag) dimensionTag.get("height")).getValue();
|
||||
// Logical height can be ignored probably - seems to be for artificial limits like the Nether.
|
||||
|
||||
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 (minY < MINIMUM_ACCEPTED_HEIGHT || maxY > MAXIMUM_ACCEPTED_HEIGHT) {
|
||||
session.getConnector().getLogger().warning(LanguageUtils.getLocaleStringLog("geyser.network.translator.chunk.out_of_bounds"));
|
||||
}
|
||||
|
||||
session.getChunkCache().setMinY(minY);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static final class ChunkData {
|
||||
private final ChunkSection[] sections;
|
||||
|
|
|
@ -152,7 +152,7 @@ public class FileUtils {
|
|||
public static InputStream getResource(String resource) {
|
||||
InputStream stream = FileUtils.class.getClassLoader().getResourceAsStream(resource);
|
||||
if (stream == null) {
|
||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.resource", resource));
|
||||
throw new AssertionError("Unable to find resource: " + resource);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b66aef5db3633468f1e6ece408ecd7a3d4a4faeb
|
||||
Subproject commit fcc8f01e25e481c9c82f2ee9bff23111ec781dd7
|
Loading…
Reference in a new issue