From 23132b899cd791dab3832af00d41292fcb096f01 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 3 Oct 2018 19:43:16 +0100 Subject: [PATCH] Added LevelProvider->getAllChunks() method this returns a generator which yields known chunks. This will be used in the future for world format conversions. --- .../level/format/io/LevelProvider.php | 7 ++++++ .../level/format/io/leveldb/LevelDB.php | 12 +++++++++ .../level/format/io/region/McRegion.php | 25 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/src/pocketmine/level/format/io/LevelProvider.php b/src/pocketmine/level/format/io/LevelProvider.php index bf7ce8589..93c6c9a2a 100644 --- a/src/pocketmine/level/format/io/LevelProvider.php +++ b/src/pocketmine/level/format/io/LevelProvider.php @@ -206,4 +206,11 @@ interface LevelProvider{ */ public function close(); + /** + * Returns a generator which yields all the chunks in this level. + * + * @return \Generator|Chunk[] + */ + public function getAllChunks() : \Generator; + } diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index d82c5a833..34017d2f8 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -535,4 +535,16 @@ class LevelDB extends BaseLevelProvider{ public function close(){ $this->db->close(); } + + public function getAllChunks() : \Generator{ + foreach($this->db->getIterator() as $key => $_){ + if(strlen($key) === 9 and substr($key, -1) === self::TAG_VERSION){ + $chunkX = Binary::readLInt(substr($key, 0, 4)); + $chunkZ = Binary::readLInt(substr($key, 4, 4)); + if(($chunk = $this->loadChunk($chunkX, $chunkZ)) !== null){ + yield $chunk; + } + } + } + } } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 35bf7f1af..4cb8df9ca 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -413,4 +413,29 @@ class McRegion extends BaseLevelProvider{ $this->getRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->nbtSerialize($chunk)); } + + public function getAllChunks() : \Generator{ + $iterator = new \RegexIterator( + new \FilesystemIterator( + $this->path . '/region/', + \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS + ), + '/\/r\.(-?\d+)\.(-?\d+)\.' . static::REGION_FILE_EXTENSION . '$/', + \RegexIterator::GET_MATCH + ); + + foreach($iterator as $region){ + $rX = ((int) $region[1]) << 5; + $rZ = ((int) $region[2]) << 5; + + for($chunkX = $rX; $chunkX < $rX + 32; ++$chunkX){ + for($chunkZ = $rZ; $chunkZ < $rZ + 32; ++$chunkZ){ + $chunk = $this->loadChunk($chunkX, $chunkZ); + if($chunk !== null){ + yield $chunk; + } + } + } + } + } }