Merge branch 'release/3.5'

This commit is contained in:
Dylan K. Taylor 2018-12-29 20:58:12 +00:00
commit 39c0fa6103
6 changed files with 47 additions and 24 deletions

View File

@ -48,6 +48,8 @@ use pocketmine\level\biome\Biome;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
use pocketmine\level\format\ChunkException; use pocketmine\level\format\ChunkException;
use pocketmine\level\format\EmptySubChunk; use pocketmine\level\format\EmptySubChunk;
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;
@ -2652,10 +2654,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){
@ -2736,23 +2737,17 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
try{ if($trySave and $this->getAutoSave() and $chunk->isGenerated()){
if($trySave and $this->getAutoSave() and $chunk->isGenerated()){ if($chunk->hasChanged() or count($chunk->getTiles()) > 0 or count($chunk->getSavableEntities()) > 0){
if($chunk->hasChanged() or count($chunk->getTiles()) > 0 or count($chunk->getSavableEntities()) > 0){ $this->provider->saveChunk($chunk);
$this->provider->saveChunk($chunk);
}
} }
foreach($this->getChunkLoaders($x, $z) as $loader){
$loader->onChunkUnloaded($chunk);
}
$chunk->onUnload();
}catch(\Throwable $e){
$logger = $this->server->getLogger();
$logger->error($this->server->getLanguage()->translateString("pocketmine.level.chunkUnloadError", [$e->getMessage()]));
$logger->logException($e);
} }
foreach($this->getChunkLoaders($x, $z) as $loader){
$loader->onChunkUnloaded($chunk);
}
$chunk->onUnload();
} }
unset($this->chunks[$chunkHash]); unset($this->chunks[$chunkHash]);

View File

@ -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;
abstract class BaseLevelProvider implements LevelProvider{ abstract class BaseLevelProvider implements LevelProvider{
@ -54,6 +56,14 @@ abstract class BaseLevelProvider implements LevelProvider{
return $this->levelData; return $this->levelData;
} }
/**
* @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);
} }
@ -65,6 +75,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;

View File

@ -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;
interface LevelProvider{ interface LevelProvider{
@ -80,8 +82,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;

View File

@ -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 @@ trait LegacyAnvilChunkTrait{
$nbt = new BigEndianNBTStream(); $nbt = new BigEndianNBTStream();
$chunk = $nbt->readCompressed($data); $chunk = $nbt->readCompressed($data);
if(!$chunk->hasTag("Level")){ if(!$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");

View File

@ -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;
@ -98,12 +98,13 @@ class McRegion extends RegionLevelProvider{
* @param string $data * @param string $data
* *
* @return Chunk * @return Chunk
* @throws CorruptedChunkException
*/ */
protected function deserializeChunk(string $data) : Chunk{ protected function deserializeChunk(string $data) : Chunk{
$nbt = new BigEndianNBTStream(); $nbt = new BigEndianNBTStream();
$chunk = $nbt->readCompressed($data); $chunk = $nbt->readCompressed($data);
if(!$chunk->hasTag("Level")){ if(!$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");

View File

@ -26,6 +26,7 @@ namespace pocketmine\level\format\io\region;
use pocketmine\level\format\Chunk; use pocketmine\level\format\Chunk;
use pocketmine\level\format\io\BaseLevelProvider; use pocketmine\level\format\io\BaseLevelProvider;
use pocketmine\level\format\io\data\JavaLevelData; use pocketmine\level\format\io\data\JavaLevelData;
use pocketmine\level\format\io\exception\CorruptedChunkException;
use pocketmine\level\format\io\LevelData; use pocketmine\level\format\io\LevelData;
use pocketmine\level\Level; use pocketmine\level\Level;
@ -156,6 +157,12 @@ abstract class RegionLevelProvider extends BaseLevelProvider{
abstract protected function serializeChunk(Chunk $chunk) : string; abstract protected function serializeChunk(Chunk $chunk) : string;
/**
* @param string $data
*
* @return Chunk
* @throws CorruptedChunkException
*/
abstract protected function deserializeChunk(string $data) : Chunk; abstract protected function deserializeChunk(string $data) : Chunk;
protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{ protected function readChunk(int $chunkX, int $chunkZ) : ?Chunk{