44 private const FLAG_POPULATED = 1 << 1;
46 private function __construct(){
50 private static function serializePalettedArray(ByteBufferWriter $stream, PalettedBlockArray $array) :
void{
51 $wordArray = $array->getWordArray();
52 $palette = $array->getPalette();
54 Byte::writeUnsigned($stream, $array->getBitsPerBlock());
55 $stream->writeByteArray($wordArray);
56 $serialPalette = pack(
"L*", ...$palette);
57 BE::writeUnsignedInt($stream, strlen($serialPalette));
58 $stream->writeByteArray($serialPalette);
66 $stream = new ByteBufferWriter();
67 Byte::writeUnsigned($stream, ($chunk->isPopulated() ? self::FLAG_POPULATED : 0));
71 $count = count($subChunks);
72 Byte::writeUnsigned($stream, $count);
74 foreach($subChunks as $y => $subChunk){
75 Byte::writeSigned($stream, $y);
76 BE::writeUnsignedInt($stream, $subChunk->getEmptyBlockId());
78 $layers = $subChunk->getBlockLayers();
79 Byte::writeUnsigned($stream, count($layers));
80 foreach($layers as $blocks){
81 self::serializePalettedArray($stream, $blocks);
83 self::serializePalettedArray($stream, $subChunk->getBiomeArray());
86 return $stream->getData();
89 private static function deserializePalettedArray(ByteBufferReader $stream) : PalettedBlockArray{
90 $bitsPerBlock = Byte::readUnsigned($stream);
91 $words = $stream->readByteArray(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock));
92 $paletteSize = BE::readUnsignedInt($stream);
94 $unpackedPalette = unpack(
"L*", $stream->readByteArray($paletteSize));
95 $palette = array_values($unpackedPalette);
97 return PalettedBlockArray::fromData($bitsPerBlock, $words, $palette);
104 $stream = new ByteBufferReader($data);
106 $flags = Byte::readUnsigned($stream);
107 $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED);
111 $count = Byte::readUnsigned($stream);
112 for($subCount = 0; $subCount < $count; ++$subCount){
113 $y = Byte::readSigned($stream);
115 $airBlockId = BE::readUnsignedInt($stream);
117 $layerCount = Byte::readUnsigned($stream);
119 throw new \UnexpectedValueException(
"Expected at most 2 layers, but got $layerCount");
121 $layer0 = $layerCount >= 1 ? self::deserializePalettedArray($stream) : null;
122 $layer1 = $layerCount === 2 ? self::deserializePalettedArray($stream) : null;
124 $biomeArray = self::deserializePalettedArray($stream);
125 $subChunks[$y] =
new SubChunk($airBlockId, $layer0, $layer1, $biomeArray);
128 return new Chunk($subChunks, $terrainPopulated);