From 66e475cbb8efb9e568743cf2a3350be227d30915 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Dec 2017 19:59:35 +0000 Subject: [PATCH] Region: Remove RegionLoader/McRegion cyclic dependency --- .../level/format/io/region/McRegion.php | 14 ++++++--- .../level/format/io/region/RegionLoader.php | 30 ++++++------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index abdfe366d..32ae24f10 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -315,7 +315,7 @@ class McRegion extends BaseLevelProvider{ if(!$chunk->isGenerated()){ throw new \InvalidStateException("Cannot save un-generated chunk"); } - $this->getRegion($chunkX >> 5, $chunkZ >> 5)->writeChunk($chunk); + $this->getRegion($chunkX >> 5, $chunkZ >> 5)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->nbtSerialize($chunk)); return true; } @@ -341,7 +341,13 @@ class McRegion extends BaseLevelProvider{ $this->loadRegion($regionX, $regionZ); $this->level->timings->syncChunkLoadDataTimer->startTiming(); - $chunk = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); + $chunk = null; + + $chunkData = $this->getRegion($regionX, $regionZ)->readChunk($chunkX & 0x1f, $chunkZ & 0x1f); + if($chunkData !== null){ + $chunk = $this->nbtDeserialize($chunkData); + } + if($chunk === null and $create){ $chunk = new Chunk($chunkX, $chunkZ); } @@ -434,7 +440,7 @@ class McRegion extends BaseLevelProvider{ */ protected function loadRegion(int $regionX, int $regionZ){ if(!isset($this->regions[$index = Level::chunkHash($regionX, $regionZ)])){ - $this->regions[$index] = new RegionLoader($this, $regionX, $regionZ, static::REGION_FILE_EXTENSION); + $this->regions[$index] = new RegionLoader($this->getPath() . "region/r.$regionX.$regionZ." . static::REGION_FILE_EXTENSION, $regionX, $regionZ); try{ $this->regions[$index]->open(); }catch(CorruptedRegionException $e){ @@ -448,7 +454,7 @@ class McRegion extends BaseLevelProvider{ rename($path, $backupPath); $logger->error("Corrupted region file has been backed up to " . $backupPath); - $this->regions[$index] = new RegionLoader($this, $regionX, $regionZ, static::REGION_FILE_EXTENSION); + $this->regions[$index] = new RegionLoader($this->getPath() . "region/r.$regionX.$regionZ." . static::REGION_FILE_EXTENSION, $regionX, $regionZ); $this->regions[$index]->open(); //this will create a new empty region to replace the corrupted one } } diff --git a/src/pocketmine/level/format/io/region/RegionLoader.php b/src/pocketmine/level/format/io/region/RegionLoader.php index f922e8f0d..9eeebe09f 100644 --- a/src/pocketmine/level/format/io/region/RegionLoader.php +++ b/src/pocketmine/level/format/io/region/RegionLoader.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\level\format\io\region; -use pocketmine\level\format\Chunk; use pocketmine\level\format\ChunkException; use pocketmine\utils\Binary; use pocketmine\utils\MainLogger; @@ -49,18 +48,15 @@ class RegionLoader{ protected $filePointer; /** @var int */ protected $lastSector; - /** @var McRegion */ - protected $levelProvider; /** @var int[][] [offset in sectors, chunk size in sectors, timestamp] */ protected $locationTable = []; /** @var int */ public $lastUsed = 0; - public function __construct(McRegion $level, int $regionX, int $regionZ, string $fileExtension = McRegion::REGION_FILE_EXTENSION){ + public function __construct(string $filePath, int $regionX, int $regionZ){ $this->x = $regionX; $this->z = $regionZ; - $this->levelProvider = $level; - $this->filePath = $this->levelProvider->getPath() . "region/r.$regionX.$regionZ.$fileExtension"; + $this->filePath = $filePath; } public function open(){ @@ -99,7 +95,7 @@ class RegionLoader{ return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0); } - public function readChunk(int $x, int $z){ + public function readChunk(int $x, int $z) : ?string{ $index = self::getChunkOffset($x, $z); if($index < 0 or $index >= 4096){ return null; @@ -133,9 +129,9 @@ class RegionLoader{ return null; } - $chunk = $this->levelProvider->nbtDeserialize(fread($this->filePointer, $length - 1)); - if($chunk instanceof Chunk){ - return $chunk; + $chunkData = fread($this->filePointer, $length - 1); + if($chunkData !== false){ + return $chunkData; }else{ MainLogger::getLogger()->error("Corrupted chunk detected"); return null; @@ -146,7 +142,9 @@ class RegionLoader{ return $this->isChunkGenerated(self::getChunkOffset($x, $z)); } - protected function saveChunk(int $x, int $z, string $chunkData){ + public function writeChunk(int $x, int $z, string $chunkData){ + $this->lastUsed = time(); + $length = strlen($chunkData) + 1; if($length + 4 > self::MAX_SECTOR_LENGTH){ throw new ChunkException("Chunk is too big! " . ($length + 4) . " > " . self::MAX_SECTOR_LENGTH); @@ -179,14 +177,6 @@ class RegionLoader{ $this->locationTable[$index][1] = 0; } - public function writeChunk(Chunk $chunk){ - $this->lastUsed = time(); - $chunkData = $this->levelProvider->nbtSerialize($chunk); - if($chunkData !== false){ - $this->saveChunk($chunk->getX() & 0x1f, $chunk->getZ() & 0x1f, $chunkData); - } - } - protected static function getChunkOffset(int $x, int $z) : int{ return $x + ($z << 5); } @@ -204,8 +194,6 @@ class RegionLoader{ fclose($this->filePointer); } - - $this->levelProvider = null; } public function doSlowCleanUp() : int{