Merge pull request #155 from OnlyBMan/biomes

Add biomes
This commit is contained in:
Redned 2020-02-09 14:45:18 -06:00 committed by GitHub
commit b2d3ae5d64
6 changed files with 64 additions and 5 deletions

View file

@ -41,6 +41,8 @@ import com.nukkitx.math.vector.Vector2f;
import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector2i;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i; 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.nbt.tag.CompoundTag;
import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.data.GamePublishSetting; 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.session.AuthData;
import org.geysermc.api.window.FormWindow; import org.geysermc.api.window.FormWindow;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.console.GeyserLogger;
import org.geysermc.connector.entity.PlayerEntity; import org.geysermc.connector.entity.PlayerEntity;
import org.geysermc.connector.inventory.PlayerInventory; import org.geysermc.connector.inventory.PlayerInventory;
import org.geysermc.connector.network.session.cache.*; 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.ChunkUtils;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.Toolbox;
import java.io.InputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.UUID; import java.util.UUID;
@ -130,9 +134,9 @@ public class GeyserSession implements Player {
ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false); ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
BiomeDefinitionListPacket biomePacket = new BiomeDefinitionListPacket(); BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
biomePacket.setTag(CompoundTag.EMPTY); biomeDefinitionListPacket.setTag(Toolbox.BIOMES);
upstream.sendPacket(biomePacket); upstream.sendPacket(biomeDefinitionListPacket);
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket(); AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
entityPacket.setTag(CompoundTag.EMPTY); entityPacket.setTag(CompoundTag.EMPTY);

View file

@ -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)];
}
}

View file

@ -35,6 +35,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import org.geysermc.api.Geyser; import org.geysermc.api.Geyser;
import org.geysermc.connector.network.session.GeyserSession; 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.network.translators.PacketTranslator;
import org.geysermc.connector.utils.ChunkUtils; import org.geysermc.connector.utils.ChunkUtils;
import org.geysermc.connector.world.chunk.ChunkSection; import org.geysermc.connector.world.chunk.ChunkSection;
@ -74,7 +75,9 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
section.writeToNetwork(byteBuf); section.writeToNetwork(byteBuf);
} }
byteBuf.writeBytes(chunkData.biomes); // Biomes - 256 bytes byte[] bedrockBiome = BiomeTranslator.toBedrockBiome(packet.getColumn().getBiomeData());
byteBuf.writeBytes(bedrockBiome); // Biomes - 256 bytes
byteBuf.writeByte(0); // Border blocks - Edu edition only byteBuf.writeByte(0); // Border blocks - Edu edition only
VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now

View file

@ -131,7 +131,6 @@ public class ChunkUtils {
public static final class ChunkData { public static final class ChunkData {
public ChunkSection[] sections; public ChunkSection[] sections;
public byte[] biomes = new byte[256];
public byte[] blockEntities = new byte[0]; public byte[] blockEntities = new byte[0];
} }
} }

View file

@ -31,6 +31,7 @@ import com.nukkitx.nbt.stream.NBTInputStream;
import com.nukkitx.nbt.tag.CompoundTag; import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.nbt.tag.ListTag; import com.nukkitx.nbt.tag.ListTag;
import com.nukkitx.nbt.tag.Tag; import com.nukkitx.nbt.tag.Tag;
import com.nukkitx.protocol.bedrock.packet.BiomeDefinitionListPacket;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@ -47,11 +48,27 @@ public class Toolbox {
public static final Collection<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>(); public static final Collection<StartGamePacket.ItemEntry> ITEMS = new ArrayList<>();
public static ListTag<CompoundTag> BLOCKS; public static ListTag<CompoundTag> BLOCKS;
public static CompoundTag BIOMES;
public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>();
public static final Int2ObjectMap<BlockEntry> BLOCK_ENTRIES = new Int2ObjectOpenHashMap<>(); public static final Int2ObjectMap<BlockEntry> BLOCK_ENTRIES = new Int2ObjectOpenHashMap<>();
public static void init() { 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"); InputStream stream = GeyserConnector.class.getClassLoader().getResourceAsStream("bedrock/runtime_block_states.dat");
if (stream == null) { if (stream == null) {
throw new AssertionError("Unable to find bedrock/runtime_block_states.dat"); throw new AssertionError("Unable to find bedrock/runtime_block_states.dat");
@ -69,6 +86,7 @@ public class Toolbox {
} }
BLOCKS = blocksTag; BLOCKS = blocksTag;
InputStream stream2 = Toolbox.class.getClassLoader().getResourceAsStream("bedrock/items.json"); InputStream stream2 = Toolbox.class.getClassLoader().getResourceAsStream("bedrock/items.json");
if (stream2 == null) { if (stream2 == null) {
throw new AssertionError("Items Table not found"); throw new AssertionError("Items Table not found");