isLightPopulated(); $stream = new BinaryStream(); $stream->putInt($chunk->getX()); $stream->putInt($chunk->getZ()); $stream->putByte( ($includeLight ? self::FLAG_HAS_LIGHT : 0) | ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) | ($chunk->isGenerated() ? self::FLAG_GENERATED : 0) ); if($chunk->isGenerated()){ //subchunks $subChunks = $chunk->getSubChunks(); $count = $subChunks->count(); $stream->putByte($count); foreach($subChunks as $y => $subChunk){ $stream->putByte($y); $layers = $subChunk->getBlockLayers(); $stream->putByte(count($layers)); foreach($layers as $blocks){ $wordArray = $blocks->getWordArray(); $palette = $blocks->getPalette(); $stream->putByte($blocks->getBitsPerBlock()); $stream->put($wordArray); $serialPalette = pack("L*", ...$palette); $stream->putInt(strlen($serialPalette)); $stream->put($serialPalette); } if($includeLight){ $stream->put($subChunk->getBlockSkyLightArray()->getData()); $stream->put($subChunk->getBlockLightArray()->getData()); } } //biomes $stream->put($chunk->getBiomeIdArray()); if($includeLight){ $stream->put(pack("S*", ...$chunk->getHeightMapArray())); } } return $stream->getBuffer(); } /** * Deserializes a fast-serialized chunk */ public static function deserialize(string $data) : Chunk{ $stream = new BinaryStream($data); $x = $stream->getInt(); $z = $stream->getInt(); $flags = $stream->getByte(); $lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); $terrainGenerated = (bool) ($flags & self::FLAG_GENERATED); $subChunks = []; $biomeIds = null; $heightMap = null; if($terrainGenerated){ $count = $stream->getByte(); for($subCount = 0; $subCount < $count; ++$subCount){ $y = $stream->getByte(); /** @var PalettedBlockArray[] $layers */ $layers = []; for($i = 0, $layerCount = $stream->getByte(); $i < $layerCount; ++$i){ $bitsPerBlock = $stream->getByte(); $words = $stream->get(PalettedBlockArray::getExpectedWordArraySize($bitsPerBlock)); $palette = array_values(unpack("L*", $stream->get($stream->getInt()))); $layers[] = PalettedBlockArray::fromData($bitsPerBlock, $words, $palette); } $subChunks[$y] = new SubChunk( BlockLegacyIds::AIR << 4, $layers, $lightPopulated ? new LightArray($stream->get(2048)) : null, $lightPopulated ? new LightArray($stream->get(2048)) : null ); } $biomeIds = new BiomeArray($stream->get(256)); if($lightPopulated){ $heightMap = new HeightArray(array_values(unpack("S*", $stream->get(512)))); } } $chunk = new Chunk($x, $z, $subChunks, null, null, $biomeIds, $heightMap); $chunk->setGenerated($terrainGenerated); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); return $chunk; } }