From 2e2fc136156350fb6ac356046c707496ccea3e73 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 28 Oct 2018 20:11:52 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=20=D0=B8=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=B0=D0=BB=D0=B3?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D1=82=D0=BC=20=D1=81=D0=B5=D1=80=D0=B8=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D1=87=D0=B0=D0=BD?= =?UTF-8?q?=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- proto_1.12.2/build.gradle | 1 + .../proto_1_12_2/packets/ChunkDataPacket.java | 204 ++++++++++-------- 2 files changed, 116 insertions(+), 89 deletions(-) diff --git a/proto_1.12.2/build.gradle b/proto_1.12.2/build.gradle index 8e3a7e2..7c71711 100644 --- a/proto_1.12.2/build.gradle +++ b/proto_1.12.2/build.gradle @@ -6,4 +6,5 @@ dependencies { /* Components */ compile (group: 'com.google.code.gson', name: 'gson', version: '2.8.5') + compile (group: 'net.sf.trove4j', name: 'trove4j', version: '3.0.3') } 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 38db3cc..6b880fc 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 @@ -1,9 +1,7 @@ -/* - * DmitriyMX - * 2018-07-21 - */ package mc.core.network.proto_1_12_2.packets; +import gnu.trove.list.TIntList; +import gnu.trove.list.array.TIntArrayList; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -15,7 +13,6 @@ import mc.core.world.block.BlockType; import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkSection; -import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -80,10 +77,6 @@ public class ChunkDataPacket implements SCPacket { private Chunk chunk; private List sectionList; - private int serializeBlockState(BlockType blockType) { - return (blockType.getId() << 4) | blockType.getMeta(); - } - public void setChunk(Chunk chunk) { this.sectionList = null; this.chunk = chunk; @@ -96,13 +89,18 @@ public class ChunkDataPacket implements SCPacket { @Override public void writeSelf(NetOutputStream netStream) { + if (sectionList == null && chunk == null) { + log.warn("Empty chunk data!"); //TODO для такого нужна заглушка + return; + } + netStream.writeInt(x); // Chunk X netStream.writeInt(z); // Chunk Y netStream.writeBoolean(initChunk); // Init Chunk int maxH = 0; + int bitMask = 0; if (sectionList == null && chunk != null) { - int bitMask = 0; for (int h = 15; h >= 0; h--) { bitMask = bitMask << 1; ChunkSection chunkSection = chunk.getChunkSection(h); @@ -113,11 +111,8 @@ public class ChunkDataPacket implements SCPacket { bitMask |= 0x00; } } - - netStream.writeVarInt(bitMask); // Primary Bit Mask } else if (sectionList != null && chunk == null) { sectionList.sort(Comparator.comparingInt(ChunkSection::getY)); - int bitMask = 0; for (int h = 15, i = 0; h >= 0; h--) { bitMask = bitMask << 1; ChunkSection chunkSection = sectionList.get(i); @@ -128,16 +123,13 @@ public class ChunkDataPacket implements SCPacket { bitMask |= 0x00; } } - - netStream.writeVarInt(bitMask); // Primary Bit Mask - } else { - log.warn("Empty chunk data"); - return; } + netStream.writeVarInt(bitMask); // Primary Bit Mask final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream(); - int dataItems = 0; - final int airBlockPalette = serializeBlockState(BlockType.AIR); + + final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream(); + boolean biomeWrite = true; for (int h = 0; h < maxH; h++) { ChunkSection chunkSection = null; @@ -152,64 +144,19 @@ public class ChunkDataPacket implements SCPacket { continue; } - final List palette = new ArrayList<>(); - palette.add(airBlockPalette); - final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream(); - final ByteArrayOutputNetStream blockLight = new ByteArrayOutputNetStream(); - final ByteArrayOutputNetStream skyLight = new ByteArrayOutputNetStream(); - final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream(); - - long dataValueCompacted = 0; - int blockLightCompacted = 0; - int skyLightCompacted = 0; - - int idxHalfLong = 0; - int idxHalfByte = 0; - boolean biomeFinally = false; + final PalettedChunkSection palettedChunkSection = new PalettedChunkSection(); + palettedChunkSection.addBlockType(BlockType.AIR); for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { - Block block = chunkSection.getBlock(x, y, z); - int blockState = serializeBlockState(block.getBlockType()); + palettedChunkSection.addBlock(chunkSection.getBlock(x, y, z)); + palettedChunkSection.addSkyLight(chunkSection.getSkyLight(x, y, z)); - int currentIndexPaletteBlock; - if (!palette.contains(blockState)) { - palette.add(blockState); - currentIndexPaletteBlock = palette.size()-1; - } else { - currentIndexPaletteBlock = palette.indexOf(blockState); - } - - if (idxHalfLong == 0) { - dataValueCompacted = currentIndexPaletteBlock; - idxHalfLong++; - } else if (idxHalfLong > 0 && idxHalfLong < 15) { - dataValueCompacted = (dataValueCompacted << 4) | currentIndexPaletteBlock; - idxHalfLong++; - } else { - dataValueCompacted = (dataValueCompacted << 4) | currentIndexPaletteBlock; - dataArray.writeLong(dataValueCompacted); - idxHalfLong = 0; - dataItems++; - } - - if (idxHalfByte == 0) { - blockLightCompacted = block.getLight(); - skyLightCompacted = chunkSection.getSkyLight(x, y, z); - idxHalfByte++; - } else { - blockLightCompacted = (blockLightCompacted << 4) | block.getLight(); - blockLight.writeByte(blockLightCompacted); - skyLightCompacted = (skyLightCompacted << 4) | chunkSection.getSkyLight(x, y, z); - skyLight.writeByte(skyLightCompacted); - idxHalfByte = 0; - } - - if (!biomeFinally) { + if (biomeWrite) { biomes.writeByte(chunkSection.getBiome(x, z).getId()); if (x == 15 && z == 15) { - biomeFinally = true; + biomeWrite = false; } } } @@ -217,30 +164,109 @@ public class ChunkDataPacket implements SCPacket { } // - // - data.writeUnsignedByte(4); // Bits Per Block - data.writeVarInt(palette.size()); // Size of palette - palette.forEach(data::writeVarInt); // Palette - // - // - data.writeVarInt(dataItems); // Size of Data Array - data.writeBytes(dataArray.toByteArray()); // Data Array - // - // - data.writeBytes(blockLight.toByteArray()); - // - // - data.writeBytes(skyLight.toByteArray()); - // + palettedChunkSection.writeToNetStream(data); // - // - data.writeBytes(biomes.toByteArray()); - // } + // + data.writeBytes(biomes.toByteArray()); + // netStream.writeVarInt(data.size()); // Size of Data netStream.writeBytes(data.toByteArray()); // Data netStream.writeVarInt(0); // Number of block entities /* writeNBT */ } + + private class PalettedChunkSection { + private TIntList palette = new TIntArrayList(); + private int dataItems = 0; + private ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream(); + private ByteArrayOutputNetStream blockLight = new ByteArrayOutputNetStream(); + private ByteArrayOutputNetStream skyLight = new ByteArrayOutputNetStream(); + + private int idxHalfLong = 0; + private int idxHalfByte1 = 0; + private int idxHalfByte2 = 0; + + private long dataValueCompacted = 0; + private int blockLightCompacted = 0; + private int skyLightCompacted = 0; + + private int serializeBlockState(BlockType blockType) { + return (blockType.getId() << 4) | blockType.getMeta(); + } + + int addBlockType(BlockType blockType) { + int blockState = serializeBlockState(blockType); + + int idx; + if (!palette.contains(blockState)) { + palette.add(blockState); + idx = palette.size()-1; + } else { + idx = palette.indexOf(blockState); + } + + return 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 + if (idxHalfByte1 == 0) { + blockLightCompacted = block.getLight(); + idxHalfByte1++; + } else { + blockLightCompacted = (blockLightCompacted << 4) | block.getLight(); + blockLight.writeByte(blockLightCompacted); + idxHalfByte1 = 0; + } + } + + void addSkyLight(int value) { + // sky light data + if (idxHalfByte2 == 0) { + skyLightCompacted = value; + idxHalfByte2++; + } else { + skyLightCompacted = (skyLightCompacted << 4) | value; + skyLight.writeByte(skyLightCompacted); + idxHalfByte2 = 0; + } + } + + void writeToNetStream(final NetOutputStream netOutputStream) { + // + netOutputStream.writeUnsignedByte(4); // 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 + // + // + netOutputStream.writeBytes(blockLight.toByteArray()); + // + // + netOutputStream.writeBytes(skyLight.toByteArray()); + // + } + } }