mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-06 01:51:51 +00:00
Handle errors properly on chunk load
Only CorruptedChunkException and UnsupportedChunkFormatException are expected. Anything else should crash the server.
This commit is contained in:
parent
beb5d72299
commit
cd80ae00d4
@ -49,6 +49,8 @@ use pocketmine\level\format\ChunkException;
|
|||||||
use pocketmine\level\format\EmptySubChunk;
|
use pocketmine\level\format\EmptySubChunk;
|
||||||
use pocketmine\level\format\io\BaseLevelProvider;
|
use pocketmine\level\format\io\BaseLevelProvider;
|
||||||
use pocketmine\level\format\io\ChunkRequestTask;
|
use pocketmine\level\format\io\ChunkRequestTask;
|
||||||
|
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||||
|
use pocketmine\level\format\io\exception\UnsupportedChunkFormatException;
|
||||||
use pocketmine\level\format\io\LevelProvider;
|
use pocketmine\level\format\io\LevelProvider;
|
||||||
use pocketmine\level\generator\Generator;
|
use pocketmine\level\generator\Generator;
|
||||||
use pocketmine\level\generator\GeneratorManager;
|
use pocketmine\level\generator\GeneratorManager;
|
||||||
@ -2750,10 +2752,9 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
|
|
||||||
try{
|
try{
|
||||||
$chunk = $this->provider->loadChunk($x, $z);
|
$chunk = $this->provider->loadChunk($x, $z);
|
||||||
}catch(\Exception $e){
|
}catch(CorruptedChunkException | UnsupportedChunkFormatException $e){
|
||||||
$logger = $this->server->getLogger();
|
$logger = $this->server->getLogger();
|
||||||
$logger->critical("An error occurred while loading chunk x=$x z=$z: " . $e->getMessage());
|
$logger->critical("Failed to load chunk x=$x z=$z: " . $e->getMessage());
|
||||||
$logger->logException($e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($chunk === null and $create){
|
if($chunk === null and $create){
|
||||||
|
@ -24,6 +24,8 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\level\format\io;
|
namespace pocketmine\level\format\io;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
|
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||||
|
use pocketmine\level\format\io\exception\UnsupportedChunkFormatException;
|
||||||
use pocketmine\level\LevelException;
|
use pocketmine\level\LevelException;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\nbt\BigEndianNBTStream;
|
use pocketmine\nbt\BigEndianNBTStream;
|
||||||
@ -152,6 +154,14 @@ abstract class BaseLevelProvider implements LevelProvider{
|
|||||||
file_put_contents($this->getPath() . "level.dat", $buffer);
|
file_put_contents($this->getPath() . "level.dat", $buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $chunkX
|
||||||
|
* @param int $chunkZ
|
||||||
|
*
|
||||||
|
* @return Chunk|null
|
||||||
|
* @throws CorruptedChunkException
|
||||||
|
* @throws UnsupportedChunkFormatException
|
||||||
|
*/
|
||||||
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
||||||
return $this->readChunk($chunkX, $chunkZ);
|
return $this->readChunk($chunkX, $chunkZ);
|
||||||
}
|
}
|
||||||
@ -163,6 +173,14 @@ abstract class BaseLevelProvider implements LevelProvider{
|
|||||||
$this->writeChunk($chunk);
|
$this->writeChunk($chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $chunkX
|
||||||
|
* @param int $chunkZ
|
||||||
|
*
|
||||||
|
* @return Chunk|null
|
||||||
|
* @throws UnsupportedChunkFormatException
|
||||||
|
* @throws CorruptedChunkException
|
||||||
|
*/
|
||||||
abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk;
|
abstract protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk;
|
||||||
|
|
||||||
abstract protected function writeChunk(Chunk $chunk) : void;
|
abstract protected function writeChunk(Chunk $chunk) : void;
|
||||||
|
@ -24,6 +24,8 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\level\format\io;
|
namespace pocketmine\level\format\io;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
|
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||||
|
use pocketmine\level\format\io\exception\UnsupportedChunkFormatException;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
|
|
||||||
interface LevelProvider{
|
interface LevelProvider{
|
||||||
@ -100,8 +102,8 @@ interface LevelProvider{
|
|||||||
*
|
*
|
||||||
* @return null|Chunk
|
* @return null|Chunk
|
||||||
*
|
*
|
||||||
* @throws \Exception any of a range of exceptions that could be thrown while reading chunks. See individual
|
* @throws CorruptedChunkException
|
||||||
* implementations for details.
|
* @throws UnsupportedChunkFormatException
|
||||||
*/
|
*/
|
||||||
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk;
|
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk;
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\level\format\io\region;
|
namespace pocketmine\level\format\io\region;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\format\ChunkException;
|
|
||||||
use pocketmine\level\format\io\ChunkUtils;
|
use pocketmine\level\format\io\ChunkUtils;
|
||||||
|
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||||
use pocketmine\level\format\SubChunk;
|
use pocketmine\level\format\SubChunk;
|
||||||
use pocketmine\nbt\BigEndianNBTStream;
|
use pocketmine\nbt\BigEndianNBTStream;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
@ -99,7 +99,7 @@ class Anvil extends McRegion{
|
|||||||
$nbt = new BigEndianNBTStream();
|
$nbt = new BigEndianNBTStream();
|
||||||
$chunk = $nbt->readCompressed($data);
|
$chunk = $nbt->readCompressed($data);
|
||||||
if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){
|
if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){
|
||||||
throw new ChunkException("Invalid NBT format");
|
throw new CorruptedChunkException("'Level' key is missing from chunk NBT");
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk = $chunk->getCompoundTag("Level");
|
$chunk = $chunk->getCompoundTag("Level");
|
||||||
|
@ -24,9 +24,9 @@ declare(strict_types=1);
|
|||||||
namespace pocketmine\level\format\io\region;
|
namespace pocketmine\level\format\io\region;
|
||||||
|
|
||||||
use pocketmine\level\format\Chunk;
|
use pocketmine\level\format\Chunk;
|
||||||
use pocketmine\level\format\ChunkException;
|
|
||||||
use pocketmine\level\format\io\BaseLevelProvider;
|
use pocketmine\level\format\io\BaseLevelProvider;
|
||||||
use pocketmine\level\format\io\ChunkUtils;
|
use pocketmine\level\format\io\ChunkUtils;
|
||||||
|
use pocketmine\level\format\io\exception\CorruptedChunkException;
|
||||||
use pocketmine\level\format\SubChunk;
|
use pocketmine\level\format\SubChunk;
|
||||||
use pocketmine\level\generator\GeneratorManager;
|
use pocketmine\level\generator\GeneratorManager;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
@ -107,12 +107,13 @@ class McRegion extends BaseLevelProvider{
|
|||||||
* @param string $data
|
* @param string $data
|
||||||
*
|
*
|
||||||
* @return Chunk
|
* @return Chunk
|
||||||
|
* @throws CorruptedChunkException
|
||||||
*/
|
*/
|
||||||
protected function nbtDeserialize(string $data) : Chunk{
|
protected function nbtDeserialize(string $data) : Chunk{
|
||||||
$nbt = new BigEndianNBTStream();
|
$nbt = new BigEndianNBTStream();
|
||||||
$chunk = $nbt->readCompressed($data);
|
$chunk = $nbt->readCompressed($data);
|
||||||
if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){
|
if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){
|
||||||
throw new ChunkException("Invalid NBT format");
|
throw new CorruptedChunkException("'Level' key is missing from chunk NBT");
|
||||||
}
|
}
|
||||||
|
|
||||||
$chunk = $chunk->getCompoundTag("Level");
|
$chunk = $chunk->getCompoundTag("Level");
|
||||||
@ -348,6 +349,14 @@ class McRegion extends BaseLevelProvider{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $chunkX
|
||||||
|
* @param int $chunkZ
|
||||||
|
*
|
||||||
|
* @return Chunk|null
|
||||||
|
*
|
||||||
|
* @throws CorruptedChunkException
|
||||||
|
*/
|
||||||
protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{
|
||||||
$regionX = $regionZ = null;
|
$regionX = $regionZ = null;
|
||||||
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
|
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user