diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java index 60b7eadd9..a8c7c93e6 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/packets/WorldPackets.java @@ -11,6 +11,7 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type; import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2; +import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; import java.util.Arrays; @@ -26,7 +27,8 @@ public class WorldPackets { @Override public void handle(PacketWrapper wrapper) throws Exception { ClientWorld clientWorld = wrapper.user().get(ClientWorld.class); - Chunk chunk = wrapper.passthrough(new Chunk1_13Type(clientWorld)); + Chunk chunk = wrapper.read(new Chunk1_13Type(clientWorld)); + wrapper.write(new Chunk1_14Type(clientWorld), chunk); for (ChunkSection section : chunk.getSections()) { if (section != null) { @@ -37,7 +39,7 @@ public class WorldPackets { } if (chunk.isBiomeData()) { - Arrays.fill(chunk.getBiomeData(), (byte) 1); + Arrays.fill(chunk.getBiomeData(), (byte) 0); //TODO map biome ids } } }); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/types/Chunk1_14Type.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/types/Chunk1_14Type.java new file mode 100644 index 000000000..0c6ce1739 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/types/Chunk1_14Type.java @@ -0,0 +1,108 @@ +package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.types; + +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import io.netty.buffer.ByteBuf; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.minecraft.chunks.Chunk; +import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; +import us.myles.ViaVersion.api.type.PartialType; +import us.myles.ViaVersion.api.type.Type; +import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks.Chunk1_13; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks.ChunkSection1_13; +import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.List; + +public class Chunk1_14Type extends PartialType { + + public Chunk1_14Type(ClientWorld param) { + super(param, Chunk.class); + } + + @Override + public Chunk read(ByteBuf input, ClientWorld world) throws Exception { + int chunkX = input.readInt(); + int chunkZ = input.readInt(); + + boolean groundUp = input.readBoolean(); + int primaryBitmask = Type.VAR_INT.read(input); + Type.VAR_INT.read(input); + + BitSet usedSections = new BitSet(16); + ChunkSection1_13[] sections = new ChunkSection1_13[16]; + // Calculate section count from bitmask + for (int i = 0; i < 16; i++) { + if ((primaryBitmask & (1 << i)) != 0) { + usedSections.set(i); + } + } + + // Read sections + for (int i = 0; i < 16; i++) { + if (!usedSections.get(i)) continue; // Section not set + ChunkSection1_13 section = new ChunkSection1_13(); + sections[i] = section; + input.readShort(); //TODO unknown short + section.readBlocks(input); + } + + byte[] biomeData = groundUp ? new byte[256] : null; + if (groundUp) { + for (int i = 0; i < 256; i++) { + biomeData[i] = (byte) input.readInt(); + } + } + + List nbtData = new ArrayList<>(Arrays.asList(Type.NBT_ARRAY.read(input))); + + // Read all the remaining bytes (workaround for #681) + if (input.readableBytes() > 0) { + byte[] array = Type.REMAINING_BYTES.read(input); + if (Via.getManager().isDebug()) { + Via.getPlatform().getLogger().warning("Found " + array.length + " more bytes than expected while reading the chunk: " + chunkX + "/" + chunkZ); + } + } + + return new Chunk1_13(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData); + } + + @Override + public void write(ByteBuf output, ClientWorld world, Chunk chunk) throws Exception { + output.writeInt(chunk.getX()); + output.writeInt(chunk.getZ()); + + output.writeBoolean(chunk.isGroundUp()); + Type.VAR_INT.write(output, chunk.getBitmask()); + + ByteBuf buf = output.alloc().buffer(); + for (int i = 0; i < 16; i++) { + ChunkSection section = chunk.getSections()[i]; + if (section == null) continue; // Section not set + buf.writeShort(0); //TODO find out what this short does (number of air blocks, important?) + section.writeBlocks1_13(buf); + } + buf.readerIndex(0); + Type.VAR_INT.write(output, buf.readableBytes() + (chunk.isBiomeData() ? 256 * 4 : 0)); + output.writeBytes(buf); + buf.release(); // release buffer + + // Write biome data + if (chunk.isBiomeData()) { + for (byte value : chunk.getBiomeData()) { + output.writeInt(value & 0xFF); // This is a temporary workaround, we'll look into fixing this soon :) + } + } + + // Write Block Entities + Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0])); + } + + @Override + public Class getBaseClass() { + return BaseChunkType.class; + } +}