diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 53fecf79..f4835863 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -41,6 +41,8 @@ import com.nukkitx.math.vector.Vector2f; import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; +import com.nukkitx.nbt.NbtUtils; +import com.nukkitx.nbt.stream.NBTInputStream; import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.data.GamePublishSetting; @@ -53,6 +55,7 @@ import org.geysermc.api.RemoteServer; import org.geysermc.api.session.AuthData; import org.geysermc.api.window.FormWindow; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.console.GeyserLogger; import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.network.session.cache.*; @@ -60,6 +63,7 @@ import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.Toolbox; +import java.io.InputStream; import java.net.InetSocketAddress; import java.util.UUID; @@ -130,9 +134,9 @@ public class GeyserSession implements Player { ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); - BiomeDefinitionListPacket biomePacket = new BiomeDefinitionListPacket(); - biomePacket.setTag(CompoundTag.EMPTY); - upstream.sendPacket(biomePacket); + BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket(); + biomeDefinitionListPacket.setTag(Toolbox.BIOMES); + upstream.sendPacket(biomeDefinitionListPacket); AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket(); entityPacket.setTag(CompoundTag.EMPTY); diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java new file mode 100644 index 00000000..12278841 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/network/translators/BiomeTranslator.java @@ -0,0 +1,35 @@ +package org.geysermc.connector.network.translators; +import java.util.Arrays; + +//Based off of ProtocolSupport's LegacyBiomeData.java https://github.com/ProtocolSupport/ProtocolSupport/blob/b2cad35977f3fcb65bee57b9e14fc9c975f71d32/src/protocolsupport/protocol/typeremapper/legacy/LegacyBiomeData.java +//Array index formula by https://wiki.vg/Chunk_Format + +public class BiomeTranslator { + + public static byte[] toBedrockBiome(int[] biomeData) { + byte[] bedrockData = new byte[256]; + if(biomeData == null) { + return bedrockData; + } + + for (int z = 0; z < 16; z += 4) { + for (int x = 0; x < 16; x += 4) { + byte biomeId = biomeID(biomeData, x, z); + fillArray(z, x, bedrockData, biomeId); + fillArray(z + 1, x, bedrockData, biomeId); + fillArray(z + 2, x, bedrockData, biomeId); + fillArray(z + 3, x, bedrockData, biomeId); + } + } + return bedrockData; + } + + protected static void fillArray(int z, int x, byte[] legacyBiomeData, int biomeId) { + int offset = (z << 4) | x; + Arrays.fill(legacyBiomeData, offset, offset + 4, (byte) biomeId); + } + + protected static byte biomeID(int[] biomeData, int x, int z) { + return (byte) biomeData[((z >> 2) & 3) << 2 | ((x >> 2) & 3)]; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index 1a9230e6..d7499599 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -35,6 +35,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.geysermc.api.Geyser; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.translators.BiomeTranslator; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.world.chunk.ChunkSection; @@ -74,7 +75,9 @@ public class JavaChunkDataTranslator extends PacketTranslator ITEMS = new ArrayList<>(); public static ListTag BLOCKS; + public static CompoundTag BIOMES; public static final Int2ObjectMap ITEM_ENTRIES = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap BLOCK_ENTRIES = new Int2ObjectOpenHashMap<>(); public static void init() { + InputStream biomestream = GeyserConnector.class.getClassLoader().getResourceAsStream("bedrock/biome_definitions.dat"); + if (biomestream == null) { + throw new AssertionError("Unable to find bedrock/biome_definitions.dat"); + } + + CompoundTag biomesTag; + + try (NBTInputStream biomenbtInputStream = NbtUtils.createNetworkReader(biomestream)){ + biomesTag = (CompoundTag) biomenbtInputStream.readTag(); + BIOMES = biomesTag; + } catch (Exception ex) { + GeyserLogger.DEFAULT.warning("Failed to get biomes from biome definitions, is there something wrong with the file?"); + throw new AssertionError(ex); + } + InputStream stream = GeyserConnector.class.getClassLoader().getResourceAsStream("bedrock/runtime_block_states.dat"); if (stream == null) { throw new AssertionError("Unable to find bedrock/runtime_block_states.dat"); @@ -69,6 +86,7 @@ public class Toolbox { } BLOCKS = blocksTag; + InputStream stream2 = Toolbox.class.getClassLoader().getResourceAsStream("bedrock/items.json"); if (stream2 == null) { throw new AssertionError("Items Table not found"); diff --git a/connector/src/main/resources/bedrock/biome_definitions.dat b/connector/src/main/resources/bedrock/biome_definitions.dat index 015a2650..b8c6df4a 100644 Binary files a/connector/src/main/resources/bedrock/biome_definitions.dat and b/connector/src/main/resources/bedrock/biome_definitions.dat differ