BaseLevelProvider: stop crashing the server on invalid level.dat

broken userdata isn't a core bug, so it shouldn't be flooding our crash archives.
This commit is contained in:
Dylan K. Taylor 2020-05-11 15:34:53 +01:00
parent ef97c8f99e
commit 2f47597d75

View File

@ -35,6 +35,7 @@ use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function mkdir;
use function zlib_decode;
abstract class BaseLevelProvider implements LevelProvider{
/** @var string */
@ -53,8 +54,20 @@ abstract class BaseLevelProvider implements LevelProvider{
}
protected function loadLevelData() : void{
$compressedLevelData = @file_get_contents($this->getPath() . "level.dat");
if($compressedLevelData === false){
throw new LevelException("Failed to read level.dat (permission denied or doesn't exist)");
}
$rawLevelData = @zlib_decode($compressedLevelData);
if($rawLevelData === false){
throw new LevelException("Failed to decompress level.dat contents (probably corrupted)");
}
$nbt = new BigEndianNBTStream();
$levelData = $nbt->readCompressed(file_get_contents($this->getPath() . "level.dat"));
try{
$levelData = $nbt->read($rawLevelData);
}catch(\UnexpectedValueException $e){
throw new LevelException("Failed to decode level.dat (" . $e->getMessage() . ")", 0, $e);
}
if(!($levelData instanceof CompoundTag) or !$levelData->hasTag("Data", CompoundTag::class)){
throw new LevelException("Invalid level.dat");