Как сделать копирование /copy и /paste логику

Как сделать копирование /copy и вставить /paste логику с асинхронными потоками
код:

<?php
namespace FastAsyncWorldEdit;

use pocketmine\plugin\PluginBase;
use pocketmine\event\Listener;
use pocketmine\command\Command;
use pocketmine\block\BlockIds;
use pocketmine\command\CommandSender;
use pocketmine\Player;
use pocketmine\math\Vector3;
use pocketmine\block\Block;
use pocketmine\scheduler\AsyncTask;
use pocketmine\Server;

class Main extends PluginBase implements Listener {

    private array $positions = [];

    public function onEnable() {
        $this->getServer()->getPluginManager()->registerEvents($this, $this);
    }

    public function onCommand(CommandSender $sender, Command $command, $label, array $args): bool {
        if (!$sender instanceof Player) {
            $sender->sendMessage("Эта команда доступна только для игроков.");
            return true;
        }

        switch ($command->getName()) {
            case "pos1":
                $this->setPlayerPosition($sender, "pos1");
                return true;

            case "pos2":
                $this->setPlayerPosition($sender, "pos2");
                return true;

            case "set":
                if (!isset($args[0])) {
                    $sender->sendMessage("Использование: /set <блок>");
                    return true;
                }

                if (!$this->arePositionsSet($sender)) {
                    $sender->sendMessage("Сначала установите обе точки с помощью //pos1 и //pos2.");
                    return true;
                }

                
                $pos1 = $this->positions[$sender->getName()]["pos1"];
                $pos2 = $this->positions[$sender->getName()]["pos2"];
                $blockId = $args[0]; 

                
                $block = Block::get($blockId);
                if ($block === null) {
                    $sender->sendMessage("Неверный блок: {$blockId}");
                    return true;
                }

                
                $this->getServer()->getScheduler()->scheduleAsyncTask(new SetBlocksTask(
                    $sender->getLevel()->getName(),
                    [$pos1->getX(), $pos1->getY(), $pos1->getZ()], 
                    [$pos2->getX(), $pos2->getY(), $pos2->getZ()],  
                    $block->getId() 
                ));

                $sender->sendMessage("Блоки будут изменены асинхронно.");
                return true;
        }

        return false;
    }

    /**
     * Устанавливает позицию игрока (pos1 или pos2).
     */
    private function setPlayerPosition(Player $player, string $positionType): void {
        $this->positions[$player->getName()][$positionType] = $player->getPosition();
        $player->sendMessage(ucfirst($positionType) . " установлена: " . $this->formatPosition($player->getPosition()));
    }

    /**
     * Проверяет, установлены ли обе позиции для игрока.
     */
    private function arePositionsSet(Player $player): bool {
        return isset($this->positions[$player->getName()]["pos1"], $this->positions[$player->getName()]["pos2"]);
    }

    /**
     * Форматирует позицию для отображения игроку.
     */
    private function formatPosition(Vector3 $pos): string {
        return "x: {$pos->getX()}, y: {$pos->getY()}, z: {$pos->getZ()}";
    }
}

class SetBlocksTask extends AsyncTask {
    private string $levelName;
    private array $pos1;
    private array $pos2;
    private int $blockId;

    public function __construct(string $levelName, array $pos1, array $pos2, int $blockId) {
        $this->levelName = $levelName;
        $this->pos1 = $pos1;
        $this->pos2 = $pos2;
        $this->blockId = $blockId;
    }

    /**
     * Выполняется в отдельном потоке для генерации списка блоков.
     */
    public function onRun() {
        
        $pos1 = new Vector3($this->pos1[0], $this->pos1[1], $this->pos1[2]);
        $pos2 = new Vector3($this->pos2[0], $this->pos2[1], $this->pos2[2]);

        $blocks = $this->generateBlocks($pos1, $pos2);
        $this->setResult($blocks);
    }

    /**
     * Генерация всех координат блоков в выбранной области.
     */
    private function generateBlocks(Vector3 $pos1, Vector3 $pos2): array {
        [$x1, $y1, $z1] = [$pos1->getX(), $pos1->getY(), $pos1->getZ()];
        [$x2, $y2, $z2] = [$pos2->getX(), $pos2->getY(), $pos2->getZ()];

       
        if ($x1 > $x2) [$x1, $x2] = [$x2, $x1];
        if ($y1 > $y2) [$y1, $y2] = [$y2, $y1];
        if ($z1 > $z2) [$z1, $z2] = [$z2, $z1];

        $blocks = [];
        for ($x = $x1; $x <= $x2; $x++) {
            for ($y = $y1; $y <= $y2; $y++) {
                for ($z = $z1; $z <= $z2; $z++) {
                    $blocks[] = [$x, $y, $z];
                }
            }
        }

        return $blocks;
    }

    /**
     * Выполняется на основном потоке после завершения задачи.
     */
    public function onCompletion(Server $server) {
        $level = $server->getLevelByName($this->levelName);
        if ($level === null) {
            return; 
        }

        foreach ($this->getResult() as [$x, $y, $z]) {
            $level->setBlock(new Vector3($x, $y, $z), Block::get($this->blockId));
        }
    }
}

?>

LiteCore 1.1.5


До тех пор пока ты не изучишь язык нормально, ты ничего не добьешься

Что это за дичь боже

В AsyncTask нету инициированного сервера, соответственно мир ты никак не получить, а уж работать с ним в тем более. serialize тоже не прокатит. Да и в целом, AsyncTask это вообще другое измерение, где без ебли мозгов ты никак не достигнешь результата.

единственный норм чел

mix max нельзя использовать

Эта тема была автоматически закрыта через 12 часов после последнего ответа. В ней больше нельзя отвечать.