diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java
index 2223ad9..0e35b48 100644
--- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java
+++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java
@@ -9,7 +9,6 @@ import mc.core.network.NetOutputStream;
import mc.core.network.SCPacket;
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
import mc.core.utils.NibbleArray;
-import mc.core.world.Biome;
import mc.core.world.block.Block;
import mc.core.world.block.BlockLocation;
import mc.core.world.block.BlockType;
@@ -180,71 +179,116 @@ public class ChunkDataPacket implements SCPacket {
/* writeNBT */
}
+ @Override
+ public String toString() {
+ return "ChunkDataPacket{" +
+ "x=" + x +
+ ", z=" + z +
+ ", chunk=" + chunk +
+ '}';
+ }
+
private class PalettedChunkSection {
private TIntList palette = new TIntArrayList();
- private int dataItems = 0;
- private ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream();
+ private byte[] blocks = new byte[4096];
private NibbleArray blockLight = new NibbleArray();
private NibbleArray skyLight = new NibbleArray();
- private int idxHalfLong = 0;
+ private int coordsToIndex(BlockLocation location) {
+ return coordsToIndex(location.getX(), location.getY(), location.getZ());
+ }
- private long dataValueCompacted = 0;
+ private int coordsToIndex(int x, int y, int z) {
+ return y << 8 | z << 4 | x;
+ }
private int serializeBlockState(BlockType blockType) {
return (blockType.getId() << 4) | blockType.getMeta();
}
- int addBlockType(BlockType blockType) {
+ byte addBlockType(BlockType blockType) {
int blockState = serializeBlockState(blockType);
- int idx;
- if (!palette.contains(blockState)) {
+ int idx = palette.indexOf(blockState);
+ if (idx == -1) {
palette.add(blockState);
idx = palette.size()-1;
- } else {
- idx = palette.indexOf(blockState);
}
- return idx;
+ return (byte) idx;
}
- void addBlock(Block block) {
- int idx = addBlockType(block.getBlockType());
-
- //TODO нужно убрать этот позор
- // block data
- if (idxHalfLong == 0) {
- dataValueCompacted = idx;
- idxHalfLong++;
- } else if (idxHalfLong > 0 && idxHalfLong < 15) {
- dataValueCompacted = (dataValueCompacted << 4) | idx;
- idxHalfLong++;
- } else {
- dataValueCompacted = (dataValueCompacted << 4) | idx;
- dataArray.writeLong(dataValueCompacted);
- idxHalfLong = 0;
- dataItems++;
- }
-
- // block light data
- blockLight.set(block.getLocation().toLocal(), block.getLight());
+ void addBlockLight(int x, int y, int z, int value) {
+ blockLight.set(x, y, z, value);
}
void addSkyLight(int x, int y, int z, int value) {
- // sky light data
skyLight.set(x, y, z, value);
}
+ void addBlock(Block block) {
+ BlockLocation location = block.getLocation().toLocal();
+ blocks[coordsToIndex(location)] = addBlockType(block.getBlockType());
+ addBlockLight(location.getX(), location.getY(), location.getZ(), block.getLight());
+ }
+
void writeToNetStream(final NetOutputStream netOutputStream) {
+ int bitsPerBlock = 4;
+ if (palette.size() > 15) {
+ if (palette.size() <= 31)
+ bitsPerBlock = 5;
+ else if (palette.size() > 31 && palette.size() <= 63)
+ bitsPerBlock = 6;
+ else if (palette.size() > 63 && palette.size() <= 127)
+ bitsPerBlock = 7;
+ else if (palette.size() > 127 && palette.size() <= 255)
+ bitsPerBlock = 8;
+ }
+
//
- netOutputStream.writeUnsignedByte(4); // Bits Per Block
+ netOutputStream.writeUnsignedByte(bitsPerBlock); // Bits Per Block
netOutputStream.writeVarInt(palette.size()); // Size of palette
palette.forEach(value -> { netOutputStream.writeVarInt(value); return true; }); // Palette
//
//
- netOutputStream.writeVarInt(dataItems); // Size of Data Array
- netOutputStream.writeBytes(dataArray.toByteArray()); // Data Array
+ final int dataLength = (4096/*16*16*16*/ * bitsPerBlock) / 64;
+ netOutputStream.writeVarInt(dataLength); // Size of Data Array
+ //
+ long value = 0;
+ int lastPos = 0;
+ boolean fairy = false;
+ long fairyValue = 0;
+ for (int y = 0; y < 16; y++) {
+ for (int z = 0; z < 16; z++) {
+ for (int x = 0; x < 16; x++) {
+ final int blockNumber = (((y << 4) + z) << 4) + x;
+ final int startLong = ( blockNumber * bitsPerBlock ) / 64;
+ final int startOffset = ( blockNumber * bitsPerBlock ) % 64;
+ final int endLong = ((blockNumber + 1) * bitsPerBlock - 1) / 64;
+
+ final long idxBlockInPalette = blocks[coordsToIndex(x, y, z)];
+
+ if (startLong != lastPos) {
+ netOutputStream.writeLong(value);
+ lastPos = startLong;
+ if (fairy) {
+ value = fairyValue;
+ fairy = false;
+ } else {
+ value = 0;
+ }
+ }
+ value |= (idxBlockInPalette << startOffset);
+
+ if (startLong != endLong) {
+ fairyValue = idxBlockInPalette >> (64 - startOffset);
+ fairy = true;
+ }
+ }
+ }
+ }
+ netOutputStream.writeLong(value);
+ //
//
//
netOutputStream.writeBytes(blockLight.getRawData());
@@ -254,13 +298,4 @@ public class ChunkDataPacket implements SCPacket {
//
}
}
-
- @Override
- public String toString() {
- return "ChunkDataPacket{" +
- "x=" + x +
- ", z=" + z +
- ", chunk=" + chunk +
- '}';
- }
}