mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-24 22:44:45 +00:00
Since task execution depends on tasks executing sequentially on a particular worker in some cases (e.g. PopulationTask must be preceded by GeneratorRegisterTask), it doesn't make sense to continue task execution if an error occurs. Moreover, a task crashing may render the whole server unstable, as it leaves the server in an undefined state. This is the same kind of problem we fixed with scheduled tasks in PM3. In versions past, pthreads was unreliable enough that random tasks would crash without an obvious reason, forcing us to accommodate this. I still don't know the origin or frequency of said issues, but I think it's time to rip the band-aid off and solve these problems for real.
79 lines
3.0 KiB
PHP
79 lines
3.0 KiB
PHP
<?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\network\mcpe;
|
|
|
|
use pocketmine\network\mcpe\compression\CompressBatchPromise;
|
|
use pocketmine\network\mcpe\compression\Compressor;
|
|
use pocketmine\network\mcpe\convert\TypeConverter;
|
|
use pocketmine\network\mcpe\protocol\LevelChunkPacket;
|
|
use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
|
|
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
|
use pocketmine\network\mcpe\protocol\types\ChunkPosition;
|
|
use pocketmine\network\mcpe\serializer\ChunkSerializer;
|
|
use pocketmine\scheduler\AsyncTask;
|
|
use pocketmine\thread\NonThreadSafeValue;
|
|
use pocketmine\utils\BinaryStream;
|
|
use pocketmine\world\format\Chunk;
|
|
use pocketmine\world\format\io\FastChunkSerializer;
|
|
|
|
class ChunkRequestTask extends AsyncTask{
|
|
private const TLS_KEY_PROMISE = "promise";
|
|
|
|
protected string $chunk;
|
|
protected int $chunkX;
|
|
protected int $chunkZ;
|
|
/** @phpstan-var NonThreadSafeValue<Compressor> */
|
|
protected NonThreadSafeValue $compressor;
|
|
private string $tiles;
|
|
|
|
public function __construct(int $chunkX, int $chunkZ, Chunk $chunk, CompressBatchPromise $promise, Compressor $compressor){
|
|
$this->compressor = new NonThreadSafeValue($compressor);
|
|
|
|
$this->chunk = FastChunkSerializer::serializeTerrain($chunk);
|
|
$this->chunkX = $chunkX;
|
|
$this->chunkZ = $chunkZ;
|
|
$this->tiles = ChunkSerializer::serializeTiles($chunk);
|
|
|
|
$this->storeLocal(self::TLS_KEY_PROMISE, $promise);
|
|
}
|
|
|
|
public function onRun() : void{
|
|
$chunk = FastChunkSerializer::deserializeTerrain($this->chunk);
|
|
$subCount = ChunkSerializer::getSubChunkCount($chunk);
|
|
$converter = TypeConverter::getInstance();
|
|
$encoderContext = new PacketSerializerContext($converter->getItemTypeDictionary());
|
|
$payload = ChunkSerializer::serializeFullChunk($chunk, $converter->getBlockTranslator(), $encoderContext, $this->tiles);
|
|
|
|
$stream = new BinaryStream();
|
|
PacketBatch::encodePackets($stream, $encoderContext, [LevelChunkPacket::create(new ChunkPosition($this->chunkX, $this->chunkZ), $subCount, false, null, $payload)]);
|
|
$this->setResult($this->compressor->deserialize()->compress($stream->getBuffer()));
|
|
}
|
|
|
|
public function onCompletion() : void{
|
|
/** @var CompressBatchPromise $promise */
|
|
$promise = $this->fetchLocal(self::TLS_KEY_PROMISE);
|
|
$promise->resolve($this->getResult());
|
|
}
|
|
}
|