22declare(strict_types=1);
24namespace pocketmine\world\format\io\region;
39use pocketmine\world\format\PalettedBlockArray;
42use
function zlib_decode;
53trait LegacyAnvilChunkTrait{
57 protected function deserializeChunk(
string $data, \
Logger $logger) : ?LoadedChunkData{
58 $decompressed = @zlib_decode($data);
59 if($decompressed ===
false){
60 throw new CorruptedChunkException(
"Failed to decompress chunk NBT");
62 $nbt =
new BigEndianNbtSerializer();
64 $chunk = $nbt->read($decompressed)->mustGetCompoundTag();
65 }
catch(NbtDataException $e){
66 throw new CorruptedChunkException($e->getMessage(), 0, $e);
68 $chunk = $chunk->getTag(
"Level");
69 if(!($chunk instanceof CompoundTag)){
70 throw new CorruptedChunkException(
"'Level' key is missing from chunk NBT");
73 $makeBiomeArray =
function(
string $biomeIds) : PalettedBlockArray{
74 if(strlen($biomeIds) !== 256){
75 throw new CorruptedChunkException(
"Expected biome array to be exactly 256 bytes, got " . strlen($biomeIds));
81 if(($biomeColorsTag = $chunk->getTag(
"BiomeColors")) instanceof IntArrayTag){
83 }elseif(($biomesTag = $chunk->getTag(
"Biomes")) instanceof ByteArrayTag){
84 $biomes3d = $makeBiomeArray($biomesTag->getValue());
86 $biomes3d =
new PalettedBlockArray(BiomeIds::OCEAN);
90 $subChunksTag = $chunk->getListTag(
"Sections") ?? [];
91 foreach($subChunksTag as $subChunk){
92 if($subChunk instanceof CompoundTag){
93 $y = $subChunk->getByte(
"Y");
94 $subChunks[$y] = $this->deserializeSubChunk($subChunk, clone $biomes3d,
new \
PrefixedLogger($logger,
"Subchunk y=$y"));
97 for($y = Chunk::MIN_SUBCHUNK_INDEX; $y <= Chunk::MAX_SUBCHUNK_INDEX; ++$y){
98 if(!isset($subChunks[$y])){
99 $subChunks[$y] =
new SubChunk(Block::EMPTY_STATE_ID, [], clone $biomes3d);
103 return new LoadedChunkData(
106 $chunk->getByte(
"TerrainPopulated", 0) !== 0,
107 ($entitiesTag = $chunk->getTag(
"Entities")) instanceof ListTag ? self::getCompoundList(
"Entities", $entitiesTag) : [],
108 ($tilesTag = $chunk->getTag(
"TileEntities")) instanceof ListTag ? self::getCompoundList(
"TileEntities", $tilesTag) : [],
111 fixerFlags: LoadedChunkData::FIXER_FLAG_ALL
115 abstract protected function deserializeSubChunk(CompoundTag $subChunk, PalettedBlockArray $biomes3d, \
Logger $logger) : SubChunk;