diff --git a/src/world/format/io/region/LegacyAnvilChunkTrait.php b/src/world/format/io/region/LegacyAnvilChunkTrait.php index 8970a2fb3..7debb29ba 100644 --- a/src/world/format/io/region/LegacyAnvilChunkTrait.php +++ b/src/world/format/io/region/LegacyAnvilChunkTrait.php @@ -51,7 +51,7 @@ trait LegacyAnvilChunkTrait{ /** * @throws CorruptedChunkException */ - protected function deserializeChunk(string $data) : ChunkData{ + protected function deserializeChunk(string $data) : ?ChunkData{ $decompressed = @zlib_decode($data); if($decompressed === false){ throw new CorruptedChunkException("Failed to decompress chunk NBT"); diff --git a/src/world/format/io/region/McRegion.php b/src/world/format/io/region/McRegion.php index 3367a2f81..bf1597364 100644 --- a/src/world/format/io/region/McRegion.php +++ b/src/world/format/io/region/McRegion.php @@ -29,6 +29,7 @@ use pocketmine\data\bedrock\BiomeIds; use pocketmine\nbt\BigEndianNbtSerializer; use pocketmine\nbt\NbtDataException; use pocketmine\nbt\tag\ByteArrayTag; +use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; @@ -45,7 +46,7 @@ class McRegion extends RegionWorldProvider{ /** * @throws CorruptedChunkException */ - protected function deserializeChunk(string $data) : ChunkData{ + protected function deserializeChunk(string $data) : ?ChunkData{ $decompressed = @zlib_decode($data); if($decompressed === false){ throw new CorruptedChunkException("Failed to decompress chunk NBT"); @@ -61,6 +62,14 @@ class McRegion extends RegionWorldProvider{ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } + $legacyGeneratedTag = $chunk->getTag("TerrainGenerated"); + if($legacyGeneratedTag instanceof ByteTag && $legacyGeneratedTag->getValue() === 0){ + //In legacy PM before 3.0, PM used to save MCRegion chunks even when they weren't generated. In these cases + //(we'll see them in old worlds), some of the tags which we expect to always be present, will be missing. + //If TerrainGenerated (PM-specific tag from the olden days) is false, toss the chunk data and don't bother + //trying to read it. + return null; + } $subChunks = []; $fullIds = self::readFixedSizeByteArray($chunk, "Blocks", 32768); $fullData = self::readFixedSizeByteArray($chunk, "Data", 16384); diff --git a/src/world/format/io/region/RegionWorldProvider.php b/src/world/format/io/region/RegionWorldProvider.php index df28c3ffe..1fe62912c 100644 --- a/src/world/format/io/region/RegionWorldProvider.php +++ b/src/world/format/io/region/RegionWorldProvider.php @@ -146,7 +146,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{ /** * @throws CorruptedChunkException */ - abstract protected function deserializeChunk(string $data) : ChunkData; + abstract protected function deserializeChunk(string $data) : ?ChunkData; /** * @return CompoundTag[]