Added LevelProvider->getAllChunks() method

this returns a generator which yields known chunks. This will be used in the future for world format conversions.
This commit is contained in:
Dylan K. Taylor 2018-10-03 19:43:16 +01:00
parent 8a062f440d
commit 23132b899c
3 changed files with 44 additions and 0 deletions

View File

@ -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;
}

View File

@ -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;
}
}
}
}
}

View File

@ -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;
}
}
}
}
}
}