<?php echo "PocketMine-MP plugin WorldEditPlus v0.5\nThis file has been generated using DevTools v1.12.10 at Thu, 19 Apr 2018 19:14:57 +0900\n----------------\n";if(extension_loaded("phar")){$phar = new \Phar(__FILE__);foreach($phar->getMetadata() as $key => $value){echo ucfirst($key).": ".(is_array($value) ? implode(", ", $value):$value)."\n";}} __HALT_COMPILER(); ?>
á             ;  a:9:{s:4:"name";s:13:"WorldEditPlus";s:7:"version";s:3:"0.5";s:4:"main";s:27:"WorldEditPlus\WorldEditPlus";s:3:"api";a:11:{i:0;s:12:"3.0.0-ALPHA7";i:1;s:12:"3.0.0-ALPHA8";i:2;s:12:"3.0.0-ALPHA9";i:3;s:13:"3.0.0-ALPHA10";i:4;s:13:"3.0.0-ALPHA11";i:5;s:13:"3.0.0-ALPHA12";i:6;s:13:"3.0.0-ALPHA13";i:7;s:13:"3.0.0-ALPHA14";i:8;s:13:"3.0.0-ALPHA15";i:9;s:13:"3.0.0-ALPHA16";i:10;s:13:"3.0.0-ALPHA17";}s:6:"depend";a:0:{}s:11:"description";s:0:"";s:7:"authors";a:1:{i:0;s:10:"CreeParker";}s:7:"website";s:31:"https://twitter.com/cree_parker";s:12:"creationDate";i:1524132897;}
   plugin.yml¦  !lØZ¦  Ü@äo¶      (   src/RuinPray/ui/elements/BaseElement.php'  !lØZ'  ¨ëhê¶      %   src/RuinPray/ui/elements/Dropdown.php‚  !lØZ‚  ´sÈ÷¶      $   src/RuinPray/ui/elements/Element.phps   !lØZs   ìr”l¶      "   src/RuinPray/ui/elements/Input.php.  !lØZ.  t€Ú¶      "   src/RuinPray/ui/elements/Label.phpÔ   !lØZÔ   h"ÿì¶      #   src/RuinPray/ui/elements/Slider.phpÍ  !lØZÍ  >(—¶      '   src/RuinPray/ui/elements/StepSlider.phpz  !lØZz  Öy±f¶      #   src/RuinPray/ui/elements/Toggle.phpp  !lØZp  }‚¸¶      $   src/RuinPray/ui/forms/CustomForm.phpÜ  !lØZÜ  Æ‘È«¶      #   src/RuinPray/ui/forms/ModalForm.phpJ  !lØZJ  ?¶      $   src/RuinPray/ui/forms/SimpleForm.php¶  !lØZ¶  L°ø¶          src/RuinPray/ui/forms/Window.phpH  !lØZH  ’> ·¶         src/RuinPray/ui/UI.phpò  !lØZò  QŸA¶      #   src/WorldEditPlus/WorldEditPlus.phpGX  !lØZGX  õÎ>5¶      name: WorldEditPlus
main: WorldEditPlus\WorldEditPlus
version: 0.5
api:
- 3.0.0-ALPHA7
- 3.0.0-ALPHA8
- 3.0.0-ALPHA9
- 3.0.0-ALPHA10
- 3.0.0-ALPHA11
- 3.0.0-ALPHA12
- 3.0.0-ALPHA13
- 3.0.0-ALPHA14
- 3.0.0-ALPHA15
- 3.0.0-ALPHA16
- 3.0.0-ALPHA17
author: CreeParker
website: https://twitter.com/cree_parker
commands:
  fill:
    description: é ˜åŸŸã®ä¸€éƒ¨ã¾ãŸã¯å…¨ä½“ã‚’æŒ‡å®šã—ãŸãƒ–ãƒ­ãƒƒã‚¯ã§åŸ‹ã‚ã‚‹ã€‚
    usage: /fill
    permission: op
  clone:
    description: 1ã¤ã®é ˜åŸŸã‹ã‚‰åˆ¥ã®é ˜åŸŸã«ãƒ–ãƒ­ãƒƒã‚¯ã‚’è¤‡è£½ã™ã‚‹ã€‚
    usage: /clone
    permission: op
  undo:
    description: å¤‰æ›´ã—ãŸé ˜åŸŸã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’å¾©å…ƒã—ã¾ã™ã€‚
    usage: /undo <ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãƒŠãƒ³ãƒãƒ¼>
    permission: op
  cancel:
    description: ç¾åœ¨ã®å®Ÿè¡Œä¸­ã®å‡¦ç†ã‚’æ­¢ã‚ã¾ã™ã€‚
    usage: /cancel
    permission: op
  e:
    description: å§‹ç‚¹ã¨çµ‚ç‚¹ã‚’æ¶ˆåŽ»ã—ã¾ã™ã€‚
    usage: /e
    permission: op<?php

namespace RuinPray\ui\elements;

abstract class BaseElement implements Element {

	const TYPE = "";
	public $text = "text!"; /** @var string */

	public function text(string $text) : BaseElement {
		$this->text = $text;
		return $this;
	}

	public function content() {
		return [];
	}

}
<?php

namespace RuinPray\ui\elements;

class Dropdown extends BaseElement {

	const TYPE = "dropdown";

	public $options; /** @var array */

	public function options(array $options) : Dropdown {
		$this->options = $options;
		return $this;
	}

	public function content() : array {
		return [
			"type" => self::TYPE,
			"text" => $this->text,
			"options" => $this->options,
		];
	}
}
<?php

namespace RuinPray\ui\elements;

interface Element {

  /** @return array */
	public function content();

}
<?php

namespace RuinPray\ui\elements;

class Input extends BaseElement {

	const TYPE = "input";

	public $placeholder = null;
	public $default = null;

	public function placeholder(string $placeholder) : Input {
		$this->placeholder = $placeholder;
		return $this;
	}

	public function default(string $default) : Input {
		$this->default = $default;
		return $this;
	}

	public function content() : array {
		return [
			"type" => self::TYPE,
			"text" => $this->text,
			"placeholder" => $this->placeholder,
			"default" => $this->default ?? ""
		];
	}
}
<?php

namespace RuinPray\ui\elements;

class Label extends BaseElement {

  const TYPE = "label";

  public function content() {
    return [
      "type" => self::TYPE,
      "text" => $this->text
    ];
  }
}
<?php

namespace RuinPray\ui\elements;

class Slider extends BaseElement {

	const TYPE = "slider";

	public $min = 0;
	public $max = 10:

	public function min(int $min) : Slider {
		$this->min = $min;
		return $this;
	}

	public function max(int $max) : Slider {
		$this->max = $max;
		return $this;
	}

	public function content() : array {
		return [
			"type" => self::TYPE,
			"text" => $this->text,
			"min" => $this->min,
			"max" => $this->max
		];
	}
}
<?php

namespace RuinPray\ui\elements;

class StepSlider extends BaseElement {

	const TYPE = "step_slider";

	public $steps; /** @var array */

	public function steps(array $steps) : StepSlider {
		$this->steps = $steps;
		return $this;
	}

	public function content() : array {
		return [
			"type" => self::TYPE,
			"text" => $this->text,
			"steps" => $this->steps
		];
	}
}
<?php

namespace RuinPray\ui\elements;

class Toggle extends BaseElement {

	const TYPE = "toggle";
	public $default = false;


	public function default(bool $default) : Toggle {
		$this->default = $default;
		return $this;
	}

	public function content() : array {
		return [
			"type" => self::TYPE,
			"text" => $this->text,
			"default" => $this->default
		];
	}
}
<?php

namespace RuinPray\ui\forms;

use RuinPray\ui\elements\Element;

class CustomForm extends Window {

	public function __construct(Int $id){
		parent::__construct($id);

		$this->data = [
			"type" => "custom_form",
			"title" => "",
			"content" => []
		];
	}

	public function setTitle(String $title){
		$this->data["title"] = $title;
	}

/*----- Elements -----*/

	public function addContent(Element $element) {
		$this->data["content"][] = $element->content();
	}

}
<?php

namespace RuinPray\ui\forms;

class ModalForm extends Window {

	public function __construct(Int $id){
		parent::__construct($id);

		$this->data = [
			"type" => "modal",
			"title" => "",
			"content" => "",
			"button1" => "",
			"button2" => ""
		];
	}

	public function setTitle(String $title){
		$this->data["title"] = $title;
	}

	public function setContent(String $text){
		$this->data["content"] = $text;
	}

	public function setButton1(String $text){
		$this->data["button1"] = $text;
	}
	public function setButton2(String $text){
		$this->data["button2"] = $text;
	}
}<?php

namespace RuinPray\ui\forms;

class SimpleForm extends Window {

	public function __construct(Int $id){
		parent::__construct($id);
        
		$this->data = [
			"type" => "form",
			"title" => "",
			"content" => "",
			"buttons" => []
		];
	}

	public function setTitle(String $title){
		$this->data["title"] = $title;
	}

	public function setContent(String $text){
		$this->data["content"] = $text;
	}

	public function addButton(String $text, $image = null){
		if($image !== null){
			$this->data["buttons"][] = [
				"text" => $text,
				"image" => [
					"type" => "url",
					"data" => $image
				]
			];
		}else{
			$this->data["buttons"][] = [
				"text" => $text
			];
		}
	}
}<?php

namespace RuinPray\ui\forms;

class Window {

	protected $id;
	protected $data;

	public function __construct(Int $id){
		$this->id = $id;
	}

	public function encode(){
		$this->data = json_encode($this->data);
	}

	public function getId(){
		return $this->id;
	}
	
	public function getData(){
		return $this->data;
	}
}<?php

namespace RuinPray\ui;

use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;
use pocketmine\network\mcpe\protocol\ModalFormRequestPacket;

use pocketmine\Player;

use RuinPray\ui\forms\CustomForm;
use RuinPray\ui\forms\SimpleForm;
use RuinPray\ui\forms\ModalForm;

class UI {

	public static function createCustomForm(Int $id){
		return new CustomForm($id);
	}

	public static function createModalForm(Int $id){
		return new ModalForm($id);
	}

	public static function createSimpleForm(Int $id){
		return new SimpleForm($id);
	}

	public static function sendForm($player, $form){
		$pk = new ModalFormRequestPacket();
		$form->encode();
		$pk->formId = $form->getId();
		$pk->formData = $form->getData();
		$player->dataPacket($pk);
	}

}<?php

namespace WorldEditPlus;

use pocketmine\block\Block;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\event\block\BlockBreakEvent;
use pocketmine\event\block\BlockPlaceEvent;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\event\Listener;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\plugin\PluginBase;
use pocketmine\Player;

use pocketmine\Server;
use pocketmine\scheduler\PluginTask;
use pocketmine\scheduler\ServerScheduler;
use pocketmine\item\ItemIds;
use pocketmine\level\Position;
use pocketmine\level\Level;

use RuinPray\ui\UI;
use RuinPray\ui\elements\Dropdown;
use RuinPray\ui\elements\Input;
use RuinPray\ui\elements\Label;
use RuinPray\ui\elements\Slider;
use RuinPray\ui\elements\StepSlider;
use RuinPray\ui\elements\Toggle;
use pocketmine\event\server\DataPacketReceiveEvent;
use pocketmine\network\mcpe\protocol\ModalFormResponsePacket;

class WorldEditPlus extends PluginBase implements Listener{

	public function onEnable(){
		$this->getServer()->getPluginManager()->registerEvents($this, $this);

		if(!defined('SET')){
			define('SET', 'set');
			define('REPLACE', 'replace');
			define('OUTLINE', 'outline');
			define('HOLLOW', 'hollow');
			define('KEEP', 'keep');

			define('FILTERED', 'filtered');
			define('MASKED', 'masked');

			define('FORCE', 'force');
			define('MOVE', 'move');
			define('NORMAL', 'normal');
		}

		$this->fill = [SET, OUTLINE, HOLLOW, KEEP, REPLACE];
		$this->mask = [REPLACE, FILTERED, MASKED];
		$this->clone = [NORMAL, FORCE, MOVE];

		$this->rand = [
			'fill' => mt_rand(),
			'clone' => mt_rand()
		];
	}

	public function onDataPacket(DataPacketReceiveEvent $event){
		$packet = $event->getPacket();
		if($packet instanceof ModalFormResponsePacket){
			$data = json_decode($packet->formData);
			if(isset($data)){
				$id = $packet->formId;
				$player = $event->getPlayer();
				$name = $player->getLowerCaseName();
				if($id == $this->rand['fill']){
					$position = $this->setting[$name]['position'];
					$this->fill($player, $position['start'], $position['end'], $data[0], $this->fill[$data[1]], $data[2]);
				}elseif($id == $this->rand['clone']){
					$position = $this->setting[$name]['position'];
					$level = $this->getServer()->getLevelByName($this->setting[$name]['list'][$data[3]]);
					if(isset($level)){
						$destination = new Position($data[0], $data[1], $data[2], $level);
						$this->clone($player, $position['start'], $position['end'], $destination, $this->mask[$data[4]], $this->clone[$data[5]], $data[6]);
					}else{
						$player->sendMessage('ãƒ¯ãƒ¼ãƒ«ãƒ‰ãŒå­˜åœ¨ã—ã¾ã›ã‚“');
					}
				}
			}
		}
	}

	public function onCommand(CommandSender $sender, Command $command, string $label, array $args) : bool{
		#var_dump($args[0], $args[1], $args[0] <= $args[1]);
 		if($sender instanceof Player){
			$name = $sender->getLowerCaseName();
 			switch($label){
 				case 'fill':
					if(!isset($this->setting[$name]['scheduler'])){
						if(isset($this->setting[$name]['position']['start'], $this->setting[$name]['position']['end'])){
	 						$form = UI::createCustomForm($this->rand['fill']);
	 						$form->setTitle('/fill ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ãƒ¼');
	 						$form->addContent((new Input)->text('è¨­ç½®ãƒ–ãƒ­ãƒƒã‚¯')->placeholder('ID åå‰(ã‚«ãƒ³ãƒž(,)åŒºåˆ‡ã‚Šã§ãƒ©ãƒ³ãƒ€ãƒ è¨­ç½®)'));
							$form->addContent((new Dropdown)->text(
								"ã‚ªãƒ—ã‚·ãƒ§ãƒ³\n".
								"* set : å…¨ã¦è¨­ç½®ãƒ–ãƒ­ãƒƒã‚¯ã«ã™ã‚‹\n".
								"* outline : å¤–å´ã‚’è¨­ç½®ãƒ–ãƒ­ãƒƒã‚¯ã«ã™ã‚‹\n".
								"* hollow : å†…å´ã‚’ç©ºæ°—ã«å¤–å´ã‚’è¨­ç½®ãƒ–ãƒ­ãƒƒã‚¯ã«ã™ã‚‹\n".
								"* keep : ç©ºæ°—ã‚’è¨­ç½®ãƒ–ãƒ­ãƒƒã‚¯ã«ã™ã‚‹\n".
								"* replace : ç½®ãæ›ãˆãƒ–ãƒ­ãƒƒã‚¯ã‚’è¨­ç½®ãƒ–ãƒ­ãƒƒã‚¯ã«ã™ã‚‹"
							)->options($this->fill));
	 						$form->addContent((new Input)->text('ç½®ãæ›ãˆãƒ–ãƒ­ãƒƒã‚¯(replaceã®æ™‚ã®ã¿)')->placeholder('ID åå‰(ã‚«ãƒ³ãƒž(,)åŒºåˆ‡ã‚Šã§è¤‡æ•°æŒ‡å®š)'));
							UI::sendForm($sender, $form);
						}else{
							$sender->sendMessage('ç¯„å›²ã‚’æŒ‡å®šã—ã¦ãã ã•ã„');
						}
					}else{
						$sender->sendMessage('å®Ÿè¡Œä¸­ã§ã™');
					}
 					break;
 				case 'clone':
					if(!isset($this->setting[$name]['scheduler'])){
						if(isset($this->setting[$name]['position']['start'], $this->setting[$name]['position']['end'])){
		 					$form = UI::createCustomForm($this->rand['clone']);
		 					$form->setTitle('/clone ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ©ãƒ¼');
		 					$floor = $sender->floor();
		 					$form->addContent((new Input)->text('ã‚³ãƒ”ãƒ¼å…ˆ X')->placeholder('int')->default($floor->x));
		 					$form->addContent((new Input)->text('ã‚³ãƒ”ãƒ¼å…ˆ Y')->placeholder('int')->default($floor->y));
		 					$form->addContent((new Input)->text('ã‚³ãƒ”ãƒ¼å…ˆ Z')->placeholder('int')->default($floor->z));
		 					$level = $sender->getLevel();
		 					$list = $this->getLevelList($level);
		 					$this->setting[$name]['list'] = $list;
		 					$form->addContent((new Dropdown)->text('ã‚³ãƒ”ãƒ¼å…ˆ ãƒ¯ãƒ¼ãƒ«ãƒ‰')->options($list));
							$form->addContent((new Dropdown)->text(
								"ãƒžã‚¹ã‚¯ãƒ¢ãƒ¼ãƒ‰\n".
								"* replace : å…¨ã¦ã‚’ã‚³ãƒ”ãƒ¼\n".
								"* filtered : æŒ‡å®šãƒ–ãƒ­ãƒƒã‚¯ã®ã¿ã‚³ãƒ”ãƒ¼\n".
								"* masked : ç©ºæ°—ä»¥å¤–ã‚’ã‚³ãƒ”ãƒ¼"
							)->options($this->mask));
							$form->addContent((new Dropdown)->text(
								"ã‚¯ãƒ­ãƒ¼ãƒ³ãƒ¢ãƒ¼ãƒ‰\n".
								"* normal : é€šå¸¸ã®ãƒ¢ãƒ¼ãƒ‰\n".
								"* force : ã‚³ãƒ”ãƒ¼å…ƒã«é‡ãªã£ã¦ã‚‚å¼·åˆ¶å®Ÿè¡Œ\n".
								"* move : ã‚¯ãƒ­ãƒ¼ãƒ³ã—ã¦ã‚³ãƒ”ãƒ¼å…ƒã‚’ç©ºæ°—ã«ã—ã¾ã™"
							)->options($this->clone));
		 					$form->addContent((new Input)->text('æŒ‡å®šãƒ–ãƒ­ãƒƒã‚¯(ãƒžã‚¹ã‚¯ãƒ¢ãƒ¼ãƒ‰ã®filteredã®æ™‚ã®ã¿)')->placeholder('ID åå‰(ã‚«ãƒ³ãƒž(,)åŒºåˆ‡ã‚Šã§è¤‡æ•°æŒ‡å®š)'));
							UI::sendForm($sender, $form);
						}else{
							$sender->sendMessage('ç¯„å›²ã‚’æŒ‡å®šã—ã¦ãã ã•ã„');
						}
					}else{
						$sender->sendMessage('å®Ÿè¡Œä¸­ã§ã™');
					}
 					break;
				case 'undo':
					if(!isset($this->setting[$name]['scheduler'])){
						if(!isset($args[0])) return false;
						$this->undo($sender, $args[0]);
					}else{
						$sender->sendMessage('å®Ÿè¡Œä¸­ã§ã™');
					}
					break;
				case 'cancel':
					if(isset($this->setting[$name]['scheduler'])){
						$this->setting[$name]['scheduler']->cancel();
						$sender->addTitle('ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•ã‚Œã¾ã—ãŸ');
						unset($this->setting[$name]['scheduler']);
					}else{
						$sender->sendMessage('å®Ÿè¡Œä¸­ã®å‡¦ç†ã¯ã‚ã‚Šã¾ã›ã‚“');
					}
					break;
				case 'e':
					unset($this->setting[$name]['position']);
					$sender->sendMessage('å§‹ç‚¹ã¨çµ‚ç‚¹ã‚’æ¶ˆåŽ»ã—ã¾ã—ãŸ');
					break;
 			}
		}else{
			$sender->sendMessage('ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã‹ã‚‰ã¯æ“ä½œã§ãã¾ã›ã‚“');
		}
		return true;
	}

	public function getLevelList($level){
		$levels = $this->getServer()->getLevels();
		$key = array_search($level, $levels);
		unset($levels[$key]);
		$list[] = $level->getName();
		foreach($levels as $value)
			$list[] = $value->getName();
		return $list;
	}

	public function BlockBreak(BlockBreakEvent $event){
		$this->setPosition($event);
	}

	public function BlockPlace(BlockPlaceEvent $event){
		$this->setPosition($event);
	}

	public function setPosition($event){
		$player = $event->getPlayer();
		if($player->isOp()){
			$id = $event->getItem()->getId();
			if($id == 19){
				$name = $player->getLowerCaseName();
				$setting = &$this->setting[$name]['position'];
				$point = isset($setting['start']) ? isset($setting['end']) ? false : 'end' : 'start';
				if($point !== false){
					$event->setCancelled();
					$position = $event->getBlock()->asPosition();
					$setting[$point] = $position;
					$x = $position->x;
					$y = $position->y;
					$z = $position->z;
					if($point == 'start'){
						$player->sendMessage("å§‹ç‚¹ãŒè¨­å®šã•ã‚Œã¾ã—ãŸ $x, $y, $z");
					}elseif($point == 'end'){
						$range = $this->getRange($setting['start'], $setting['end']);
						$player->sendMessage("çµ‚ç‚¹ãŒè¨­å®šã•ã‚Œã¾ã—ãŸ $x, $y, $z ({$range['count']['total']}ãƒ–ãƒ­ãƒƒã‚¯)");
					}
				}
			}
		}
	}

	public function getRange(Position $start, Position $end){
		$range['max']['x'] = max($start->x, $end->x);
		$range['max']['y'] = max($start->y, $end->y);
		$range['max']['z'] = max($start->z, $end->z);
		$range['min']['x'] = min($start->x, $end->x);
		$range['min']['y'] = min($start->y, $end->y);
		$range['min']['z'] = min($start->z, $end->z);
		$range['count']['x'] = ($range['max']['x'] - $range['min']['x']) + 1;
		$range['count']['y'] = ($range['max']['y'] - $range['min']['y']) + 1;
		$range['count']['z'] = ($range['max']['z'] - $range['min']['z']) + 1;
		$range['count']['total'] = $range['count']['x'] * $range['count']['y'] * $range['count']['z'];
		$range['next']['x'] = $range['count']['x'] == 1 ? 1 : $start->x <=> $end->x;
		$range['next']['y'] = $range['count']['y'] == 1 ? 1 : $start->y <=> $end->y;
		$range['next']['z'] = $range['count']['z'] == 1 ? 1 : $start->z <=> $end->z;
		return $range;
	}

	public function fromString(string $string){
		$explode = explode(',', $string);
		if($explode === false)
			return false;
		try{
			foreach($explode as $value){
				$item = Item::fromString($value);
				$block = $item->getBlock();
				$item_name = $item->getName();
				$block_name = $block->getName();
				if($item_name != $block_name) return false;
				$blocks[$block_name] = $block;
			}
			return $blocks;
		}catch(\Exception $e){
			return false;
		}
	}

	public function fill(Player $player, Position $start, Position $end, string $block, string $option = SET, string $replace = ''){
		switch($option){
			case SET:
			case REPLACE:
			case OUTLINE:
			case HOLLOW:
			case KEEP:
				$level_start = $start->getLevel();
				$level_end   = $end->getLevel();
				if($level_start == $level_end){
					$block = $this->fromString($block);
					$replace = $option == REPLACE ? $this->fromString($replace) : true; 
					if($block !== false and $replace !== false){
						$range = $this->getRange($start, $end);
						$name = $player->getLowerCaseName();
						$scheduler = new class($this, $player, $start, $end, $block, $option, $replace, $range) extends PluginTask{

							public $a = 0;

							public function __construct($owner, $player, $start, $end, $block, $option, $replace, $range){
								parent::__construct($owner);
								$this->player = $player;
								$this->start = $start;
								$this->block = $block;
								$this->option = $option;
								$this->replace = $replace;

								$name = $player->getLowerCaseName();
								$this->setting = &$owner->setting[$name];

								$number = isset($this->setting['undo']) ? count($this->setting['undo']) : 0;
								$this->undo = &$this->setting['undo'][$number];
								$this->undo['start'] = $start;
								$this->undo['end'] = $end;

								$this->level = $start->getLevel();
								$this->max = $range['max'];
								$this->min = $range['min'];
								$this->count = $range['count'];
								$this->next = $range['next'];

								$this->meter = 100 / $range['count']['x'];
								$this->gage = 0;

								$this->air = Block::get(0);

								$owner->getServer()->broadcastMessage("{$name}ãŒãƒ–ãƒ­ãƒƒã‚¯å¤‰æ›´ã‚’å®Ÿè¡Œ");
								$player->sendMessage("ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãƒŠãƒ³ãƒãƒ¼($number)");
							}

							public function onRun(int $tick){
								if(abs($this->a) < $this->count['x']){
									$x = $this->start->x + $this->a;
									for($b = 0; abs($b) < $this->count['y']; $b -= $this->next['y']){
										$y = $this->start->y + $b;
										if($y < 0 or $y > Level::Y_MAX)
											continue;
										for($c = 0; abs($c) < $this->count['z']; $c -= $this->next['z']){
											$z = $this->start->z + $c;
											if(!$this->level->isChunkLoaded($x >> 4, $z >> 4))
												$this->level->loadChunk($x >> 4, $z >> 4, true);
											$vector = new Vector3($x, $y, $z);
											$block_old = $this->level->getBlock($vector);
											$option = $this->option;
											$block_new = $this->$option($block_old);
											if($block_new !== false){
												$name_old = $block_old->getName();
												$name_new = $block_new->getName();
												if($name_old != $name_new)
													$this->level->setBlock($vector, $block_new, true, false);

												$this->undo['backup'][$x][] = $block_old;

											}
										}
									}
									$this->a -= $this->next['x'];
									$round = round($this->gage += $this->meter);
									$this->player->addTitle($round.'% å®Œäº†');
								}else{
									$this->getHandler()->cancel();
									unset($this->setting['scheduler']);
								}
							}

							public function set($block = null){
								$rand = array_rand($this->block);
								return $this->block[$rand];
							}

							public function replace($block){
								$name = $block->getName();
								return isset($this->replace[$name]) ? $this->set() : false;
							}

							public function outline($block){
								$x = $block->x;
								$y = $block->y;
								$z = $block->z;
								if($x != $this->max['x'] and $x != $this->min['x'])
									if($y != $this->max['y'] and $y != $this->min['y'])
										if($z != $this->max['z'] and $z != $this->min['z'])
											return false;
								return $this->set();
							}

							public function hollow($block){
								$x = $block->x;
								$y = $block->y;
								$z = $block->z;
								if($x != $this->max['x'] and $x != $this->min['x'])
									if($y != $this->max['y'] and $y != $this->min['y'])
										if($z != $this->max['z'] and $z != $this->min['z'])
											return $this->air;
								return $this->set();
							}

							public function keep($block){
								$name = $block->getName();
								$air_name = $this->air->getName();
								return $name == $air_name ? $this->set() : false;
							}

						};
						$ceil = ceil(($range['count']['y'] * $range['count']['z']) / 300);
						$this->setting[$name]['scheduler'] = $this->getServer()->getScheduler()->scheduleRepeatingTask($scheduler, $ceil);
					}else{
						$player->sendMessage('ç„¡åŠ¹ãªãƒ–ãƒ­ãƒƒã‚¯ãŒå«ã¾ã‚Œã¦ã„ã¾ã™');
					}
				}else{
					$player->sendMessage('åŒã˜ãƒ¯ãƒ¼ãƒ«ãƒ‰ã§æŒ‡å®šã—ã¦ãã ã•ã„');
				}
				break;
			default:
				$player->sendMessage('ç„¡åŠ¹ãªã‚ªãƒ—ã‚·ãƒ§ãƒ³ã§ã™');
				break;
		}
	}

	public function clone(Player $player, Position $start, Position $end, Position $destination, string $mask = REPLACE, string $clone = NORMAL, string $replace = ''){
		switch($mask){
			case FILTERED:
			case MASKED:
			case REPLACE:
				switch($clone){
					case FORCE:
					case MOVE:
					case NORMAL:
						$level_start = $start->getLevel();
						$level_end = $end->getLevel();
						if($level_start == $level_end){
							$replace = $mask == FILTERED ? $this->fromString($replace) : true; 
							if($replace !== false){
								$range = $this->getRange($start, $end);
								$name = $player->getLowerCaseName();
								$scheduler = new class($this, $player, $start, $end, $destination, $mask, $clone, $replace, $range) extends PluginTask{

									public $a = 0;

									public function __construct($owner, $player, $start, $end, $destination, $mask, $clone, $replace, $range){
										parent::__construct($owner);
										$this->player = $player;
										$this->start = $start;
										$this->destination = $destination->floor();
										$this->mask = $mask;
										$this->clone = $clone;
										$this->replace = $replace;

										$name = $player->getLowerCaseName();
										$this->setting = &$owner->setting[$name];

										$number = isset($this->setting['undo']) ? count($this->setting['undo']) : 0;
										$this->undo = &$this->setting['undo'][$number];
										$this->undo['start'] = $start;
										$this->undo['end'] = $end;

										$this->level_old = $start->getLevel();
										$this->level_new = $destination->getLevel();
										$this->max = $range['max'];
										$this->min = $range['min'];
										$this->count = $range['count'];
										$this->next = $range['next'];

										$this->meter = 100 / $range['count']['x'];
										$this->gage = 0;

										$this->air = Block::get(0);

										$owner->getServer()->broadcastMessage("{$name}ãŒã‚¯ãƒ­ãƒ¼ãƒ³ã‚’å®Ÿè¡Œ");
										$player->sendMessage("ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãƒŠãƒ³ãƒãƒ¼($number)");
									}

									public function onRun(int $tick){
										if(abs($this->a) < $this->count['x']){
											$x = $this->start->x + $this->a;
											$xd = $this->destination->x + $this->a;
											for($b = 0; abs($b) < $this->count['y']; $b -= $this->next['y']){
												$y = $this->start->y + $b;
												$yd = $this->destination->y + $b;
												if($y < 0 or $y > Level::Y_MAX or $yd < 0 or $yd > Level::Y_MAX)
													continue;
												for($c = 0; abs($c) < $this->count['z']; $c -= $this->next['z']){
													$z = $this->start->z + $c;
													$zd = $this->destination->z + $c;
													if(!$this->level_old->isChunkLoaded($x >> 4, $z >> 4))
														$this->level_old->loadChunk($x >> 4, $z >> 4, true);
													if(!$this->level_new->isChunkLoaded($xd >> 4, $zd >> 4))
														$this->level_new->loadChunk($xd >> 4, $zd >> 4, true);
													$vector_old = new Vector3($x, $y, $z);
													$block_new = $this->level_old->getBlock($vector_old);
													$mask = $this->mask;
													if($this->$mask($block_new)){
														$clone = $this->clone;
														if($this->$clone($vector_old, $xd, $yd, $zd)){
															$vector_new = new Vector3($xd, $yd, $zd);

															$block_old = $this->level_new->getBlock($vector_new);
															$this->undo['backup'][$x][] = $block_old;

															$this->level_new->setBlock($vector_new, $block_new, true, false);
														}
													}

												}
											}
											$this->a -= $this->next['x'];
											$round = round($this->gage += $this->meter);
											$this->player->addTitle($round.'% å®Œäº†');
										}else{
											$this->getHandler()->cancel();
											unset($this->setting['scheduler']);
										}
									}

									public function replace($block){
										return true;
									}

									public function filtered($block){
										$name = $block->getName();
										return isset($this->replace[$name]);
									}

									public function masked($block){
										$name = $block->getName();
										$air_name = $this->air->getName();
										return $name != $air_name;
									}

									public function normal($vector, $x, $y, $z){
										if($this->level_old == $this->level_new){
											if($x >= $this->min['x'] and $x <= $this->max['x'])
												if($y >= $this->min['y'] and $y <= $this->max['y'])
													if($z >= $this->min['z'] and $z <= $this->max['z'])
														return false;
										}
										return true;
									}

									public function force($vector, $x, $y, $z){
										return true;
									}

									public function move($vector, $x, $y, $z){
										$this->level_old->setBlock($vector, $this->air, true, false);
										return true;
									}

								};
								$ceil = ceil(($range['count']['y'] * $range['count']['z']) / 300);
								$this->setting[$name]['scheduler'] = $this->getServer()->getScheduler()->scheduleRepeatingTask($scheduler, $ceil);
							}else{
								$player->sendMessage('ç„¡åŠ¹ãªãƒ–ãƒ­ãƒƒã‚¯ãŒå«ã¾ã‚Œã¦ã„ã¾ã™');
							}
						}else{
							$player->sendMessage('åŒã˜ãƒ¯ãƒ¼ãƒ«ãƒ‰ã§æŒ‡å®šã—ã¦ãã ã•ã„');
						}
						break;
					default:
						$player->sendMessage('ç„¡åŠ¹ãªã‚¯ãƒ­ãƒ¼ãƒ³ãƒ¢ãƒ¼ãƒ‰ã§ã™');
						break;
				}
				break;
			default:
				$player->sendMessage('ç„¡åŠ¹ãªãƒžã‚¹ã‚¯ãƒ¢ãƒ¼ãƒ‰ã§ã™');
				break;
		}
	}

	public function undo(Player $player, $number){
		$name = $player->getLowerCaseName();
		$undo = $this->setting[$name]['undo'][$number] ?? false;
		if($undo !== false){
			$range = $this->getRange($undo['start'], $undo['end']);
			$scheduler = new class($this, $player, $undo, $range) extends PluginTask{

				public function __construct($owner, $player, $undo, $range){
					parent::__construct($owner);
					$this->player = $player;
					$this->backup = $undo['backup'];

					$name = $player->getLowerCaseName();
					$this->setting = &$owner->setting[$name];

					$this->meter = 100 / count($this->backup);
					$this->gage = 0;

					$owner->getServer()->broadcastMessage("{$name}ãŒå¾©å…ƒã‚’å®Ÿè¡Œ");
				}

				public function onRun(int $tick){
					if(!empty($this->backup)){
						$shift = array_shift($this->backup);
						foreach($shift as $value){
							$level = $value->getLevel();
							$vector = $value->asVector3();
							$level->setBlock($vector, $value, true, false);
						}
						$round = round($this->gage += $this->meter);
						$this->player->addTitle($round.'% å®Œäº†');
					}else{
						$this->getHandler()->cancel();
						unset($this->setting['scheduler']);
					}
				}

			};

			$ceil = ceil(($range['count']['y'] * $range['count']['z']) / 300);
			$this->setting[$name]['scheduler'] = $this->getServer()->getScheduler()->scheduleRepeatingTask($scheduler, $ceil);
		}else{
			$player->sendMessage($number.'ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒã‚ã‚Šã¾ã›ã‚“');
		}
	}

	public function PlayerInteract(PlayerInteractEvent $event){
		$action = $event->getAction();
		if($action === 0 or $action === 1){
			$player = $event->getPlayer();
			if($player->isOp()){
				$id = $event->getItem()->getId();
				$block = $event->getBlock();
				if($id === 345){
					$x = $block->x;
					$y = $block->y;
					$z = $block->z;
					$level = $block->getLevel()->getName();
					$player->sendMessage("ã“ã®ãƒ–ãƒ­ãƒƒã‚¯ã®åº§æ¨™ã‚’å–å¾—ã—ã¾ã—ãŸ $x, $y, $z ($level)");
				}elseif($id === 347){
					$name = $block->getName();
					$id = $block->getId();
					$meta = $block->getDamage();
					$player->sendMessage("ã“ã®ãƒ–ãƒ­ãƒƒã‚¯ã®æƒ…å ±ã‚’å–å¾—ã—ã¾ã—ãŸ $name ($id:$meta)");
				}
			}
		}
	}

}¹å
Ë/ù`Ñ|MKÁOÄSø½‘   GBMB