diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java index e6e265475..bba7a593b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java @@ -5,6 +5,7 @@ import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; public class ChunkSectionType1_13 extends Type { + private static final int GLOBAL_PALETTE = 14; public ChunkSectionType1_13() { super("Chunk Section Type", ChunkSection.class); @@ -16,18 +17,15 @@ public class ChunkSectionType1_13 extends Type { // Reaad bits per block int bitsPerBlock = buffer.readUnsignedByte(); + int originalBitsPerBlock = bitsPerBlock; + + if (bitsPerBlock == 0 || bitsPerBlock > 8) { + bitsPerBlock = GLOBAL_PALETTE; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; - if (bitsPerBlock == 0) { - bitsPerBlock = 14; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 14; - } - int paletteLength = bitsPerBlock == 14 ? 0 : Type.VAR_INT.read(buffer); + int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.read(buffer); // Read palette chunkSection.clearPalette(); for (int i = 0; i < paletteLength; i++) { @@ -37,6 +35,11 @@ public class ChunkSectionType1_13 extends Type { // Read blocks long[] blockData = new long[Type.VAR_INT.read(buffer)]; if (blockData.length > 0) { + int expectedLength = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + if (blockData.length != expectedLength) { + throw new IllegalStateException("Block data length (" + blockData.length + ") does not match expected length (" + expectedLength + ")! bitsPerBlock=" + bitsPerBlock + ", originalBitsPerBlock=" + originalBitsPerBlock); + } + for (int i = 0; i < blockData.length; i++) { blockData[i] = buffer.readLong(); } @@ -53,7 +56,7 @@ public class ChunkSectionType1_13 extends Type { val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); } - if (bitsPerBlock == 14) { + if (bitsPerBlock == GLOBAL_PALETTE) { chunkSection.setFlatBlock(i, val); } else { chunkSection.setPaletteIndex(i, val); @@ -72,15 +75,14 @@ public class ChunkSectionType1_13 extends Type { } if (bitsPerBlock > 8) { - bitsPerBlock = 14; + bitsPerBlock = GLOBAL_PALETTE; } long maxEntryValue = (1L << bitsPerBlock) - 1; buffer.writeByte(bitsPerBlock); - // Write pallet (or not) - if (bitsPerBlock != 14) { + if (bitsPerBlock != GLOBAL_PALETTE) { Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); for (int i = 0; i < chunkSection.getPaletteSize(); i++) { Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); @@ -91,7 +93,7 @@ public class ChunkSectionType1_13 extends Type { Type.VAR_INT.write(buffer, length); long[] data = new long[length]; for (int index = 0; index < ChunkSection.SIZE; index++) { - int value = bitsPerBlock == 14 ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); + int value = bitsPerBlock == GLOBAL_PALETTE ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); int bitIndex = index * bitsPerBlock; int startIndex = bitIndex / 64; int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java index 8a596e24a..8d11a517b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java @@ -1,11 +1,11 @@ package us.myles.ViaVersion.api.type.types.version; -import com.google.common.collect.BiMap; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; public class ChunkSectionType1_9 extends Type { + private static final int GLOBAL_PALETTE = 13; public ChunkSectionType1_9() { super("Chunk Section Type", ChunkSection.class); @@ -17,22 +17,23 @@ public class ChunkSectionType1_9 extends Type { // Reaad bits per block int bitsPerBlock = buffer.readUnsignedByte(); + int originalBitsPerBlock = bitsPerBlock; long maxEntryValue = (1L << bitsPerBlock) - 1; if (bitsPerBlock == 0) { - bitsPerBlock = 13; + bitsPerBlock = GLOBAL_PALETTE; } if (bitsPerBlock < 4) { bitsPerBlock = 4; } if (bitsPerBlock > 8) { - bitsPerBlock = 13; + bitsPerBlock = GLOBAL_PALETTE; } int paletteLength = Type.VAR_INT.read(buffer); // Read palette chunkSection.clearPalette(); for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { + if (bitsPerBlock != GLOBAL_PALETTE) { chunkSection.addPaletteEntry(Type.VAR_INT.read(buffer)); } else { Type.VAR_INT.read(buffer); @@ -42,6 +43,11 @@ public class ChunkSectionType1_9 extends Type { // Read blocks long[] blockData = new long[Type.VAR_INT.read(buffer)]; if (blockData.length > 0) { + int expectedLength = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + if (blockData.length != expectedLength) { + throw new IllegalStateException("Block data length (" + blockData.length + ") does not match expected length (" + expectedLength + ")! bitsPerBlock=" + bitsPerBlock + ", originalBitsPerBlock=" + originalBitsPerBlock); + } + for (int i = 0; i < blockData.length; i++) { blockData[i] = buffer.readLong(); } @@ -58,7 +64,7 @@ public class ChunkSectionType1_9 extends Type { val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); } - if (bitsPerBlock == 13) { + if (bitsPerBlock == GLOBAL_PALETTE) { chunkSection.setBlock(i, val >> 4, val & 0xF); } else { chunkSection.setPaletteIndex(i, val); @@ -75,20 +81,29 @@ public class ChunkSectionType1_9 extends Type { while (chunkSection.getPaletteSize() > 1 << bitsPerBlock) { bitsPerBlock += 1; } + + if (bitsPerBlock > 8) { + bitsPerBlock = GLOBAL_PALETTE; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; buffer.writeByte(bitsPerBlock); - // Write pallet - Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); - for (int i = 0; i < chunkSection.getPaletteSize(); i++) { - Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); + // Write pallet (or not) + if (bitsPerBlock != GLOBAL_PALETTE) { + Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); + for (int i = 0; i < chunkSection.getPaletteSize(); i++) { + Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); + } + } else { + Type.VAR_INT.write(buffer, 0); } int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); Type.VAR_INT.write(buffer, length); long[] data = new long[length]; for (int index = 0; index < ChunkSection.SIZE; index++) { - int value = chunkSection.getPaletteIndex(index); + int value = bitsPerBlock == GLOBAL_PALETTE ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); int bitIndex = index * bitsPerBlock; int startIndex = bitIndex / 64; int endIndex = ((index + 1) * bitsPerBlock - 1) / 64;