diff --git a/src/pocketmine/network/mcpe/ChunkRequestTask.php b/src/pocketmine/network/mcpe/ChunkRequestTask.php index fe9a77a4ec..c1f04986c2 100644 --- a/src/pocketmine/network/mcpe/ChunkRequestTask.php +++ b/src/pocketmine/network/mcpe/ChunkRequestTask.php @@ -26,6 +26,7 @@ namespace pocketmine\network\mcpe; use pocketmine\network\mcpe\protocol\FullChunkDataPacket; use pocketmine\scheduler\AsyncTask; use pocketmine\world\format\Chunk; +use pocketmine\world\format\io\FastChunkSerializer; class ChunkRequestTask extends AsyncTask{ private const TLS_KEY_PROMISE = "promise"; @@ -40,19 +41,24 @@ class ChunkRequestTask extends AsyncTask{ protected $compressionLevel; + /** @var string */ + private $tiles = ""; + public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, ?\Closure $onError = null){ $this->compressionLevel = NetworkCompression::$LEVEL; - $this->chunk = ChunkSerializer::serialize($chunk); + $this->chunk = FastChunkSerializer::serialize($chunk); $this->chunkX = $chunkX; $this->chunkZ = $chunkZ; + $this->tiles = ChunkSerializer::serializeTiles($chunk); $this->storeLocal(self::TLS_KEY_PROMISE, $promise); $this->storeLocal(self::TLS_KEY_ERROR_HOOK, $onError); } public function onRun() : void{ - $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $this->chunk))->getBuffer(), $this->compressionLevel)); + $chunk = ChunkSerializer::serialize(FastChunkSerializer::deserialize($this->chunk), $this->tiles); + $this->setResult(NetworkCompression::compress(PacketBatch::fromPackets(FullChunkDataPacket::create($this->chunkX, $this->chunkZ, $chunk))->getBuffer(), $this->compressionLevel)); } public function onError() : void{ diff --git a/src/pocketmine/network/mcpe/ChunkSerializer.php b/src/pocketmine/network/mcpe/ChunkSerializer.php index 0939504eb0..b8f702285d 100644 --- a/src/pocketmine/network/mcpe/ChunkSerializer.php +++ b/src/pocketmine/network/mcpe/ChunkSerializer.php @@ -25,6 +25,7 @@ namespace pocketmine\network\mcpe; use pocketmine\block\tile\Spawnable; use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping; +use pocketmine\utils\BinaryStream; use pocketmine\world\format\Chunk; use function count; use function pack; @@ -36,11 +37,13 @@ final class ChunkSerializer{ } /** - * @param Chunk $chunk + * @param Chunk $chunk + * + * @param string|null $tiles * * @return string */ - public static function serialize(Chunk $chunk) : string{ + public static function serialize(Chunk $chunk, ?string $tiles = null) : string{ $stream = new NetworkBinaryStream(); $subChunkCount = $chunk->getSubChunkSendCount(); $stream->putByte($subChunkCount); @@ -66,6 +69,16 @@ final class ChunkSerializer{ $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. + if($tiles !== null){ + $stream->put($tiles); + }else{ + $stream->put(self::serializeTiles($chunk)); + } + return $stream->getBuffer(); + } + + public static function serializeTiles(Chunk $chunk) : string{ + $stream = new BinaryStream(); foreach($chunk->getTiles() as $tile){ if($tile instanceof Spawnable){ $stream->put($tile->getSerializedSpawnCompound());