Clean up entity/tile data loading from world providers

This commit is contained in:
Dylan K. Taylor 2021-08-29 23:11:18 +01:00
parent 533b0d0724
commit 994a2c9eb9
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
12 changed files with 106 additions and 76 deletions

View File

@ -75,6 +75,7 @@ use pocketmine\utils\ReversePriorityQueue;
use pocketmine\world\biome\Biome; use pocketmine\world\biome\Biome;
use pocketmine\world\biome\BiomeRegistry; use pocketmine\world\biome\BiomeRegistry;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\ChunkData;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\io\WritableWorldProvider;
use pocketmine\world\format\LightArray; use pocketmine\world\format\LightArray;
@ -1127,7 +1128,11 @@ class World implements ChunkManager{
foreach($this->chunks as $chunkHash => $chunk){ foreach($this->chunks as $chunkHash => $chunk){
if($chunk->isDirty()){ if($chunk->isDirty()){
self::getXZ($chunkHash, $chunkX, $chunkZ); self::getXZ($chunkHash, $chunkX, $chunkZ);
$this->provider->saveChunk($chunkX, $chunkZ, $chunk); $this->provider->saveChunk($chunkX, $chunkZ, new ChunkData(
$chunk,
array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()),
array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()),
));
$chunk->clearDirtyFlags(); $chunk->clearDirtyFlags();
} }
} }
@ -2443,31 +2448,31 @@ class World implements ChunkManager{
return null; return null;
} }
$this->chunks[$chunkHash] = $chunk; $this->chunks[$chunkHash] = $chunk->getChunk();
unset($this->blockCache[$chunkHash]); unset($this->blockCache[$chunkHash]);
$this->initChunk($x, $z, $chunk); $this->initChunk($x, $z, $chunk);
(new ChunkLoadEvent($this, $x, $z, $chunk, false))->call(); (new ChunkLoadEvent($this, $x, $z, $this->chunks[$chunkHash], false))->call();
if(!$this->isChunkInUse($x, $z)){ if(!$this->isChunkInUse($x, $z)){
$this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity"); $this->logger->debug("Newly loaded chunk $x $z has no loaders registered, will be unloaded at next available opportunity");
$this->unloadChunkRequest($x, $z); $this->unloadChunkRequest($x, $z);
} }
foreach($this->getChunkListeners($x, $z) as $listener){ foreach($this->getChunkListeners($x, $z) as $listener){
$listener->onChunkLoaded($x, $z, $chunk); $listener->onChunkLoaded($x, $z, $this->chunks[$chunkHash]);
} }
$this->timings->syncChunkLoad->stopTiming(); $this->timings->syncChunkLoad->stopTiming();
return $chunk; return $this->chunks[$chunkHash];
} }
private function initChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ private function initChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{
if($chunk->NBTentities !== null){ if(count($chunkData->getEntityNBT()) !== 0){
$this->timings->syncChunkLoadEntities->startTiming(); $this->timings->syncChunkLoadEntities->startTiming();
$entityFactory = EntityFactory::getInstance(); $entityFactory = EntityFactory::getInstance();
foreach($chunk->NBTentities as $k => $nbt){ foreach($chunkData->getEntityNBT() as $k => $nbt){
try{ try{
$entity = $entityFactory->createFromData($this, $nbt); $entity = $entityFactory->createFromData($this, $nbt);
}catch(NbtDataException $e){ }catch(NbtDataException $e){
@ -2489,14 +2494,14 @@ class World implements ChunkManager{
//here, because entities currently add themselves to the world //here, because entities currently add themselves to the world
} }
$chunk->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true); $this->getChunk($chunkX, $chunkZ)?->setDirtyFlag(Chunk::DIRTY_FLAG_ENTITIES, true);
$chunk->NBTentities = null;
$this->timings->syncChunkLoadEntities->stopTiming(); $this->timings->syncChunkLoadEntities->stopTiming();
} }
if($chunk->NBTtiles !== null){
if(count($chunkData->getTileNBT()) !== 0){
$this->timings->syncChunkLoadTileEntities->startTiming(); $this->timings->syncChunkLoadTileEntities->startTiming();
$tileFactory = TileFactory::getInstance(); $tileFactory = TileFactory::getInstance();
foreach($chunk->NBTtiles as $k => $nbt){ foreach($chunkData->getTileNBT() as $k => $nbt){
try{ try{
$tile = $tileFactory->createFromData($this, $nbt); $tile = $tileFactory->createFromData($this, $nbt);
}catch(NbtDataException $e){ }catch(NbtDataException $e){
@ -2513,8 +2518,7 @@ class World implements ChunkManager{
} }
} }
$chunk->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true); $this->getChunk($chunkX, $chunkZ)?->setDirtyFlag(Chunk::DIRTY_FLAG_TILES, true);
$chunk->NBTtiles = null;
$this->timings->syncChunkLoadTileEntities->stopTiming(); $this->timings->syncChunkLoadTileEntities->stopTiming();
} }
} }
@ -2564,7 +2568,11 @@ class World implements ChunkManager{
if($trySave and $this->getAutoSave() and $chunk->isDirty()){ if($trySave and $this->getAutoSave() and $chunk->isDirty()){
$this->timings->syncChunkSave->startTiming(); $this->timings->syncChunkSave->startTiming();
try{ try{
$this->provider->saveChunk($x, $z, $chunk); $this->provider->saveChunk($x, $z, new ChunkData(
$chunk,
array_map(fn(Entity $e) => $e->saveNBT(), $chunk->getSavableEntities()),
array_map(fn(Tile $t) => $t->saveNBT(), $chunk->getTiles()),
));
}finally{ }finally{
$this->timings->syncChunkSave->stopTiming(); $this->timings->syncChunkSave->stopTiming();
} }

View File

@ -31,7 +31,6 @@ use pocketmine\block\BlockLegacyIds;
use pocketmine\block\tile\Tile; use pocketmine\block\tile\Tile;
use pocketmine\data\bedrock\BiomeIds; use pocketmine\data\bedrock\BiomeIds;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\player\Player; use pocketmine\player\Player;
use function array_fill; use function array_fill;
use function array_filter; use function array_filter;
@ -72,18 +71,10 @@ class Chunk{
/** @var BiomeArray */ /** @var BiomeArray */
protected $biomeIds; protected $biomeIds;
/** @var CompoundTag[]|null */
public $NBTtiles;
/** @var CompoundTag[]|null */
public $NBTentities;
/** /**
* @param SubChunk[] $subChunks * @param SubChunk[] $subChunks
* @param CompoundTag[] $entities
* @param CompoundTag[] $tiles
*/ */
public function __construct(array $subChunks = [], ?array $entities = null, ?array $tiles = null, ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){ public function __construct(array $subChunks = [], ?BiomeArray $biomeIds = null, ?HeightArray $heightMap = null){
$this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS); $this->subChunks = new \SplFixedArray(Chunk::MAX_SUBCHUNKS);
foreach($this->subChunks as $y => $null){ foreach($this->subChunks as $y => $null){
@ -93,9 +84,6 @@ class Chunk{
$val = ($this->subChunks->getSize() * 16); $val = ($this->subChunks->getSize() * 16);
$this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val)); $this->heightMap = $heightMap ?? new HeightArray(array_fill(0, 256, $val));
$this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN); $this->biomeIds = $biomeIds ?? BiomeArray::fill(BiomeIds::OCEAN);
$this->NBTtiles = $tiles;
$this->NBTentities = $entities;
} }
/** /**
@ -292,20 +280,6 @@ class Chunk{
} }
} }
/**
* @return CompoundTag[]
*/
public function getNBTtiles() : array{
return $this->NBTtiles ?? array_map(function(Tile $tile) : CompoundTag{ return $tile->saveNBT(); }, $this->tiles);
}
/**
* @return CompoundTag[]
*/
public function getNBTentities() : array{
return $this->NBTentities ?? array_map(function(Entity $entity) : CompoundTag{ return $entity->saveNBT(); }, $this->getSavableEntities());
}
public function getBiomeIdArray() : string{ public function getBiomeIdArray() : string{
return $this->biomeIds->getData(); return $this->biomeIds->getData();
} }

View File

@ -0,0 +1,48 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\world\format\io;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\world\format\Chunk;
final class ChunkData{
/**
* @param CompoundTag[] $entityNBT
* @param CompoundTag[] $tileNBT
*/
public function __construct(
private Chunk $chunk,
private array $entityNBT,
private array $tileNBT
){}
public function getChunk() : Chunk{ return $this->chunk; }
/** @return CompoundTag[] */
public function getEntityNBT() : array{ return $this->entityNBT; }
/** @return CompoundTag[] */
public function getTileNBT() : array{ return $this->tileNBT; }
}

View File

@ -143,7 +143,7 @@ final class FastChunkSerializer{
$heightMap = new HeightArray(array_values($unpackedHeightMap)); $heightMap = new HeightArray(array_values($unpackedHeightMap));
} }
$chunk = new Chunk($subChunks, null, null, $biomeIds, $heightMap); $chunk = new Chunk($subChunks, $biomeIds, $heightMap);
$chunk->setPopulated($terrainPopulated); $chunk->setPopulated($terrainPopulated);
$chunk->setLightPopulated($lightPopulated); $chunk->setLightPopulated($lightPopulated);
$chunk->clearDirtyFlags(); $chunk->clearDirtyFlags();

View File

@ -149,7 +149,7 @@ class FormatConverter{
$thisRound = $start; $thisRound = $start;
foreach($this->oldProvider->getAllChunks(true, $this->logger) as $coords => $chunk){ foreach($this->oldProvider->getAllChunks(true, $this->logger) as $coords => $chunk){
[$chunkX, $chunkZ] = $coords; [$chunkX, $chunkZ] = $coords;
$chunk->setDirty(); $chunk->getChunk()->setDirty();
$new->saveChunk($chunkX, $chunkZ, $chunk); $new->saveChunk($chunkX, $chunkZ, $chunk);
$counter++; $counter++;
if(($counter % $this->chunksPerProgressUpdate) === 0){ if(($counter % $this->chunksPerProgressUpdate) === 0){

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace pocketmine\world\format\io; namespace pocketmine\world\format\io;
use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
interface WorldProvider{ interface WorldProvider{
@ -44,7 +43,7 @@ interface WorldProvider{
* *
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk; public function loadChunk(int $chunkX, int $chunkZ) : ?ChunkData;
/** /**
* Performs garbage collection in the world provider, such as cleaning up regions in Region-based worlds. * Performs garbage collection in the world provider, such as cleaning up regions in Region-based worlds.
@ -64,8 +63,8 @@ interface WorldProvider{
/** /**
* Returns a generator which yields all the chunks in this world. * Returns a generator which yields all the chunks in this world.
* *
* @return \Generator|Chunk[] * @return \Generator|ChunkData[]
* @phpstan-return \Generator<array{int, int}, Chunk, void, void> * @phpstan-return \Generator<array{int, int}, ChunkData, void, void>
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator; public function getAllChunks(bool $skipCorrupted = false, ?\Logger $logger = null) : \Generator;

View File

@ -23,11 +23,9 @@ declare(strict_types=1);
namespace pocketmine\world\format\io; namespace pocketmine\world\format\io;
use pocketmine\world\format\Chunk;
interface WritableWorldProvider extends WorldProvider{ interface WritableWorldProvider extends WorldProvider{
/** /**
* Saves a chunk (usually to disk). * Saves a chunk (usually to disk).
*/ */
public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void; public function saveChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void;
} }

View File

@ -36,6 +36,7 @@ use pocketmine\utils\BinaryStream;
use pocketmine\world\format\BiomeArray; use pocketmine\world\format\BiomeArray;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\BaseWorldProvider;
use pocketmine\world\format\io\ChunkData;
use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\ChunkUtils;
use pocketmine\world\format\io\data\BedrockWorldData; use pocketmine\world\format\io\data\BedrockWorldData;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
@ -232,7 +233,7 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
/** /**
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ public function loadChunk(int $chunkX, int $chunkZ) : ?ChunkData{
$index = LevelDB::chunkIndex($chunkX, $chunkZ); $index = LevelDB::chunkIndex($chunkX, $chunkZ);
$chunkVersionRaw = $this->db->get($index . self::TAG_VERSION); $chunkVersionRaw = $this->db->get($index . self::TAG_VERSION);
@ -405,8 +406,6 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
$chunk = new Chunk( $chunk = new Chunk(
$subChunks, $subChunks,
$entities,
$tiles,
$biomeArray $biomeArray
); );
@ -423,16 +422,17 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
$chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format $chunk->setDirty(); //trigger rewriting chunk to disk if it was converted from an older format
} }
return $chunk; return new ChunkData($chunk, $entities, $tiles);
} }
public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ public function saveChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{
$idMap = LegacyBlockIdToStringIdMap::getInstance(); $idMap = LegacyBlockIdToStringIdMap::getInstance();
$index = LevelDB::chunkIndex($chunkX, $chunkZ); $index = LevelDB::chunkIndex($chunkX, $chunkZ);
$write = new \LevelDBWriteBatch(); $write = new \LevelDBWriteBatch();
$write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION)); $write->put($index . self::TAG_VERSION, chr(self::CURRENT_LEVEL_CHUNK_VERSION));
$chunk = $chunkData->getChunk();
if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){ if($chunk->getDirtyFlag(Chunk::DIRTY_FLAG_TERRAIN)){
$subChunks = $chunk->getSubChunks(); $subChunks = $chunk->getSubChunks();
foreach($subChunks as $y => $subChunk){ foreach($subChunks as $y => $subChunk){
@ -474,8 +474,8 @@ class LevelDB extends BaseWorldProvider implements WritableWorldProvider{
//TODO: use this properly //TODO: use this properly
$write->put($index . self::TAG_STATE_FINALISATION, chr($chunk->isPopulated() ? self::FINALISATION_DONE : self::FINALISATION_NEEDS_POPULATION)); $write->put($index . self::TAG_STATE_FINALISATION, chr($chunk->isPopulated() ? self::FINALISATION_DONE : self::FINALISATION_NEEDS_POPULATION));
$this->writeTags($chunk->getNBTtiles(), $index . self::TAG_BLOCK_ENTITY, $write); $this->writeTags($chunkData->getTileNBT(), $index . self::TAG_BLOCK_ENTITY, $write);
$this->writeTags($chunk->getNBTentities(), $index . self::TAG_ENTITY, $write); $this->writeTags($chunkData->getEntityNBT(), $index . self::TAG_ENTITY, $write);
$write->delete($index . self::TAG_DATA_2D_LEGACY); $write->delete($index . self::TAG_DATA_2D_LEGACY);
$write->delete($index . self::TAG_LEGACY_TERRAIN); $write->delete($index . self::TAG_LEGACY_TERRAIN);

View File

@ -31,6 +31,7 @@ use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\world\format\BiomeArray; use pocketmine\world\format\BiomeArray;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\ChunkData;
use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\ChunkUtils;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
use pocketmine\world\format\SubChunk; use pocketmine\world\format\SubChunk;
@ -49,7 +50,7 @@ trait LegacyAnvilChunkTrait{
/** /**
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
protected function deserializeChunk(string $data) : Chunk{ protected function deserializeChunk(string $data) : ChunkData{
$decompressed = @zlib_decode($data); $decompressed = @zlib_decode($data);
if($decompressed === false){ if($decompressed === false){
throw new CorruptedChunkException("Failed to decompress chunk NBT"); throw new CorruptedChunkException("Failed to decompress chunk NBT");
@ -89,12 +90,14 @@ trait LegacyAnvilChunkTrait{
$result = new Chunk( $result = new Chunk(
$subChunks, $subChunks,
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
$biomeArray $biomeArray
); );
$result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0); $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0);
return $result; return new ChunkData(
$result,
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
);
} }
abstract protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk; abstract protected function deserializeSubChunk(CompoundTag $subChunk) : SubChunk;

View File

@ -33,6 +33,7 @@ use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\world\format\BiomeArray; use pocketmine\world\format\BiomeArray;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\ChunkData;
use pocketmine\world\format\io\ChunkUtils; use pocketmine\world\format\io\ChunkUtils;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
use pocketmine\world\format\io\SubChunkConverter; use pocketmine\world\format\io\SubChunkConverter;
@ -43,7 +44,7 @@ class McRegion extends RegionWorldProvider{
/** /**
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
protected function deserializeChunk(string $data) : Chunk{ protected function deserializeChunk(string $data) : ChunkData{
$decompressed = @zlib_decode($data); $decompressed = @zlib_decode($data);
if($decompressed === false){ if($decompressed === false){
throw new CorruptedChunkException("Failed to decompress chunk NBT"); throw new CorruptedChunkException("Failed to decompress chunk NBT");
@ -81,14 +82,13 @@ class McRegion extends RegionWorldProvider{
$biomeIds = $makeBiomeArray($biomesTag->getValue()); $biomeIds = $makeBiomeArray($biomesTag->getValue());
} }
$result = new Chunk( $result = new Chunk($subChunks, $biomeIds);
$subChunks, $result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0);
return new ChunkData(
$result,
($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [], ($entitiesTag = $chunk->getTag("Entities")) instanceof ListTag ? self::getCompoundList("Entities", $entitiesTag) : [],
($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [], ($tilesTag = $chunk->getTag("TileEntities")) instanceof ListTag ? self::getCompoundList("TileEntities", $tilesTag) : [],
$biomeIds
); );
$result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0);
return $result;
} }
protected static function getRegionFileExtension() : string{ protected static function getRegionFileExtension() : string{

View File

@ -27,8 +27,8 @@ use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\ByteArrayTag;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\world\format\Chunk;
use pocketmine\world\format\io\BaseWorldProvider; use pocketmine\world\format\io\BaseWorldProvider;
use pocketmine\world\format\io\ChunkData;
use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\data\JavaWorldData;
use pocketmine\world\format\io\exception\CorruptedChunkException; use pocketmine\world\format\io\exception\CorruptedChunkException;
use pocketmine\world\format\io\WorldData; use pocketmine\world\format\io\WorldData;
@ -146,7 +146,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{
/** /**
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
abstract protected function deserializeChunk(string $data) : Chunk; abstract protected function deserializeChunk(string $data) : ChunkData;
/** /**
* @return CompoundTag[] * @return CompoundTag[]
@ -185,7 +185,7 @@ abstract class RegionWorldProvider extends BaseWorldProvider{
/** /**
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
public function loadChunk(int $chunkX, int $chunkZ) : ?Chunk{ public function loadChunk(int $chunkX, int $chunkZ) : ?ChunkData{
$regionX = $regionZ = null; $regionX = $regionZ = null;
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
assert(is_int($regionX) and is_int($regionZ)); assert(is_int($regionX) and is_int($regionZ));

View File

@ -23,7 +23,7 @@ declare(strict_types=1);
namespace pocketmine\world\format\io\region; namespace pocketmine\world\format\io\region;
use pocketmine\world\format\Chunk; use pocketmine\world\format\io\ChunkData;
use pocketmine\world\format\io\data\JavaWorldData; use pocketmine\world\format\io\data\JavaWorldData;
use pocketmine\world\format\io\WritableWorldProvider; use pocketmine\world\format\io\WritableWorldProvider;
use pocketmine\world\WorldCreationOptions; use pocketmine\world\WorldCreationOptions;
@ -51,10 +51,10 @@ abstract class WritableRegionWorldProvider extends RegionWorldProvider implement
JavaWorldData::generate($path, $name, $options, static::getPcWorldFormatVersion()); JavaWorldData::generate($path, $name, $options, static::getPcWorldFormatVersion());
} }
abstract protected function serializeChunk(Chunk $chunk) : string; abstract protected function serializeChunk(ChunkData $chunk) : string;
public function saveChunk(int $chunkX, int $chunkZ, Chunk $chunk) : void{ public function saveChunk(int $chunkX, int $chunkZ, ChunkData $chunkData) : void{
self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ); self::getRegionIndex($chunkX, $chunkZ, $regionX, $regionZ);
$this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunk)); $this->loadRegion($regionX, $regionZ)->writeChunk($chunkX & 0x1f, $chunkZ & 0x1f, $this->serializeChunk($chunkData));
} }
} }