From 1f5998d24c89e8a160685e3e9c96f4e95dc3dcda Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Thu, 3 Dec 2020 20:52:33 +0000 Subject: [PATCH] FastChunkSerializer no longer encodes chunk coordinates in cases like PopulationTask it makes more sense to store the coordinates separately where they can be stored more efficiently (once instead of 9 times) In addition, PopulationTask shouldn't need to serialize an empty chunk just to copy coordinates. I've made changes like this in other areas already in preparation for the day when chunks no longer contain their coordinates, so this brings us one step closer to that goal. --- src/network/mcpe/ChunkRequestTask.php | 2 +- src/world/format/io/FastChunkSerializer.php | 8 ++----- src/world/generator/PopulationTask.php | 25 +++++++++++++++------ src/world/light/LightPopulationTask.php | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/network/mcpe/ChunkRequestTask.php b/src/network/mcpe/ChunkRequestTask.php index d90e0cd32..395a536b2 100644 --- a/src/network/mcpe/ChunkRequestTask.php +++ b/src/network/mcpe/ChunkRequestTask.php @@ -66,7 +66,7 @@ class ChunkRequestTask extends AsyncTask{ } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); $subCount = ChunkSerializer::getSubChunkCount($chunk); $payload = ChunkSerializer::serialize($chunk, RuntimeBlockMapping::getInstance(), $this->tiles); $this->setResult($this->compressor->compress(PacketBatch::fromPackets(LevelChunkPacket::withoutCache($this->chunkX, $this->chunkZ, $subCount, $payload))->getBuffer())); diff --git a/src/world/format/io/FastChunkSerializer.php b/src/world/format/io/FastChunkSerializer.php index b180c75bb..3151a7bb6 100644 --- a/src/world/format/io/FastChunkSerializer.php +++ b/src/world/format/io/FastChunkSerializer.php @@ -61,8 +61,6 @@ final class FastChunkSerializer{ $includeLight = $includeLight && $chunk->isLightPopulated() === true; $stream = new BinaryStream(); - $stream->putInt($chunk->getX()); - $stream->putInt($chunk->getZ()); $stream->putByte( ($includeLight ? self::FLAG_HAS_LIGHT : 0) | ($chunk->isPopulated() ? self::FLAG_POPULATED : 0) | @@ -109,11 +107,9 @@ final class FastChunkSerializer{ /** * Deserializes a fast-serialized chunk */ - public static function deserialize(string $data) : Chunk{ + public static function deserialize(string $data, int $chunkX, int $chunkZ) : Chunk{ $stream = new BinaryStream($data); - $x = $stream->getInt(); - $z = $stream->getInt(); $flags = $stream->getByte(); $lightPopulated = (bool) ($flags & self::FLAG_HAS_LIGHT); $terrainPopulated = (bool) ($flags & self::FLAG_POPULATED); @@ -148,7 +144,7 @@ final class FastChunkSerializer{ } } - $chunk = new Chunk($x, $z, $subChunks, null, null, $biomeIds, $heightMap); + $chunk = new Chunk($chunkX, $chunkZ, $subChunks, null, null, $biomeIds, $heightMap); $chunk->setGenerated($terrainGenerated); $chunk->setPopulated($terrainPopulated); $chunk->setLightPopulated($lightPopulated); diff --git a/src/world/generator/PopulationTask.php b/src/world/generator/PopulationTask.php index 377acc34e..fcee7cd24 100644 --- a/src/world/generator/PopulationTask.php +++ b/src/world/generator/PopulationTask.php @@ -28,6 +28,7 @@ use pocketmine\world\format\Chunk; use pocketmine\world\format\io\FastChunkSerializer; use pocketmine\world\SimpleChunkManager; use pocketmine\world\World; +use function intdiv; class PopulationTask extends AsyncTask{ private const TLS_KEY_WORLD = "world"; @@ -36,6 +37,11 @@ class PopulationTask extends AsyncTask{ public $state; /** @var int */ public $worldId; + /** @var int */ + private $chunkX; + /** @var int */ + private $chunkZ; + /** @var string */ public $chunk; @@ -62,6 +68,8 @@ class PopulationTask extends AsyncTask{ public function __construct(World $world, Chunk $chunk){ $this->state = true; $this->worldId = $world->getId(); + $this->chunkX = $chunk->getX(); + $this->chunkZ = $chunk->getZ(); $this->chunk = FastChunkSerializer::serializeWithoutLight($chunk); foreach($world->getAdjacentChunks($chunk->getX(), $chunk->getZ()) as $i => $c){ @@ -83,7 +91,7 @@ class PopulationTask extends AsyncTask{ /** @var Chunk[] $chunks */ $chunks = []; - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -93,9 +101,9 @@ class PopulationTask extends AsyncTask{ $zz = -1 + (int) ($i / 3); $ck = $this->{"chunk$i"}; if($ck === null){ - $chunks[$i] = new Chunk($chunk->getX() + $xx, $chunk->getZ() + $zz); + $chunks[$i] = new Chunk($this->chunkX + $xx, $this->chunkZ + $zz); }else{ - $chunks[$i] = FastChunkSerializer::deserialize($ck); + $chunks[$i] = FastChunkSerializer::deserialize($ck, $this->chunkX + $xx, $this->chunkZ + $zz); } } @@ -134,7 +142,7 @@ class PopulationTask extends AsyncTask{ $world->registerGeneratorToWorker($this->worker->getAsyncWorkerId()); } - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); for($i = 0; $i < 9; ++$i){ if($i === 4){ @@ -142,12 +150,15 @@ class PopulationTask extends AsyncTask{ } $c = $this->{"chunk$i"}; if($c !== null){ - $c = FastChunkSerializer::deserialize($c); - $world->generateChunkCallback($c->getX(), $c->getZ(), $this->state ? $c : null); + $xx = -1 + $i % 3; + $zz = -1 + intdiv($i, 3); + + $c = FastChunkSerializer::deserialize($c, $this->chunkX + $xx, $this->chunkZ + $zz); + $world->generateChunkCallback($this->chunkX + $xx, $this->chunkZ + $zz, $this->state ? $c : null); } } - $world->generateChunkCallback($chunk->getX(), $chunk->getZ(), $this->state ? $chunk : null); + $world->generateChunkCallback($this->chunkX, $this->chunkZ, $this->state ? $chunk : null); } } } diff --git a/src/world/light/LightPopulationTask.php b/src/world/light/LightPopulationTask.php index 25828b117..3f5c59a29 100644 --- a/src/world/light/LightPopulationTask.php +++ b/src/world/light/LightPopulationTask.php @@ -60,7 +60,7 @@ class LightPopulationTask extends AsyncTask{ } public function onRun() : void{ - $chunk = FastChunkSerializer::deserialize($this->chunk); + $chunk = FastChunkSerializer::deserialize($this->chunk, $this->chunkX, $this->chunkZ); $manager = new SimpleChunkManager(); $manager->setChunk($this->chunkX, $this->chunkZ, $chunk);