From 2cb6fda28696cdceda66afe0e729700957489a2c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 14 Jun 2019 18:25:06 +0100 Subject: [PATCH] Moved network chunk serializing code to network\mcpe namespace --- .../network/mcpe/ChunkRequestTask.php | 2 +- .../network/mcpe/ChunkSerializer.php | 77 +++++++++++++++++++ src/pocketmine/world/format/Chunk.php | 44 ----------- 3 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 src/pocketmine/network/mcpe/ChunkSerializer.php diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index cc5ec7d7f..fe9a77a4e 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -43,7 +43,7 @@ class ChunkRequestTask extends AsyncTask{ public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = NetworkCompression::$LEVEL; - $this->chunk = $chunk->networkSerialize(); + $this->chunk = ChunkSerializer::serialize($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; diff --git a/src/pocketmine/network/mcpe/ChunkSerializer.php b/src/pocketmine/network/mcpe/ChunkSerializer.php new file mode 100644 index 000000000..0939504eb --- /dev/null +++ b/src/pocketmine/network/mcpe/ChunkSerializer.php @@ -0,0 +1,77 @@ +getSubChunkSendCount(); + $stream->putByte($subChunkCount); + + for($y = 0; $y < $subChunkCount; ++$y){ + $layers = $chunk->getSubChunk($y)->getBlockLayers(); + $stream->putByte(8); //version + + $stream->putByte(count($layers)); + + foreach($layers as $blocks){ + $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless + $stream->put($blocks->getWordArray()); + $palette = $blocks->getPalette(); + $stream->putVarInt(count($palette)); //yes, this is intentionally zigzag + foreach($palette as $p){ + $stream->putVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf)); + } + } + } + $stream->put(pack("v*", ...$chunk->getHeightMapArray())); + $stream->put($chunk->getBiomeIdArray()); + $stream->putByte(0); //border block array count + //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. + + foreach($chunk->getTiles() as $tile){ + if($tile instanceof Spawnable){ + $stream->put($tile->getSerializedSpawnCompound()); + } + } + + return $stream->getBuffer(); + } +} diff --git a/src/pocketmine/world/format/Chunk.php b/src/pocketmine/world/format/Chunk.php index 7fccb58ed..4a88fd261 100644 --- a/src/pocketmine/world/format/Chunk.php +++ b/src/pocketmine/world/format/Chunk.php @@ -28,14 +28,11 @@ namespace pocketmine\world\format; use pocketmine\block\BlockFactory; use pocketmine\block\BlockLegacyIds; -use pocketmine\block\tile\Spawnable; use pocketmine\block\tile\Tile; use pocketmine\block\tile\TileFactory; use pocketmine\entity\Entity; use pocketmine\entity\EntityFactory; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\network\mcpe\NetworkBinaryStream; -use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; use pocketmine\Player; use pocketmine\world\World; use function array_fill; @@ -45,7 +42,6 @@ use function assert; use function chr; use function count; use function ord; -use function pack; use function str_repeat; use function strlen; @@ -723,46 +719,6 @@ class Chunk{ } } - /** - * Serializes the chunk for sending to players - * - * @return string - */ - public function networkSerialize() : string{ - $stream = new NetworkBinaryStream(); - $subChunkCount = $this->getSubChunkSendCount(); - $stream->putByte($subChunkCount); - - for($y = 0; $y < $subChunkCount; ++$y){ - $layers = $this->subChunks[$y]->getBlockLayers(); - $stream->putByte(8); //version - - $stream->putByte(count($layers)); - - foreach($layers as $blocks){ - $stream->putByte(($blocks->getBitsPerBlock() << 1) | 1); //last 1-bit means "network format", but seems pointless - $stream->put($blocks->getWordArray()); - $palette = $blocks->getPalette(); - $stream->putVarInt(count($palette)); //yes, this is intentionally zigzag - foreach($palette as $p){ - $stream->putVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf)); - } - } - } - $stream->put(pack("v*", ...$this->heightMap)); - $stream->put($this->biomeIds); - $stream->putByte(0); //border block array count - //Border block entry format: 1 byte (4 bits X, 4 bits Z). These are however useless since they crash the regular client. - - foreach($this->tiles as $tile){ - if($tile instanceof Spawnable){ - $stream->put($tile->getSerializedSpawnCompound()); - } - } - - return $stream->getBuffer(); - } - /** * Hashes the given chunk block coordinates into a single integer. *