Archived
0

fix: ChunkDataPacket

Many thanks Forwolk!
This commit is contained in:
2018-08-04 18:40:11 +03:00
parent 4206354760
commit 1b4f2f8eac

View File

@@ -8,14 +8,14 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.Location;
import mc.core.network.NetOutputStream; import mc.core.network.NetOutputStream;
import mc.core.network.SCPacket; import mc.core.network.SCPacket;
import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream; import mc.core.network.proto_1_12_2.ByteArrayOutputNetStream;
import mc.core.world.Block; import mc.core.world.Block;
import mc.core.world.Chunk; import mc.core.world.Chunk;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -80,8 +80,8 @@ public class ChunkDataPacket implements SCPacket {
@Getter @Getter
private List<Chunk> chunks = new ArrayList<>(); private List<Chunk> chunks = new ArrayList<>();
private long serializeBlockState(Block block) { private int serializeBlockState(int id, int state) {
return (block.getId() << 4) | block.getState(); return (id << 4) | state;
} }
@Override @Override
@@ -89,25 +89,33 @@ public class ChunkDataPacket implements SCPacket {
netStream.writeInt(x); // Chunk X netStream.writeInt(x); // Chunk X
netStream.writeInt(z); // Chunk Y netStream.writeInt(z); // Chunk Y
netStream.writeBoolean(initChunk); // Init Chunk netStream.writeBoolean(initChunk); // Init Chunk
netStream.writeVarInt(0b11111111); // Primary Bit Mask netStream.writeVarInt(0b00000001); // Primary Bit Mask
final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream(); final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream();
int dataItems = 0;
final int airBlockPalette = serializeBlockState(0, 0);
for (Chunk chunk : chunks) { for (Chunk chunk : chunks) {
final List<Long> palette = new ArrayList<>(); final List<Integer> palette = new ArrayList<>();
palette.add(airBlockPalette);
final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream(); final ByteArrayOutputNetStream dataArray = new ByteArrayOutputNetStream();
final ByteArrayOutputNetStream blockLight = new ByteArrayOutputNetStream(); final ByteArrayOutputNetStream blockLight = new ByteArrayOutputNetStream();
final ByteArrayOutputNetStream skyLight = new ByteArrayOutputNetStream(); final ByteArrayOutputNetStream skyLight = new ByteArrayOutputNetStream();
final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream(); final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream();
long dataValueCompacted = 0;
int blockLightCompacted = 0; int blockLightCompacted = 0;
boolean flagFirstHalf = true; int skyLightCompacted = 0;
int idxHalfLong = 0;
int idxHalfByte = 0;
boolean biomeFinally = false;
for (int y = 0; y < 16; y++) { for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
Block block = chunk.getBlock(x, y, z); Block block = chunk.getBlock(x, y, z);
long blockState = serializeBlockState(block); int blockState = serializeBlockState(block.getId(), block.getState());
int currentIndexPaletteBlock; int currentIndexPaletteBlock;
if (!palette.contains(blockState)) { if (!palette.contains(blockState)) {
@@ -117,18 +125,37 @@ public class ChunkDataPacket implements SCPacket {
currentIndexPaletteBlock = palette.indexOf(blockState); currentIndexPaletteBlock = palette.indexOf(blockState);
} }
dataArray.writeLong(currentIndexPaletteBlock); if (idxHalfLong == 0) {
if (flagFirstHalf) { 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(); blockLightCompacted = block.getLight();
flagFirstHalf = false; skyLightCompacted = chunk.getSkyLight(x, y, z);
idxHalfByte++;
} else { } else {
blockLightCompacted = (blockLightCompacted << 4) | block.getLight(); blockLightCompacted = (blockLightCompacted << 4) | block.getLight();
blockLight.writeByte(blockLightCompacted); blockLight.writeByte(blockLightCompacted);
flagFirstHalf = true; skyLightCompacted = (skyLightCompacted << 4) | chunk.getSkyLight(x, y, z);
skyLight.writeByte(0b11111111); //FIXME skyLight.writeByte(skyLightCompacted);
idxHalfByte = 0;
} }
if (!biomeFinally) {
biomes.writeByte(chunk.getBiome(x, z)); biomes.writeByte(chunk.getBiome(x, z));
if (x == 15 && z == 15) {
biomeFinally = true;
}
}
} }
} }
} }
@@ -137,12 +164,10 @@ public class ChunkDataPacket implements SCPacket {
// <Palette> // <Palette>
data.writeUnsignedByte(4); // Bits Per Block data.writeUnsignedByte(4); // Bits Per Block
data.writeVarInt(palette.size()); // Size of palette data.writeVarInt(palette.size()); // Size of palette
palette.stream() palette.forEach(data::writeVarInt); // Palette
.mapToInt(Long::intValue)
.forEach(data::writeVarInt); // Palette
// </Palette> // </Palette>
// <Data Array> // <Data Array>
data.writeVarInt(dataArray.size()); // Size of Data Array data.writeVarInt(dataItems); // Size of Data Array
data.writeBytes(dataArray.toByteArray()); // Data Array data.writeBytes(dataArray.toByteArray()); // Data Array
// </Data Array> // </Data Array>
// <Block Light> // <Block Light>