diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java index 1eea32c11..7e15d1f07 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/ChunkSection.java @@ -2,6 +2,8 @@ package us.myles.ViaVersion.api.minecraft.chunks; import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; +import lombok.Getter; +import lombok.Setter; import java.util.List; @@ -14,10 +16,14 @@ public class ChunkSection { * Length of the sky and block light nibble arrays. */ public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - private final List palette = Lists.newArrayList(); + @Getter + private final List palette = Lists.newArrayList(); private final int[] blocks; private NibbleArray blockLight; private NibbleArray skyLight; + @Getter + @Setter + private int nonAirBlocksCount; public ChunkSection() { this.blocks = new int[SIZE]; @@ -162,10 +168,6 @@ public class ChunkSection { output.writeBytes(skyLight.getHandle()); } - public List getPalette() { - return palette; - } - /** * Check if sky light is present * @@ -178,12 +180,4 @@ public class ChunkSection { public boolean hasBlockLight() { return blockLight != null; } - - public int getNonAirBlocksCount() { - return this.nonAirBlocksCount; - } - - public void setNonAirBlocksCount(int nonAirBlocksCount) { - this.nonAirBlocksCount = nonAirBlocksCount; - } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java deleted file mode 100644 index e85601093..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/chunks/ChunkSection1_13.java +++ /dev/null @@ -1,316 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import lombok.Getter; -import lombok.Setter; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_13 implements ChunkSection { - @Getter - @Setter - private int nonAirBlocksCount; - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_13() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it fails to read - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Read bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - boolean directPalette = false; - - if (bitsPerBlock == 0) { - bitsPerBlock = 14; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock >= 9) { - directPalette = true; - bitsPerBlock = 14; - } - - int paletteLength = directPalette ? 0 : Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - palette.add(Type.VAR_INT.read(input)); - } - - // Read blocks - // Long[] blockData = Type.LONG_ARRAY.read(input); - long[] blockData = new long[Type.VAR_INT.read(input)]; - for (int i = 0; i < blockData.length; i++) { - blockData[i] = input.readLong(); - } - - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex >> 6; // /64 - int endIndex = ((i + 1) * bitsPerBlock - 1) >> 6; // /64 - int startBitSubIndex = bitIndex & 0x3F; // % 64 - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (directPalette) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - @Override - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - @Override - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - @Override - public boolean hasSkyLight() { - return skyLight != null; - } - - @Override - public List getPalette() { - return palette; - } -} 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 32fd01af9..56dd17530 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 @@ -31,31 +31,32 @@ public class WorldPackets { wrapper.write(new Chunk1_14Type(clientWorld), chunk); for (ChunkSection section : chunk.getSections()) { - if (section != null) { - boolean hasBlock = false; - for (int i = 0; i < section.getPalette().size(); i++) { - int old = section.getPalette().get(i); - if (!hasBlock && !(old == 0 || old == 8591 || old == 8592)) { // air, void_air, cave_air - hasBlock = true; - } - int newId = Protocol1_14To1_13_2.getNewBlockStateId(old); - section.getPalette().set(i, newId); + if (section == null) continue; + boolean hasBlock = false; + for (int i = 0; i < section.getPalette().size(); i++) { + int old = section.getPalette().get(i); + if (!hasBlock && !(old == 0 || old == 8591 || old == 8592)) { // air, void_air, cave_air + hasBlock = true; } - if (hasBlock) { - int nonAirBlockCount = 0; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int id = section.getBlock(x, y, z); - if (id == 0 || id == 8591 || id == 8592) { - nonAirBlockCount++; - } - } + int newId = Protocol1_14To1_13_2.getNewBlockStateId(old); + section.getPalette().set(i, newId); + } + if (!hasBlock) { + section.setNonAirBlocksCount(0); + continue; + } + int nonAirBlockCount = 0; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + int id = section.getFlatBlock(x, y, z); + if (id == 0 || id == 8591 || id == 8592) { + nonAirBlockCount++; } } - section.setNonAirBlocksCount(nonAirBlockCount); } } + section.setNonAirBlocksCount(nonAirBlockCount); } PacketWrapper lightPacket = wrapper.create(0x57); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java deleted file mode 100644 index 8b69953dd..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_1_2to1_9_3_4/chunks/ChunkSection1_9_3_4.java +++ /dev/null @@ -1,373 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import lombok.Getter; -import lombok.Setter; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_9_3_4 implements ChunkSection { - @Getter - @Setter - private int nonAirBlocksCount; - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_9_3_4() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - /** - * Set a flat block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - */ - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it fails to read - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Read bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - if (bitsPerBlock == 0) { - bitsPerBlock = 13; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 13; - } - int paletteLength = Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { - palette.add(Type.VAR_INT.read(input)); - } else { - Type.VAR_INT.read(input); - } - } - - // Read blocks - //Long[] blockData = Type.LONG_ARRAY.read(input); - long[] blockData = new long[Type.VAR_INT.read(input)]; - for (int i = 0; i < blockData.length; i++) { - blockData[i] = input.readLong(); - } - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (bitsPerBlock == 13) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - if ((value & (~0 << 7)) == 0) - return 1; - if ((value & (~0 << 14)) == 0) - return 2; - if ((value & (~0 << 21)) == 0) - return 3; - if ((value & (~0 << 28)) == 0) - return 4; - return 5; - } - - @Override - public List getPalette() { - return palette; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java deleted file mode 100644 index dcf1251a7..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9_3to1_9_1_2/chunks/ChunkSection1_9_1_2.java +++ /dev/null @@ -1,365 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import lombok.Getter; -import lombok.Setter; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_9_1_2 implements ChunkSection { - @Getter - @Setter - private int nonAirBlocksCount; - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_9_1_2() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Read blocks from input stream. - * This reads all the block related data: - *
    - *
  • Block length/palette type
  • - *
  • Palette
  • - *
  • Block hashes/palette reference
  • - *
- * - * @param input The buffer to read from. - * @throws Exception If it failed to read properly - */ - public void readBlocks(ByteBuf input) throws Exception { - palette.clear(); - - // Reaad bits per block - int bitsPerBlock = input.readUnsignedByte(); - long maxEntryValue = (1L << bitsPerBlock) - 1; - - if (bitsPerBlock == 0) { - bitsPerBlock = 13; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 13; - } - int paletteLength = Type.VAR_INT.read(input); - // Read palette - for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { - palette.add(Type.VAR_INT.read(input)); - } else { - Type.VAR_INT.read(input); - } - } - - // Read blocks - // Long[] blockData = Type.LONG_ARRAY.read(input); - long[] blockData = new long[Type.VAR_INT.read(input)]; - for (int i = 0; i < blockData.length; i++) { - blockData[i] = input.readLong(); - } - if (blockData.length > 0) { - for (int i = 0; i < blocks.length; i++) { - int bitIndex = i * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((i + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - int val; - if (startIndex == endIndex) { - val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue); - } else { - int endBitSubIndex = 64 - startBitSubIndex; - val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); - } - - if (bitsPerBlock == 13) { - int type = val >> 4; - int data = val & 0xF; - - setBlock(i, type, data); - } else { - blocks[i] = val; - } - } - } - } - - /** - * Read block light from buffer. - * - * @param input The buffer to read from - */ - public void readBlockLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - blockLight.setHandle(handle); - } - - /** - * Read sky light from buffer. - * Note: Only sent in overworld! - * - * @param input The buffer to read from - */ - public void readSkyLight(ByteBuf input) { - byte[] handle = new byte[LIGHT_LENGTH]; - input.readBytes(handle); - if (skyLight != null) { - skyLight.setHandle(handle); - return; - } - - this.skyLight = new NibbleArray(handle); - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - @Override - public List getPalette() { - return palette; - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - if ((value & (~0 << 7)) == 0) - return 1; - if ((value & (~0 << 14)) == 0) - return 2; - if ((value & (~0 << 21)) == 0) - return 3; - if ((value & (~0 << 28)) == 0) - return 4; - return 5; - } -} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java deleted file mode 100644 index 374a3402c..000000000 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/chunks/ChunkSection1_9to1_8.java +++ /dev/null @@ -1,268 +0,0 @@ -package us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks; - -import com.google.common.collect.Lists; -import io.netty.buffer.ByteBuf; -import lombok.Getter; -import lombok.Setter; -import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; -import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; -import us.myles.ViaVersion.api.type.Type; - -import java.util.List; - -public class ChunkSection1_9to1_8 implements ChunkSection { - @Getter - @Setter - private int nonAirBlocksCount; - /** - * Size (dimensions) of blocks in a chunks section. - */ - public static final int SIZE = 16 * 16 * 16; // width * depth * height - /** - * Length of the sky and block light nibble arrays. - */ - public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count) - /** - * Length of the block data array. - */ - - private final List palette = Lists.newArrayList(); - private final int[] blocks; - private final NibbleArray blockLight; - private NibbleArray skyLight; - - public ChunkSection1_9to1_8() { - this.blocks = new int[SIZE]; - this.blockLight = new NibbleArray(SIZE); - palette.add(0); // AIR - } - - /** - * Set a block in the chunks - * - * @param x Block X - * @param y Block Y - * @param z Block Z - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int x, int y, int z, int type, int data) { - setBlock(index(x, y, z), type, data); - } - - @Override - public void setFlatBlock(int x, int y, int z, int type) { - int index = palette.indexOf(type); - if (index == -1) { - index = palette.size(); - palette.add(type); - } - - blocks[index(x, y, z)] = index; - } - - public int getBlockId(int x, int y, int z) { - return getBlock(x, y, z) >> 4; - } - - public int getBlock(int x, int y, int z) { - int index = blocks[index(x, y, z)]; - return palette.get(index); - } - - /** - * Set a block in the chunks based on the index - * - * @param idx Index - * @param type The type of the block - * @param data The data value of the block - */ - public void setBlock(int idx, int type, int data) { - int hash = type << 4 | (data & 0xF); - int index = palette.indexOf(hash); - if (index == -1) { - index = palette.size(); - palette.add(hash); - } - - blocks[idx] = index; - } - - /** - * Set the block light array - * - * @param data The value to set the block light to - */ - public void setBlockLight(byte[] data) { - blockLight.setHandle(data); - } - - /** - * Set the sky light array - * - * @param data The value to set the sky light to - */ - public void setSkyLight(byte[] data) { - if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH); - this.skyLight = new NibbleArray(data); - } - - private int index(int x, int y, int z) { - return y << 8 | z << 4 | x; - } - - /** - * Write the blocks to a buffer. - * - * @param output The buffer to write to. - * @throws Exception Throws if it failed to write. - */ - public void writeBlocks(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock += 1; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - @Override - public void writeBlocks1_13(ByteBuf output) throws Exception { - // Write bits per block - int bitsPerBlock = 4; - while (palette.size() > 1 << bitsPerBlock) { - bitsPerBlock++; - } - boolean directPalette = false; - if (bitsPerBlock >= 9) { - bitsPerBlock = 14; - directPalette = true; - } - long maxEntryValue = (1L << bitsPerBlock) - 1; - output.writeByte(bitsPerBlock); - - // Write pallet (or not) - if (!directPalette) { - Type.VAR_INT.write(output, palette.size()); - for (int mappedId : palette) { - Type.VAR_INT.write(output, mappedId); - } - } - - int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0); - Type.VAR_INT.write(output, length); - long[] data = new long[length]; - for (int index = 0; index < blocks.length; index++) { - int value = directPalette ? palette.get(blocks[index]) : blocks[index]; - int bitIndex = index * bitsPerBlock; - int startIndex = bitIndex / 64; - int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; - int startBitSubIndex = bitIndex % 64; - data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex; - if (startIndex != endIndex) { - int endBitSubIndex = 64 - startBitSubIndex; - data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex; - } - } - for (long l : data) { - output.writeLong(l); - } - } - - /** - * Write the block light to a buffer - * - * @param output The buffer to write to - */ - public void writeBlockLight(ByteBuf output) { - output.writeBytes(blockLight.getHandle()); - } - - /** - * Write the sky light to a buffer - * - * @param output The buffer to write to - */ - public void writeSkyLight(ByteBuf output) { - output.writeBytes(skyLight.getHandle()); - } - - @Override - public List getPalette() { - return palette; - } - - /** - * Check if sky light is present - * - * @return True if skylight is present - */ - public boolean hasSkyLight() { - return skyLight != null; - } - - /** - * Get expected size of this chunks section. - * - * @return Amount of bytes sent by this section - * @throws Exception If it failed to calculate bits properly - */ - public int getExpectedSize() throws Exception { - int bitsPerBlock = palette.size() > 255 ? 16 : 8; - int bytes = 1; // bits per block - bytes += paletteBytes(); // palette - bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length - bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data - bytes += LIGHT_LENGTH; // block light - bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light - return bytes; - } - - private int paletteBytes() throws Exception { - // Count bytes used by pallet - int bytes = countBytes(palette.size()); - for (int mappedId : palette) { - bytes += countBytes(mappedId); - } - return bytes; - } - - private int countBytes(int value) throws Exception { - // Count amount of bytes that would be sent if the value were sent as a VarInt - if ((value & (~0 << 7)) == 0) - return 1; - if ((value & (~0 << 14)) == 0) - return 2; - if ((value & (~0 << 21)) == 0) - return 3; - if ((value & (~0 << 28)) == 0) - return 4; - return 5; - } -}