mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-07 10:22:56 +00:00
Level: cleaned up chunk loading error handling, close #2056
This now removes logging from the level providers (for the most part) and replaces it with exception throws and catches. The implementation using the providers should catch these exceptions if they are thrown.
This commit is contained in:
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\level\format\io\region;
|
||||
|
||||
use pocketmine\level\format\ChunkException;
|
||||
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
@ -95,10 +96,18 @@ class RegionLoader{
|
||||
return !($this->locationTable[$index][0] === 0 or $this->locationTable[$index][1] === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $x
|
||||
* @param int $z
|
||||
*
|
||||
* @return null|string
|
||||
* @throws \InvalidArgumentException if invalid coordinates are given
|
||||
* @throws CorruptedChunkException if chunk corruption is detected
|
||||
*/
|
||||
public function readChunk(int $x, int $z) : ?string{
|
||||
$index = self::getChunkOffset($x, $z);
|
||||
if($index < 0 or $index >= 4096){
|
||||
return null;
|
||||
throw new \InvalidArgumentException("Invalid chunk position in region, expected x/z in range 0-31, got x=$x, z=$z");
|
||||
}
|
||||
|
||||
$this->lastUsed = time();
|
||||
@ -115,27 +124,26 @@ class RegionLoader{
|
||||
if($length >= self::MAX_SECTOR_LENGTH){
|
||||
$this->locationTable[$index][0] = ++$this->lastSector;
|
||||
$this->locationTable[$index][1] = 1;
|
||||
MainLogger::getLogger()->error("Corrupted chunk header detected");
|
||||
throw new CorruptedChunkException("Corrupted chunk header detected (sector count larger than max)");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if($length > ($this->locationTable[$index][1] << 12)){ //Invalid chunk, bigger than defined number of sectors
|
||||
MainLogger::getLogger()->error("Corrupted bigger chunk detected");
|
||||
MainLogger::getLogger()->error("Corrupted bigger chunk detected (bigger than number of sectors given in header)");
|
||||
$this->locationTable[$index][1] = $length >> 12;
|
||||
$this->writeLocationIndex($index);
|
||||
}elseif($compression !== self::COMPRESSION_ZLIB and $compression !== self::COMPRESSION_GZIP){
|
||||
MainLogger::getLogger()->error("Invalid compression type");
|
||||
return null;
|
||||
throw new CorruptedChunkException("Invalid compression type (got $compression, expected " . self::COMPRESSION_ZLIB . " or " . self::COMPRESSION_GZIP . ")");
|
||||
}
|
||||
|
||||
$chunkData = fread($this->filePointer, $length - 1);
|
||||
if($chunkData !== false){
|
||||
return $chunkData;
|
||||
}else{
|
||||
MainLogger::getLogger()->error("Corrupted chunk detected");
|
||||
return null;
|
||||
if($chunkData === false){
|
||||
throw new CorruptedChunkException("Corrupted chunk detected (failed to read chunk data from disk)");
|
||||
|
||||
}
|
||||
|
||||
return $chunkData;
|
||||
}
|
||||
|
||||
public function chunkExists(int $x, int $z) : bool{
|
||||
|
Reference in New Issue
Block a user