diff --git a/common/src/main/java/com/viaversion/viarewind/api/minecraft/ExtendedBlockStorage.java b/common/src/main/java/com/viaversion/viarewind/api/minecraft/ExtendedBlockStorage.java index 06c029b6c..e489e1dcc 100644 --- a/common/src/main/java/com/viaversion/viarewind/api/minecraft/ExtendedBlockStorage.java +++ b/common/src/main/java/com/viaversion/viarewind/api/minecraft/ExtendedBlockStorage.java @@ -21,7 +21,7 @@ import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray; public class ExtendedBlockStorage { - private final byte[] blockLSBArray = new byte[4096]; + private final byte[] blockLSBArray = new byte[ChunkSection.SIZE]; private final NibbleArray blockMetadataArray = new NibbleArray(this.blockLSBArray.length); private final NibbleArray blockLightArray = new NibbleArray(this.blockLSBArray.length); diff --git a/common/src/main/java/com/viaversion/viarewind/api/type/chunk/BulkChunkType1_7_6.java b/common/src/main/java/com/viaversion/viarewind/api/type/chunk/BulkChunkType1_7_6.java index 20d3bd819..0ce5e7509 100644 --- a/common/src/main/java/com/viaversion/viarewind/api/type/chunk/BulkChunkType1_7_6.java +++ b/common/src/main/java/com/viaversion/viarewind/api/type/chunk/BulkChunkType1_7_6.java @@ -23,7 +23,6 @@ import com.viaversion.viaversion.util.Pair; import io.netty.buffer.ByteBuf; -import java.io.ByteArrayOutputStream; import java.util.zip.Deflater; public class BulkChunkType1_7_6 extends Type { @@ -42,18 +41,22 @@ public Chunk[] read(ByteBuf byteBuf) { @Override public void write(ByteBuf byteBuf, Chunk[] chunks) { final int chunkCount = chunks.length; - final ByteArrayOutputStream output = new ByteArrayOutputStream(); final int[] chunkX = new int[chunkCount]; final int[] chunkZ = new int[chunkCount]; final short[] primaryBitMask = new short[chunkCount]; final short[] additionalBitMask = new short[chunkCount]; + final byte[][] dataArrays = new byte[chunkCount][]; + int dataSize = 0; + for (int i = 0; i < chunkCount; i++) { final Chunk chunk = chunks[i]; Pair chunkData; try { chunkData = ChunkType1_7_6.serialize(chunk); - output.write(chunkData.key()); + final byte[] data = chunkData.key(); + dataArrays[i] = data; + dataSize += data.length; } catch (Exception e) { throw new RuntimeException("Unable to serialize chunk", e); } @@ -62,7 +65,13 @@ public void write(ByteBuf byteBuf, Chunk[] chunks) { primaryBitMask[i] = (short) chunk.getBitmask(); additionalBitMask[i] = chunkData.value(); } - final byte[] data = output.toByteArray(); + + final byte[] data = new byte[dataSize]; + int destPos = 0; + for (final byte[] array : dataArrays) { + System.arraycopy(array, 0, data, destPos, array.length); + destPos += array.length; + } final Deflater deflater = new Deflater(); byte[] compressedData; diff --git a/common/src/main/java/com/viaversion/viarewind/api/type/chunk/ChunkType1_7_6.java b/common/src/main/java/com/viaversion/viarewind/api/type/chunk/ChunkType1_7_6.java index 97f3bfca1..fda6a1f97 100644 --- a/common/src/main/java/com/viaversion/viarewind/api/type/chunk/ChunkType1_7_6.java +++ b/common/src/main/java/com/viaversion/viarewind/api/type/chunk/ChunkType1_7_6.java @@ -23,10 +23,12 @@ import com.viaversion.viaversion.util.Pair; import io.netty.buffer.ByteBuf; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.Deflater; +import static com.viaversion.viaversion.api.minecraft.chunks.ChunkSection.SIZE; +import static com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionLight.LIGHT_LENGTH; + public class ChunkType1_7_6 extends Type { public static final ChunkType1_7_6 TYPE = new ChunkType1_7_6(); @@ -94,29 +96,41 @@ public static Pair serialize(final Chunk chunk) throws IOExceptio } } - final ByteArrayOutputStream output = new ByteArrayOutputStream(); + final boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null; + final int totalSize = calculateSize(storageArrays, chunk.getBitmask(), biomes); + + final byte[] output = new byte[totalSize]; + int index = 0; for (int i = 0; i < storageArrays.length; i++) { if ((chunk.getBitmask() & 1 << i) != 0) { - output.write(storageArrays[i].getBlockLSBArray()); + final byte[] blockLSBArray = storageArrays[i].getBlockLSBArray(); + System.arraycopy(blockLSBArray, 0, output, index, blockLSBArray.length); + index += blockLSBArray.length; } } for (int i = 0; i < storageArrays.length; i++) { if ((chunk.getBitmask() & 1 << i) != 0) { - output.write(storageArrays[i].getBlockMetadataArray().getHandle()); + final byte[] blockMetadataArray = storageArrays[i].getBlockMetadataArray().getHandle(); + System.arraycopy(blockMetadataArray, 0, output, index, blockMetadataArray.length); + index += blockMetadataArray.length; } } for (int i = 0; i < storageArrays.length; i++) { if ((chunk.getBitmask() & 1 << i) != 0) { - output.write(storageArrays[i].getBlockLightArray().getHandle()); + final byte[] blockLightArray = storageArrays[i].getBlockLightArray().getHandle(); + System.arraycopy(blockLightArray, 0, output, index, blockLightArray.length); + index += blockLightArray.length; } } for (int i = 0; i < storageArrays.length; i++) { if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].getSkyLightArray() != null) { - output.write(storageArrays[i].getSkyLightArray().getHandle()); + final byte[] skyLightArray = storageArrays[i].getSkyLightArray().getHandle(); + System.arraycopy(skyLightArray, 0, output, index, skyLightArray.length); + index += skyLightArray.length; } } @@ -124,16 +138,42 @@ public static Pair serialize(final Chunk chunk) throws IOExceptio for (int i = 0; i < storageArrays.length; i++) { if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].hasBlockMSBArray()) { additionalBitMask |= (short) (1 << i); - output.write(storageArrays[i].getOrCreateBlockMSBArray().getHandle()); + final byte[] blockMSBArray = storageArrays[i].getOrCreateBlockMSBArray().getHandle(); + System.arraycopy(blockMSBArray, 0, output, index, blockMSBArray.length); + index += blockMSBArray.length; } } - if (chunk.isFullChunk() && chunk.getBiomeData() != null) { + if (biomes) { for (int biome : chunk.getBiomeData()) { - output.write(biome); + output[index++] = (byte) biome; } } - return new Pair<>(output.toByteArray(), additionalBitMask); + return new Pair<>(output, additionalBitMask); } + + private static int calculateSize(final ExtendedBlockStorage[] storageArrays, final int bitmask, final boolean biomes) { + int totalSize = 0; + for (int i = 0; i < storageArrays.length; i++) { + if ((bitmask & 1 << i) != 0) { + totalSize += SIZE; // Block lsb array + totalSize += SIZE / 2; // Block metadata array + totalSize += LIGHT_LENGTH; // Block light array + + if (storageArrays[i].getSkyLightArray() != null) { + totalSize += LIGHT_LENGTH; + } + + if (storageArrays[i].hasBlockMSBArray()) { + totalSize += SIZE / 2; // Block msb array + } + } + } + if (biomes) { + totalSize += 256; + } + return totalSize; + } + } diff --git a/gradle.properties b/gradle.properties index 38999c086..b3e534f11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.parallel=true # project maven_group=com.viaversion -maven_version=4.0.7 +maven_version=4.0.8-SNAPSHOT maven_description=ViaBackwards addon to allow 1.8.x and 1.7.x clients on newer server versions. # Smile emoji