From ca7968a0d5a85362bd43ddfec487367010e738e3 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 11 Nov 2018 02:45:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=BC=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D1=80=D1=83=D0=BF?= =?UTF-8?q?=D0=BD=D0=BE-=D0=BF=D0=B0=D0=BB=D0=B8=D1=82=D1=80=D1=8B=D1=85?= =?UTF-8?q?=20=D1=87=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit если в палитре больше 15 блоков, то используется больше битов на один блок --- .../proto_1_12_2/packets/ChunkDataPacket.java | 123 +++++++++++------- 1 file changed, 79 insertions(+), 44 deletions(-) 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 + - '}'; - } }