
<?php
echo "PocketMine-MP plugin WorldEditPlus v3.1
This file has been generated using DevTools v1.13.0 at Sun, 10 Feb 2019 01:37:19 +1030
----------------
";

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(); ?>
             6  a:9:{s:4:"name";s:13:"WorldEditPlus";s:7:"version";d:3.1;s:4:"main";s:27:"WorldEditPlus\WorldEditPlus";s:3:"api";a:2:{i:0;s:5:"3.0.0";i:1;s:5:"4.0.0";}s:6:"depend";s:0:"";s:11:"description";s:0:"";s:7:"authors";s:0:"";s:7:"website";s:36:"https://forum.mcbe.jp/resources/107/";s:12:"creationDate";i:1549724839;}   LICENSE@  ¨ì^\@  쟛޶      
   plugin.yml«   ¨ì^\«   ·,Pb¶      	   README.md  ¨ì^\  ¥ܒþ¶         resources/config.ymlý  ¨ì^\ý  6ôAŒ¶         resources/languages/jpn.ini¥  ¨ì^\¥  ­£¨¶      2   src/WorldEditPlus/command/defaults/BookCommand.php.  ¨ì^\.  ˆ—~”¶      4   src/WorldEditPlus/command/defaults/CancelCommand.phpj  ¨ì^\j  6à-›¶      3   src/WorldEditPlus/command/defaults/CloneCommand.php³  ¨ì^\³  Äᇀ¶      6   src/WorldEditPlus/command/defaults/CylinderCommand.phpà  ¨ì^\à  ‚P�~¶      2   src/WorldEditPlus/command/defaults/FillCommand.phpv  ¨ì^\v  R7‚!¶      2   src/WorldEditPlus/command/defaults/Pos1Command.php!  ¨ì^\!  tlÇ%¶      2   src/WorldEditPlus/command/defaults/Pos2Command.php#  ¨ì^\#  ‹$¶      4   src/WorldEditPlus/command/defaults/SphereCommand.php4  ¨ì^\4  àv´¶      2   src/WorldEditPlus/command/defaults/WandCommand.phpr  ¨ì^\r  Á­>¶      2   src/WorldEditPlus/command/WorldEditPlusCommand.php¨  ¨ì^\¨  ûü±ø¶      #   src/WorldEditPlus/EventListener.phpq  ¨ì^\q  +y ‚¶         src/WorldEditPlus/Language.phpà  ¨ì^\à  zܱK¶      !   src/WorldEditPlus/level/Range.phpU  ¨ì^\U  ï?X¼¶      ,   src/WorldEditPlus/processing/BackUpClass.php[  ¨ì^\[  £`¶      9   src/WorldEditPlus/processing/defaults/CloneProcessing.php	  ¨ì^\	  ùC?‹¶      <   src/WorldEditPlus/processing/defaults/CylinderProcessing.phpÓ  ¨ì^\Ó  ùxöó¶      8   src/WorldEditPlus/processing/defaults/FillProcessing.phpD  ¨ì^\D  ¾qèò¶      :   src/WorldEditPlus/processing/defaults/SphereProcessing.phpï  ¨ì^\ï  w÷¸¶      +   src/WorldEditPlus/processing/Processing.php+  ¨ì^\+  k«¶      #   src/WorldEditPlus/WorldEditPlus.php  ¨ì^\  ÁGí¶      6MIT License

Copyright (c) 2018 CreeParker

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
name: WorldEditPlus
main: WorldEditPlus\WorldEditPlus
version: 3.1
api: [3.0.0, 4.0.0]
author: CreeParker (@cree_parker)
website: https://forum.mcbe.jp/resources/107/# WorldEditPlus

https://forum.mcbe.jp/resources/107/

※ FormAPI is required

FormAPI v1.3.0 (PocketMine-MP) : https://github.com/jojoe77777/FormAPI/releases/tag/1.3.0

FormAPI v1.2.0 (Altay, MiRm) : https://github.com/jojoe77777/FormAPI/releases/tag/1.2.0
# 使用する言語ファイルを選択できます。
# 言語ファイルは「language」フォルダにあります。
# また言語ファイルから文字を変更することができます。
language: "jpn"

# 一度に処理するブロックの量を変えられます。
# 数字が少ないほど鯖への負荷は軽減できますが処理速度が遅くなります。
# 逆に数字が多いほど鯖への負荷が多くなる代わりに処理速度が早くなりますが、
# 負荷が多くなると処理速度に影響がでますのので推奨はしません。
# 基準としては 500～1000 くらいがおススメです。
stopper: 500

# stopperで指定した数のブロックを設置した際に停止する時間を変えれます。
# (1秒÷20)になっていますので 1 だと 0.05秒 になります。
# 秒数を増やすことで複数実行した時の負担を軽減できます。
# 基準としては 1～5 くらいがおススメです。
period: 1; WorldEditPlusに使われている文字をカスタマイズできます。
; /n, /s などの特殊文字は使用できないようにしています。
; §を使った文字は使用できますが、システムに予約されている§に上書きされる可能性があります。
; {%0}や{%1}には名前や座標などが自動入力されます。

; コマンドの説明文
command.fill.description=領域の一部または全体を指定したブロックで埋める。
command.fill.usage=/fill <x1> <y1> <z1> <x2> <y2> <z2> <block> [set|outline|hollow|keep|replace] [block]
command.clone.description=1つの領域から別の領域にブロックを複製する。
command.clone.usage=/clone <x1> <y1> <z1> <x2> <y2> <z2> <x3> <y3> <z3> [replace|filtered|masked] [normal|force|move] [block]
command.cylinder.description=領域に指定したブロックの円柱を作成する。
command.cylinder.usage=/cylinder <x1> <y1> <z1> <x2> <y2> <z2> <block> <x|y|z>
command.sphere.description=領域に指定したブロックの球を作成する。
command.sphere.usage=/sphere <x1> <y1> <z1> <x2> <y2> <z2> <block>
command.cancel.description=指定した番号の処理を停止させます。
command.cancel.usage=/cancel <number>
command.wand.description=始点と終点を決める斧を取り出します。
command.wand.usage=/wand
command.pos1.description=指定した座標を始点に設定します。
command.pos1.usage=/pos1 [x] [y] [z]
command.pos2.description=指定した座標を終点に設定します。
command.pos2.usage=/pos2 [x] [y] [z]
command.book.description=ブロックの情報を調べる本を取り出します。
command.book.usage=/book

; コマンドのメッセージ
command.intval.error=座標の書き方に誤りがあります。
command.cancel=#{%0} {%1}が処理をキャンセルしました。
command.cancel.error=その番号の処理は存在しません。
command.wand=始点と終点を決める斧を取り出しました。
command.book=ブロックの情報を調べる本を取り出しました。
command.console.error=コンソールからは実行できません。

; 実行前のメッセージ
processing.block.one.error=ブロック①でエラーが発生しました。
processing.block.two.error=ブロック②でエラーが発生しました。
processing.level.null.error=Levelオブジェクトが存在しません。
processing.level.error=始点と終点のワールドが違います。

processing.fill.option.error=指定されたオプションが存在しません。
processing.clone.mask.error=指定されたマスクモードが存在しません。
processing.clone.clone.error=指定されたクローンモードが存在しません。
processing.cylinder.direction.error=指定された方向が存在しません。

; 実行後のメッセージ
processing.start=#{%0} {%1}が{%2}を実行しました。 ({%3}ブロック)
processing.end=#{%0} {%1}の{%2}が完了しました。
processing.meter=#{%0} {%1} : {%2} ％ 完了

; wandのメッセージ
wand.name=Wand
wand.description.left=左クリックで始点を設定します。
wand.description.right=右クリックで終点を設定します。
wand.pos1=始点を設定しました。 {%0}, {%1}, {%2} 
wand.pos2=終点を設定しました。 {%0}, {%1}, {%2} 
wand.size=({%0}ブロック)

; ブロック図鑑のメッセージ
book.name=ブロック図鑑
book.description=調べたいブロックを右クリックします。
book.block={%0} ({%1}:{%2}) [{%3}, {%4}, {%5}]

; FormAPIが読み込まれていない時のメッセージ
form.api.error=FormAPIが読み込まれていないのでフォームが使用できません。

; フォームのメッセージ
form.message=コマンドアシスト
form.pos.one.x=始点 X
form.pos.one.y=始点 Y
form.pos.one.z=始点 Z
form.pos.two.x=終点 X
form.pos.two.y=終点 Y
form.pos.two.z=終点 Z
form.block.one=ブロック①
form.block.two=ブロック②

form.option=オプション
form.option.set=* set : 全てをブロック①にする
form.option.outline=* outline : 外側をブロック①にする
form.option.hollow=* hollow : 内側を空気に外側をブロック①にする
form.option.keep=* keep : 空気をブロック①にする
form.option.replace=* replace : ブロック②をブロック①にする

form.pos.clone.x=クローン X
form.pos.clone.y=クローン Y
form.pos.clone.z=クローン Z
form.mask=マスクモード
form.mask.replace=* replace : 全てのブロックをクローンする
form.mask.filtered=* filtered : ブロック①のみクローンする
form.mask.masked=* masked : 空気以外をクローンする
form.clone=クローンモード
form.clone.normal=* normal : コピーする
form.clone.force=* force : コピー元に重なっても強制実行する
form.clone.move=* move : 移動する

form.cylinder.direction=円柱を作成する方向<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\enchantment\EnchantmentInstance;
use pocketmine\item\Item;
use pocketmine\item\ItemIds;
use pocketmine\utils\TextFormat;
use pocketmine\Player;

class BookCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('book', $owner);
		$this->setUsage('command.book.usage');
		$this->setDescription('command.book.description');
		$this->setPermission('worldeditplus.command.book');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if ($sender instanceof Player) {
			$item = Item::get(ItemIds::BOOK);
			$enchant = new EnchantmentInstance(Enchantment::getEnchantment(Enchantment::PROTECTION));
			$item->addEnchantment($enchant);
			$item->setCustomName(Language::get('book.name'));
			$item->setLore([Language::get('book.description')]);
			$sender->getInventory()->addItem($item);
			$sender->sendMessage(Language::get('command.book'));
		} else {
			$sender->sendMessage(TextFormat::RED . Language::get('command.console.error'));
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\processing\Processing;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\Server;

class CancelCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('cancel', $owner);
		$this->setUsage('command.cancel.usage');
		$this->setDescription('command.cancel.description');
		$this->setPermission('worldeditplus.command.cancel');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (! isset($args[0]))
			return false;
		$number = str_replace('#', '', $args[0]);
		$scheduler = Processing::$scheduler[$number] ?? null;
		if ($scheduler !== null) {
			$scheduler->cancel();
			$name = $sender->getName();
			Server::getInstance()->broadcastMessage(Language::get('command.cancel', $number, $name));
		} else {
			$sender->sendMessage(TextFormat::RED . Language::get('command.cancel.error'));
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\level\Range;
use WorldEditPlus\processing\defaults\CloneProcessing;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;
use pocketmine\Server;

class CloneCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('clone', $owner);
		$this->setUsage('command.clone.usage');
		$this->setDescription('command.clone.description');
		$this->setPermission('worldeditplus.command.clone');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (isset($args[0])) {
			if (! isset($args[8]))
				return false;
			if ($this->checkNumber($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6], $args[7], $args[8])) {
				$level = ($sender instanceof Player) ? $sender->getLevel() : Server::getInstance()->getDefaultLevel();
				$pos1 = new Position($args[0], $args[1], $args[2], $level);
				$pos2 = new Position($args[3], $args[4], $args[5], $level);
				$pos3 = new Position($args[6], $args[7], $args[8], $level);
				$args[9] = $args[9] ?? CloneProcessing::MASK[0];
				$args[10] = $args[10] ?? CloneProcessing::CLONE[0];
				$args[11] = $args[11] ?? '';
				$clone = new CloneProcessing($sender, $pos1, $pos2, $pos3, $args[9], $args[10], $args[11]);
				$clone->start();
			} else {
				$sender->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
			}
		} elseif ($sender instanceof Player) {
			$callable = function($player, $data) {
				if (! isset($data))
					return;
				if ($this->checkNumber($data[0], $data[1], $data[2], $data[3], $data[4], $data[5], $data[6], $data[7], $data[8])) {
					$name = $player->getLowerCaseName();
					$level_pos1 = (WorldEditPlus::$pos1[$name] ?? $player)->getLevel();
					$level_pos2 = (WorldEditPlus::$pos2[$name] ?? $player)->getLevel();
					$level_pos3 = $player->getLevel();
					$pos1 = new Position($data[0], $data[1], $data[2], $level_pos1);
					$pos2 = new Position($data[3], $data[4], $data[5], $level_pos2);
					$pos3 = new Position($data[6], $data[7], $data[8], $level_pos3);
					$clone = new CloneProcessing($player, $pos1, $pos2, $pos3, CloneProcessing::MASK[$data[9]], CloneProcessing::CLONE[$data[10]], $data[11]);
					$clone->start();
				} else {
					$player->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
				}
			};
			$form = $this->getDefaultForm($callable, $sender);
			if ($form === null)
				return false;
			$form->addInput(TextFormat::RED . Language::get('form.pos.clone.x'), 'int', (string) Range::changeInteger($sender->x));
			$form->addInput(TextFormat::GREEN . Language::get('form.pos.clone.y'), 'int', (string) Range::changeInteger($sender->y));
			$form->addInput(TextFormat::AQUA . Language::get('form.pos.clone.z'), 'int', (string) Range::changeInteger($sender->z));
			$form->addDropdown(
				Language::get('form.mask') . TextFormat::EOL.
				Language::get('form.mask.replace') . TextFormat::EOL.
				Language::get('form.mask.filtered') . TextFormat::EOL.
				Language::get('form.mask.masked')
			, CloneProcessing::MASK);
			$form->addDropdown(
				Language::get('form.clone') . TextFormat::EOL.
				Language::get('form.clone.normal') . TextFormat::EOL.
				Language::get('form.clone.force') . TextFormat::EOL.
				Language::get('form.clone.move')
			, CloneProcessing::CLONE);
			$form->addInput(Language::get('form.block.one'), 'string');
			$form->sendToPlayer($sender);
		} else {
			return false;
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\processing\defaults\CylinderProcessing;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;
use pocketmine\Server;

class CylinderCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('cylinder', $owner);
		$this->setUsage('command.cylinder.usage');
		$this->setDescription('command.cylinder.description');
		$this->setPermission('worldeditplus.command.cylinder');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (isset($args[0])) {
			if (! isset($args[7]))
				return false;
			if ($this->checkNumber($args[0], $args[1], $args[2], $args[3], $args[4], $args[5])) {
				$level = ($sender instanceof Player) ? $sender->getLevel() : Server::getInstance()->getDefaultLevel();
				$pos1 = new Position($args[0], $args[1], $args[2], $level);
				$pos2 = new Position($args[3], $args[4], $args[5], $level);
				$cylinder = new CylinderProcessing($sender, $pos1, $pos2, $args[6], $args[7]);
				$cylinder->start();
			} else {
				$sender->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
			}
		} elseif ($sender instanceof Player) {
			$callable = function($player, $data) {
				if (! isset($data))
					return;
				if ($this->checkNumber($data[0], $data[1], $data[2], $data[3], $data[4], $data[5])) {
					$name = $player->getLowerCaseName();
					$level_pos1 = (WorldEditPlus::$pos1[$name] ?? $player)->getLevel();
					$level_pos2 = (WorldEditPlus::$pos2[$name] ?? $player)->getLevel();
					$pos1 = new Position($data[0], $data[1], $data[2], $level_pos1);
					$pos2 = new Position($data[3], $data[4], $data[5], $level_pos2);
					$cylinder = new CylinderProcessing($player, $pos1, $pos2, $data[6], CylinderProcessing::DIRECTION[$data[7]]);
					$cylinder->start();
				} else {
					$player->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
				}
			};
			$form = $this->getDefaultForm($callable, $sender);
			if ($form === null)
				return false;
			$form->addInput(Language::get('form.block.one'), 'string');
			$form->addDropdown(Language::get('form.cylinder.direction'), CylinderProcessing::DIRECTION);
			$form->sendToPlayer($sender);
		} else {
			return false;
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\processing\defaults\FillProcessing;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;
use pocketmine\Server;

class FillCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('fill', $owner);
		$this->setUsage('command.fill.usage');
		$this->setDescription('command.fill.description');
		$this->setPermission('worldeditplus.command.fill');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (isset($args[0])) {
			if (! isset($args[6]))
				return false;
			if ($this->checkNumber($args[0], $args[1], $args[2], $args[3], $args[4], $args[5])) {
				$level = ($sender instanceof Player) ? $sender->getLevel() : Server::getInstance()->getDefaultLevel();
				$pos1 = new Position($args[0], $args[1], $args[2], $level);
				$pos2 = new Position($args[3], $args[4], $args[5], $level);
				$args[7] = $args[7] ?? FillProcessing::OPTION[0];
				$args[8] = $args[8] ?? '';
				$fill = new FillProcessing($sender, $pos1, $pos2, $args[6], $args[7], $args[8]);
				$fill->start();
			} else {
				$sender->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
			}
		} elseif ($sender instanceof Player) {
			$callable = function($player, $data) {
				if (! isset($data))
					return;
				if ($this->checkNumber($data[0], $data[1], $data[2], $data[3], $data[4], $data[5])) {
					$name = $player->getLowerCaseName();
					$level_pos1 = (WorldEditPlus::$pos1[$name] ?? $player)->getLevel();
					$level_pos2 = (WorldEditPlus::$pos2[$name] ?? $player)->getLevel();
					$pos1 = new Position($data[0], $data[1], $data[2], $level_pos1);
					$pos2 = new Position($data[3], $data[4], $data[5], $level_pos2);
					$fill = new FillProcessing($player, $pos1, $pos2, $data[6], FillProcessing::OPTION[$data[7]], $data[8]);
					$fill->start();
				} else {
					$player->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
				}
			};
			$form = $this->getDefaultForm($callable, $sender);
			if ($form === null)
				return false;
			$form->addInput(Language::get('form.block.one'), 'string');
			$form->addDropdown(
				Language::get('form.option') . TextFormat::EOL.
				Language::get('form.option.set') . TextFormat::EOL.
				Language::get('form.option.outline') . TextFormat::EOL.
				Language::get('form.option.hollow') . TextFormat::EOL.
				Language::get('form.option.keep') . TextFormat::EOL.
				Language::get('form.option.replace') 
			, FillProcessing::OPTION);
			$form->addInput(Language::get('form.block.two'), 'string');
			$form->sendToPlayer($sender);
		} else {
			return false;
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\EventListener;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;

class Pos1Command extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('pos1', $owner);
		$this->setUsage('command.pos1.usage');
		$this->setDescription('command.pos1.description');
		$this->setPermission('worldeditplus.command.pos1');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (! $sender instanceof Player) {
			$sender->sendMessage(TextFormat::RED . Language::get('command.console.error'));
		} elseif (isset($args[0])) {
			if (! isset($args[2]))
				return false;
			if ($this->checkNumber($args[0], $args[1], $args[2])) {
				$level = $sender->getLevel();
				$pos = new Position($args[0], $args[1], $args[2], $level);
				EventListener::setWandPosition($sender, $pos, true);
			} else {
				$sender->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
			}
		} else {
			EventListener::setWandPosition($sender, $sender, true);
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\EventListener;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;

class Pos2Command extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('pos2', $owner);
		$this->setUsage('command.pos2.usage');
		$this->setDescription('command.pos2.description');
		$this->setPermission('worldeditplus.command.pos2');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (! $sender instanceof Player) {
			$sender->sendMessage(TextFormat::RED . Language::get('command.console.error'));
		} elseif (isset($args[0])) {
			if (! isset($args[2]))
				return false;
			if ($this->checkNumber($args[0], $args[1], $args[2])) {
				$level = $sender->getLevel();
				$pos = new Position($args[0], $args[1], $args[2], $level);
				EventListener::setWandPosition($sender, $pos, false);
			} else {
				$sender->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
			}
		} else {
			EventListener::setWandPosition($sender, $sender, false);
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\processing\defaults\SphereProcessing;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;
use pocketmine\Server;

class SphereCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('sphere', $owner);
		$this->setUsage('command.sphere.usage');
		$this->setDescription('command.sphere.description');
		$this->setPermission('worldeditplus.command.sphere');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if (isset($args[0])) {
			if (! isset($args[6]))
				return false;
			if ($this->checkNumber($args[0], $args[1], $args[2], $args[3], $args[4], $args[5])) {
				$level = ($sender instanceof Player) ? $sender->getLevel() : Server::getInstance()->getDefaultLevel();
				$pos1 = new Position($args[0], $args[1], $args[2], $level);
				$pos2 = new Position($args[3], $args[4], $args[5], $level);
				$sphere = new SphereProcessing($sender, $pos1, $pos2, $args[6]);
				$sphere->start();
			} else {
				$sender->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
			}
		} elseif ($sender instanceof Player) {
			$callable = function($player, $data) {
				if (! isset($data))
					return;
				if ($this->checkNumber($data[0], $data[1], $data[2], $data[3], $data[4], $data[5])) {
					$name = $player->getLowerCaseName();
					$level_pos1 = (WorldEditPlus::$pos1[$name] ?? $player)->getLevel();
					$level_pos2 = (WorldEditPlus::$pos2[$name] ?? $player)->getLevel();
					$pos1 = new Position($data[0], $data[1], $data[2], $level_pos1);
					$pos2 = new Position($data[3], $data[4], $data[5], $level_pos2);
					$sphere = new SphereProcessing($player, $pos1, $pos2, $data[6]);
					$sphere->start();
				} else {
					$player->sendMessage(TextFormat::RED . Language::get('command.intval.error'));
				}
			};
			$form = $this->getDefaultForm($callable, $sender);
			if ($form === null)
				return false;
			$form->addInput(Language::get('form.block.one'), 'string');
			$form->sendToPlayer($sender);
		} else {
			return false;
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command\defaults;

use WorldEditPlus\command\WorldEditPlusCommand;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\CommandSender;
use pocketmine\item\enchantment\Enchantment;
use pocketmine\item\enchantment\EnchantmentInstance;
use pocketmine\item\Item;
use pocketmine\item\ItemIds;
use pocketmine\utils\TextFormat;
use pocketmine\Player;

class WandCommand extends WorldEditPlusCommand {

	/**
	 * @param WorldEditPlus $owner
	 */
	public function __construct(WorldEditPlus $owner) {
		parent::__construct('wand', $owner);
		$this->setUsage('command.wand.usage');
		$this->setDescription('command.wand.description');
		$this->setPermission('worldeditplus.command.wand');
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	public function onCommand(CommandSender $sender, array $args) : bool {
		if ($sender instanceof Player) {
			$item = Item::get(ItemIds::WOODEN_AXE);
			$enchant = new EnchantmentInstance(Enchantment::getEnchantment(Enchantment::PROTECTION));
			$item->addEnchantment($enchant);
			$item->setCustomName(Language::get('wand.name'));
			$item->setLore([
				Language::get('wand.description.left'),
				Language::get('wand.description.right')
			]);
			$sender->getInventory()->addItem($item);
			$sender->sendMessage(Language::get('command.wand'));
		} else {
			$sender->sendMessage(TextFormat::RED . Language::get('command.console.error'));
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\command;

use WorldEditPlus\level\Range;
use WorldEditPlus\Language;
use WorldEditPlus\WorldEditPlus;

use pocketmine\command\utils\InvalidCommandSyntaxException;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\Server;

abstract class WorldEditPlusCommand extends Command {

	/** @var WorldEditPlus */
	private $owner;

	/**
	 * @param string $name
	 * @param WorldEditPlus $owner
	 */
	protected function __construct(string $name, WorldEditPlus $owner) {
		parent::__construct($name);
		$this->owner = $owner;
	}

	/**
	 * @param CommandSender $sender
	 * @param string $commandLabel
	 * @param array $args
	 *
	 * @return mixed
	 */
	public function execute(CommandSender $sender, string $commandLabel, array $args) {

		if (! $this->owner->isEnabled())
			return false;

		if (! $this->testPermission($sender))
			return false;

		$success = $this->onCommand($sender, $args);

		if (! $success and $this->usageMessage !== "")
			throw new InvalidCommandSyntaxException();

		return $success;
	}

	/**
	 * @param CommandSender $sender
	 * @param array $args
	 *
	 * @return bool
	 */
	abstract protected function onCommand(CommandSender $sender, array $args) : bool;

	/**
	 * @param string $usage
	 */
	public function setUsage(string $usage) : void {
		parent::setUsage(Language::get($usage));
	}

	/**
	 * @param string $description
	 */
	public function setDescription(string $description) : void {
		parent::setDescription(Language::get($description));
	}

	/**
	 * @param callable $callable
	 * @param CommandSender $sender
	 *
	 * @return ?object
	 */
	protected function getDefaultForm(callable $callable, CommandSender $sender) : ?object {
		$formapi = Server::getInstance()->getPluginManager()->getPlugin('FormAPI');
		if ($formapi === null) {
			WorldEditPlus::$instance->getLogger()->warning(Language::get('form.api.error'));
			return null;
		}
		$form = $formapi->createCustomForm($callable);
		$form->setTitle(Language::get('form.message'));
		$name = $sender->getLowerCaseName();
		$pos1_x = WorldEditPlus::$pos1[$name]->x ?? '';
		$pos1_y = WorldEditPlus::$pos1[$name]->y ?? '';
		$pos1_z = WorldEditPlus::$pos1[$name]->z ?? '';
		$pos2_x = WorldEditPlus::$pos2[$name]->x ?? '';
		$pos2_y = WorldEditPlus::$pos2[$name]->y ?? '';
		$pos2_z = WorldEditPlus::$pos2[$name]->z ?? '';
		$form->addInput(TextFormat::RED . Language::get('form.pos.one.x'), 'int', (string) $pos1_x);
		$form->addInput(TextFormat::GREEN . Language::get('form.pos.one.y'), 'int', (string) $pos1_y);
		$form->addInput(TextFormat::AQUA . Language::get('form.pos.one.z'), 'int', (string) $pos1_z);
		$form->addInput(TextFormat::RED . Language::get('form.pos.two.x'), 'int', (string) $pos2_x);
		$form->addInput(TextFormat::GREEN . Language::get('form.pos.two.y'), 'int', (string) $pos2_y);
		$form->addInput(TextFormat::AQUA . Language::get('form.pos.two.z'), 'int', (string) $pos2_z);
		return $form;
	}

	/**
	 * @param string &...$number
	 *
	 * @return bool
	 */
	protected function checkNumber(string &...$number) : bool {
		foreach ($number as $key => $value) {
			if (! is_numeric($value))
				return false;
			$number[$key] = Range::changeInteger($value);
		}
		return true;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus;

use WorldEditPlus\WorldEditPlus as WEP;
use WorldEditPlus\level\Range;

use pocketmine\event\block\BlockBreakEvent;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\event\Listener;
use pocketmine\item\ItemIds;
use pocketmine\level\Position;
use pocketmine\utils\TextFormat;
use pocketmine\Player;

class EventListener implements Listener {

	public $time = [];

	/**
	 * @param BlockBreakEvent $event
	 */
	public function BlockBreakEvent(BlockBreakEvent $event){
		$this->WandEvent($event, true);
	}

	/**
	 * @param BlockBreakEvent|PlayerInteractEvent $event
	 * @param bool $boolean
	 */
	public function WandEvent($event, bool $boolean) : void {
		$player = $event->getPlayer();
		if (! $player->isOp())
			return;
		$item = $event->getItem();
		$id = $item->getId();
		$name = $item->getName();
		if ($id === ItemIds::WOODEN_AXE and $name === Language::get('wand.name')) {
			$event->setCancelled();
			$position = $event->getBlock()->asPosition();
			self::setWandPosition($player, $position, $boolean);
		}
	}

	/**
	 * @param Player $player
	 * @param Position $position
	 * @param bool $boolean
	 */
	public static function setWandPosition(Player $player, Position $position, bool $boolean) : void {
		$branch = $boolean ? 'pos1' : 'pos2';
		$name = $player->getLowerCaseName();
		WEP::$$branch[$name] = $position;
		if (isset(WEP::$pos1[$name], WEP::$pos2[$name])) {
			$range = new Range(WEP::$pos1[$name], WEP::$pos2[$name]);
			$size = $range->getSize();
			$message_size = Language::get('wand.size', $size);
		} else {
			$message_size = '';
		}
		$x = TextFormat::RED . Range::changeInteger($position->x) . TextFormat::RESET;
		$y = TextFormat::GREEN . Range::changeInteger($position->y) . TextFormat::RESET;
		$z = TextFormat::AQUA . Range::changeInteger($position->z) . TextFormat::RESET;
		$message = Language::get($boolean ? 'wand.pos1' : 'wand.pos2', $x, $y, $z);
		$player->sendMessage($message . $message_size);
	}

	/**
	 * @param PlayerInteractEvent $event
	 */
	public function PlayerInteractEvent(PlayerInteractEvent $event) : void {
		$action = $event->getAction();
		if ($action !== PlayerInteractEvent::LEFT_CLICK_BLOCK and $action !== PlayerInteractEvent::RIGHT_CLICK_BLOCK)
			return;
		$player = $event->getPlayer();
		if ($this->loopInteractMeasures($player))
			return;
		$this->WandEvent($event, false);
		$item = $event->getItem();
		$id = $item->getId();
		$name = $item->getName();
		if ($id !== ItemIds::BOOK and $name !== Language::get('book.name'))
			return;
		$block = $event->getBlock();
		$name = $block->getName();
		$id = $block->getId();
		$meta = $block->getDamage();
		$x = TextFormat::RED . $block->x . TextFormat::RESET;
		$y = TextFormat::GREEN . $block->y . TextFormat::RESET;
		$z = TextFormat::AQUA . $block->z . TextFormat::RESET;
		$player->sendMessage(Language::get('book.block', $name, $id, $meta, $x, $y, $z));
	}

	/**
	 * @param Player $player
	 *
	 * @return bool
	 */
	public function loopInteractMeasures(Player $player) : bool {
		$name = $player->getLowerCaseName();
		$time = $this->time[$name] ?? 0;
		$difference = $time - microtime(true);
		$this->time[$name] = microtime(true);
		return $difference > -0.1;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus;

class Language {

	private const FALLBACK_LANGUAGE = 'jpn';

	/** @var array */
	private static $language = [];

	/** @var array */
	private static $fall_language = [];

	/**
	 * @param string $lang
	 * @param string $path
	 * @param string $fall_path
	 */
	public function __construct(string $lang, string $path, string $fall_path) {

		$path .= 'languages/' . $lang . '.ini';

		if (! $this->loadLanguage($path, self::$language))
			WorldEditPlus::$instance->getLogger()->warning('言語ファイル「' . $lang . '.ini」が見つかりませんでした。');

		$fall_path .= 'resources/languages/' . self::FALLBACK_LANGUAGE . '.ini';

		if (! $this->loadLanguage($fall_path, self::$fall_language))
			WorldEditPlus::$instance->getLogger()->error('システムの言語ファイル「' . self::FALLBACK_LANGUAGE . '.ini」が見つかりませんでした。');

	}

	/**
	 * @param string $path
	 * @param array &$language
	 *
	 * @return bool
	 */
	private function loadLanguage(string $path, array &$language) : bool {
		if (! file_exists($path))
			return false;
		$decode = parse_ini_file($path, false, INI_SCANNER_RAW);
		$language = array_map('stripcslashes', $decode);
		return true;
	}

	/**
	 * @param string $text
	 * @param array $params
	 *
	 * @return string
	 */
	public static function get(string $text, ...$params) : string {

		$message = self::$language[$text] ?? self::$fall_language[$text] ?? 'No Message.';

		foreach ($params as $key => $value)
			$message = str_replace('{%' . $key . '}', $value, $message);

		return $message;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\level;

use pocketmine\level\Level;
use pocketmine\level\Position;

class Range {

	/** @var int */
	protected $pos1_x;
	protected $pos1_y;
	protected $pos1_z;

	/** @var int */
	protected $pos2_x;
	protected $pos2_y;
	protected $pos2_z;

	/** @var Level */
	protected $pos1_level;
	protected $pos2_level;

	/** @var int */
	protected $min_x;
	protected $min_y;
	protected $min_z;

	/** @var int */
	protected $max_x;
	protected $max_y;
	protected $max_z;

	/** @var int */
	protected $side_x;
	protected $side_y;
	protected $side_z;
	
	/** @var int */
	protected $next_x;
	protected $next_y;
	protected $next_z;

	/**
	 * @param Position $pos1
	 * @param Position $pos2
	 */
	public function __construct(Position $pos1, Position $pos2) {

		$this->pos1_x = self::changeInteger($pos1->x);
		$this->pos1_y = self::changeInteger($pos1->y);
		$this->pos1_z = self::changeInteger($pos1->z);

		$this->pos2_x = self::changeInteger($pos2->x);
		$this->pos2_y = self::changeInteger($pos2->y);
		$this->pos2_z = self::changeInteger($pos2->z);

		$this->pos1_level = $pos1->getLevel();
		$this->pos2_level = $pos2->getLevel();

		$this->min_x = min($this->pos1_x, $this->pos2_x);
		$this->min_y = min($this->pos1_y, $this->pos2_y);
		$this->min_z = min($this->pos1_z, $this->pos2_z);

		$this->max_x = max($this->pos1_x, $this->pos2_x);
		$this->max_y = max($this->pos1_y, $this->pos2_y);
		$this->max_z = max($this->pos1_z, $this->pos2_z);

		$this->side_x = $this->getSide($this->max_x, $this->min_x);
		$this->side_y = $this->getSide($this->max_y, $this->min_y);
		$this->side_z = $this->getSide($this->max_z, $this->min_z);

		$this->next_x = $this->getNext($this->pos1_x, $this->pos2_x);
		$this->next_y = $this->getNext($this->pos1_y, $this->pos2_y);
		$this->next_z = $this->getNext($this->pos1_z, $this->pos2_z);

	}
	
	/**
	 * @param int|float|string $number
	 *
	 * @return int
	 */
	public static function changeInteger($number) : int {
		return (int) floor((string) $number);
	}

	/**
	 * @param int $max
	 * @param int $min
	 *
	 * @return int
	 */
	private function getSide(int $max, int $min) : int {
		return ($max - $min) + 1;
	}

	/**
	 * @param int $start
	 * @param int $end
	 *
	 * @return int
	 */
	private function getNext(int $start, int $end) : int {
		return $start < $end ? 1 : -1;
	}

	/**
	 * @return int
	 */
	public function getSize() : int {
		return $this->side_x * $this->side_y * $this->side_z;
	}

	/**
	 * @return Level
	 */
	public function getLevel() : Level {
		return $this->pos1_level;
	}

	/**
	 * @return bool
	 */
	public function isLevel() : bool {
		return $this->pos1_level == $this->pos2_level;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\processing;

use pocketmine\block\Block;
use pocketmine\level\Level;

class BackUpClass {

	/** @var Level */
	public $level;

	/** @var array */
	public $data = [];

	/**
	 * @param Level $level
	 */
	public function __construct(Level $level, $owner) {
		$folder = $owner->getDataFolder();
		if(!file_exists($folder)) mkdir($folder);
		$this->db = new \SQLite3($folder.'backup.sqlite3');
		$this->level = $level->getName();
	}

	/**
	 * @param Block $block
	 */
	public function addData(Block $block) : void {
		$this->data[] = [
			'id'      => $block->getId(),
			'meta' => $block->getDamage(),
			'x'       => $block->x,
			'y'       => $block->y,
			'z'       => $block->z
		];
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\processing\defaults;

use WorldEditPlus\Language;
use WorldEditPlus\processing\Processing;

use pocketmine\block\Block;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\math\Vector3;

class CloneProcessing extends Processing {

	public const NAME = '/clone';

	public const MASK = ['replace', 'filtered', 'masked'];
	public const CLONE = ['normal', 'force', 'move'];

	public function __construct(CommandSender $sender, Position $pos1, Position $pos2, Position $pos3, string $mask, string $clone, string $replace) {
		parent::__construct($sender, $pos1, $pos2);
		$this->pos3 = $pos3;
		$this->mask = $mask;
		$this->clone = $clone;
		$this->replace = $this->fromString($replace);
		$this->setMeter($this->side_x);
	}

	public function onCheck(CommandSender $sender) : bool {
		if (! in_array($this->mask, self::MASK)) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.clone.mask.error'));
			return false;
		} elseif (! in_array($this->clone, self::CLONE)) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.clone.clone.error'));
			return false;
		} elseif ($this->mask === self::MASK[1] and $this->replace === null) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.block.one.error'));
			return false;
		}
		return true;
	}

	public function onRun() : iterable {
		$this->startMessage(self::NAME);

		$pos3_x = parent::changeInteger($this->pos3->x);
		$pos3_y = parent::changeInteger($this->pos3->y);
		$pos3_z = parent::changeInteger($this->pos3->z);

		$new_level = $this->pos3->getLevel();

		$this->normal = $this->level == $new_level;

		$mask = $this->mask;
		$clone = $this->clone;

		for($a = 0; abs($a) < $this->side_x; $a += $this->next_x) {
			$old_x = $this->pos1_x + $a;
			$new_x = $pos3_x + $a;
			for($b = 0; abs($b) < $this->side_y; $b += $this->next_y) {
				$old_y = $this->pos1_y + $b;
				$new_y = $pos3_y + $b;
				if($this->hasHeightLimit($old_y) or $this->hasHeightLimit($new_y))
					continue;
				for($c = 0; abs($c) < $this->side_z; $c += $this->next_z){
					$old_z = $this->pos1_z + $c;
					$new_z = $pos3_z + $c;
					$this->checkChunkLoaded($this->level, $old_x, $old_z);
					$this->checkChunkLoaded($new_level, $new_x, $new_z);
					$old_vector3 = new Vector3($old_x, $old_y, $old_z);
					$new_vector3 = new Vector3($new_x, $new_y, $new_z);
					$old_block = $this->level->getBlock($old_vector3);
					if($this->$mask($old_block))
						if($this->$clone($old_vector3, $new_vector3))
							$new_level->setBlock($new_vector3, $old_block, false, false);
					if($this->hasBlockRestriction())
						yield false;
				}
			}
			$this->addMeter();
		}
		$this->endMessage(self::NAME);
		yield true;
	}

	public function replace(Block $block) : bool {
		return true;
	}

	public function filtered(Block $block) : bool {
		return isset($this->replace[(string) $block]);
	}

	public function masked(Block $block) : bool {
		return (string) $block !== (string) $this->air;
	}

	public function normal(Vector3 $old, Vector3 $new) : bool {
		if($this->normal) {
			$x = $new->x;
			$y = $new->y;
			$z = $new->z;
			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(Vector3 $old, Vector3 $new) : bool {
		return true;
	}

	public function move(Vector3 $old, Vector3 $new) : bool {
		return $this->level->setBlock($old, $this->air, false, false);
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\processing\defaults;

use WorldEditPlus\Language;
use WorldEditPlus\processing\Processing;

use pocketmine\block\Block;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\math\Vector3;

class CylinderProcessing extends Processing {

	public const NAME = '/cylinder';

	public const DIRECTION = ['x', 'y', 'z'];

	public function __construct(CommandSender $sender, Position $pos1, Position $pos2, string $block, string $direction) {
		parent::__construct($sender, $pos1, $pos2);
		$this->block = $this->fromString($block);
		$this->direction = $direction;
	}

	public function onCheck(CommandSender $sender) : bool {
		if ($this->block === null) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.block.one.error'));
			return false;
		} elseif (! in_array($this->direction, self::DIRECTION)) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.cylinder.direction.error'));
			return false;
		}
		return true;
	}

	public function onRun() : iterable {
		$this->startMessage(self::NAME);

		$copy = self::DIRECTION;
		$direction = $this->direction;
		$key = array_search($direction, $copy);
		unset($copy[$key]);
		array_unshift($copy, $direction);

		$pos1_x = 'pos1_' . $copy[0];
		$pos1_y = 'pos1_' . $copy[1];
		$pos1_z = 'pos1_' . $copy[2];

		$side_x = 'side_' . $copy[0];
		$side_y = 'side_' . $copy[1];
		$side_z = 'side_' . $copy[2];

		$next_x = 'next_' . $copy[0];
		$next_y = 'next_' . $copy[1];
		$next_z = 'next_' . $copy[2];

		$radius_y = ($this->$side_y - 1) / 2;
		$radius_z = ($this->$side_z - 1) / 2;

		$center_y = $this->$pos1_y + ($radius_y * $this->$next_y);
		$center_z = $this->$pos1_z + ($radius_z * $this->$next_z);

		for ($a = 0; $a < 360; $a += 0.01) {

			$radian = deg2rad($a);

			$x = round($center_y + ($radius_y * sin($radian)));
			$z = round($center_z + ($radius_z * cos($radian)));

			if (isset($cylinder[$x][$z]))
				continue;

			$cylinder[$x][$z] = $z;

		}

		for ($a = 0; abs($a) < $this->$side_x; $a += $this->$next_x) {

			$x = $this->$pos1_x + $a;

			foreach ($cylinder as $y => $value) {

				foreach ($value as $z) {

					if ($copy[0] === self::DIRECTION[0])
						$vector3 = new Vector3($x, $y, $z);
					elseif ($copy[0] === self::DIRECTION[1])
						$vector3 = new Vector3($y, $x, $z);
					elseif ($copy[0] === self::DIRECTION[2])
						$vector3 = new Vector3($y, $z, $x);

					$block = $this->set();
					$this->level->setBlock($vector3, $block, false, false);

					if ($this->hasBlockRestriction())
						yield false;

				}
			}
		}

		$this->endMessage(self::NAME);
		yield true;
	}

	public function set() : Block {
		$rand = array_rand($this->block);
		return $this->block[$rand];
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\processing\defaults;

use WorldEditPlus\Language;
use WorldEditPlus\processing\Processing;

use pocketmine\block\Block;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\math\Vector3;

class FillProcessing extends Processing {

	public const NAME = '/fill';

	public const OPTION = ['set', 'outline', 'hollow', 'keep', 'replace'];

	public function __construct(CommandSender $sender, Position $pos1, Position $pos2, string $block, string $option, string $replace) {
		parent::__construct($sender, $pos1, $pos2);
		$this->block = $this->fromString($block);
		$this->option = $option;
		$this->replace = $this->fromString($replace);
		$this->setMeter($this->side_x);
	}

	public function onCheck(CommandSender $sender) : bool {
		if ($this->block === null) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.block.one.error'));
			return false;
		} elseif (! in_array($this->option, self::OPTION)) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.fill.option.error'));
			return false;
		} elseif ($this->option === self::OPTION[4] and $this->replace === null) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.block.two.error'));
			return false;
		}
		return true;
	}

	public function onRun() : iterable {
		$this->startMessage(self::NAME);
		$option = $this->option;
		for ($a = 0; abs($a) < $this->side_x; $a += $this->next_x) {
			$x = $this->pos1_x + $a;
			for ($b = 0; abs($b) < $this->side_y; $b += $this->next_y) {
				$y = $this->pos1_y + $b;
				if ($this->hasHeightLimit($y))
					continue;
				for ($c = 0; abs($c) < $this->side_z; $c += $this->next_z){
					$z = $this->pos1_z + $c;
					$this->checkChunkLoaded($this->level, $x, $z);
					$vector3 = new Vector3($x, $y, $z);
					$old_block = $this->level->getBlock($vector3);
					$new_block = $this->$option($old_block);
					if ($new_block !== null)
						$this->level->setBlock($vector3, $new_block, false, false);
					if ($this->hasBlockRestriction())
						yield false;
				}
			}
			$this->addMeter();
		}
		$this->endMessage(self::NAME);
		yield true;
	}

	public function set(?Block $block = null) : Block {
		$rand = array_rand($this->block);
		return $this->block[$rand];
	}

	public function outline(Block $block) : ?Block {
		$x = $block->x;
		$y = $block->y;
		$z = $block->z;
		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 null;
		return $this->set();
	}

	public function hollow(Block $block) : Block {
		$x = $block->x;
		$y = $block->y;
		$z = $block->z;
		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 $this->air;
		return $this->set();
	}

	public function keep(Block $block) : ?Block {
		return (string) $block === (string) $this->air ? $this->set() : null;
	}

	public function replace(Block $block) : ?Block {
		return isset($this->replace[(string) $block]) ? $this->set() : null;
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\processing\defaults;

use WorldEditPlus\Language;
use WorldEditPlus\processing\Processing;

use pocketmine\block\Block;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\command\CommandSender;
use pocketmine\utils\TextFormat;
use pocketmine\math\Vector3;

class SphereProcessing extends Processing {

	public const NAME = '/sphere';

	public function __construct(CommandSender $sender, Position $pos1, Position $pos2, string $block) {
		parent::__construct($sender, $pos1, $pos2);
		$this->block = $this->fromString($block);
		#$this->filled = false;
	}

	public function onCheck(CommandSender $sender) : bool {
		if ($this->block === null) {
			$sender->sendMessage(TextFormat::RED . Language::get('processing.block.one.error'));
			return false;
		}
		return true;
	}

	public function onRun() : iterable {
		$this->startMessage(self::NAME);

		$radius_x = ($this->side_x - 1) / 2;
		$radius_y = ($this->side_y - 1) / 2;
		$radius_z = ($this->side_z - 1) / 2;

		$center_x = $this->pos1_x + ($radius_x * $this->next_x);
		$center_y = $this->pos1_y + ($radius_y * $this->next_y);
		$center_z = $this->pos1_z + ($radius_z * $this->next_z);

		var_dump($radius_x, $radius_y, $radius_z);
		var_dump($center_x, $center_y, $center_z);

		$vector3 = new Vector3($center_x, $center_y, $center_z);

        $inv_radius_x = 1 / ($radius_x);
        $inv_radius_y = 1 / ($radius_y);
        $inv_radius_z = 1 / ($radius_z);

        $next_x = 0;
		$break_x = false;

		for($x = 0; $x <= $radius_x and $break_x === false; $x += 0.5) {
			var_dump($x);

			$xn = $next_x;
			$next_x = ($x + 1) * $inv_radius_x;

			$next_y = 0;
			$break_y = false;

			for($y = 0; $y <= $radius_y and $break_y === false; $y += 0.5) {

				$yn = $next_y;
				$next_y = ($y + 1) * $inv_radius_y;

				$next_z = 0;

				for($z = 0; $z <= $radius_z; $z += 0.5) {

					$zn = $next_z;
					$next_z = ($z + 1) * $inv_radius_z;

					if ($this->hasBlockRestriction(8))
						yield false;

					$distanceSq = $this->lengthSq($xn, $yn, $zn);

					if($distanceSq > 1){
						if($z === 0){
							if($y === 0){
								$break_x = true;
								$break_y = true;
								break;
							}
							$break_y = true;
							break;
						}
						break;
					}
					
					#if($this->filled === false){						
					#	if($this->lengthSq($next_x, $yn, $zn) <= 1 and $this->lengthSq($xn, $next_y, $zn) <= 1 and $this->lengthSq($xn, $yn, $next_z) <= 1){
					#		continue;
					#	}
					#}

					#var_dump($vector3->add($x, $y, $z));

					$this->level->setBlock(($a = $vector3->add($x, $y, $z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add(-$x, -$y, -$z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add(-$x, $y, $z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add($x, -$y, $z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add($x, $y, -$z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add($x, -$y, -$z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add(-$x, $y, -$z)->ceil()), $this->set(), false, false);
					$this->level->setBlock(($vector3->add(-$x, -$y, $z)->ceil()), $this->set(), false, false);
					
				}
			}
			var_dump($a->x);
		}

		$this->endMessage(self::NAME);
		yield true;
	}

	public function int(Vector3 $vector3) : Vector3 {
		return new Vector3(
			(int) $vector3->x,
			(int) $vector3->y,
			(int) $vector3->z
		);
	}

	public function set($xn = null, $yn = null, $zn = null, $next_x = null, $next_y = null, $next_z = null, $block = null) : Block {
		$rand = array_rand($this->block);
		return $this->block[$rand];
	}

	public static function lengthSq($x, $y, $z){
		return ($x ** 2) + ($y ** 2) + ($z ** 2);
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus\processing;

use WorldEditPlus\level\Range;
use WorldEditPlus\WorldEditPlus;
use WorldEditPlus\Language;

use pocketmine\block\Block;
use pocketmine\block\BlockIds;
use pocketmine\command\CommandSender;
use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\scheduler\Task;
use pocketmine\utils\TextFormat;
use pocketmine\Server;

abstract class Processing extends Range {

	/** @var array */
	private static $message = [];

	public static $scheduler = [];

	private static $count = 0;

	/** @var int */
	private $id;
	/** @var CommandSender */
	public $sender;

	/** @var float */
	public $meter;
	/** @var floatl */
	public $gage = 0;

	/** @var int */
	public $stopper;
	/** @var int */
	public $restriction = 0;


	/**
	 * @param CommandSender $sender
	 * @param Position $pos1
	 * @param Position $pos2
	 */
	public function __construct(CommandSender $sender, Position $pos1, Position $pos2) {
		parent::__construct($pos1, $pos2);
		$this->sender = $sender;
		$this->id = self::$count++;
		$this->air = Block::get(BlockIds::AIR);
		$this->stopper = WorldEditPlus::$instance->getConfig()->get('stopper', null) ?? 500;
	}

	/**
	 * @return bool
	 */
	abstract public function onCheck(CommandSender $sender) : bool;

	/**
	 * @return iterable 
	 */
	abstract public function onRun() : iterable;

	public function start() : void {
		$this->level = $this->getLevel();
		if ($this->level === null) {
			$this->sender->sendMessage(TextFormat::RED . Language::get('processing.level.null.error'));
			return;
		}
		if (! $this->isLevel()) {
			$this->sender->sendMessage(TextFormat::RED . Language::get('processing.level.error'));
			return;
		}
		if (! $this->onCheck($this->sender))
			return;
		$task = new class($this) extends Task {

			public function __construct(Processing $owner) {
				$this->generator = $owner->onRun();
				$this->owner = $owner;
			}

			public function onRun(int $tick) {
				if ($this->generator->current())
					$this->getHandler()->cancel();
				else
					$this->generator->next();
			}

			public function onCancel() {
				$this->owner->remove();
			}

		};
		$id = $this->id;
		$period = WorldEditPlus::$instance->getConfig()->get('period', null) ?? 1;
		self::$scheduler[$id] = WorldEditPlus::$instance->getScheduler()->scheduleRepeatingTask($task, $period);
	}

	public function remove() : void {
		$id = $this->id;
		unset(self::$message[$id], self::$scheduler[$id]);
	}

	/**
	 * @param string $string
	 *
	 * @return array|null
	 */
	public function fromString(string $string) : ?array {
		try {
			$items = Item::fromString($string, true);
			foreach ($items as $item) {
				$item_name = $item->getName();
				$block = $item->getBlock();
				$block_name = $block->getName();
				if ($item_name !== $block_name) return null;
				$blocks[(string) $block] = $block;
			}
			return $blocks;
		} catch (\Exception $e) {
			return null;
		}
	}

	public function hasHeightLimit(int $y) : bool {
		return $y < 0 or $y > Level::Y_MAX;
	}

	public function checkChunkLoaded(Level $level, int $x, int $z) : void {
		if (! $level->isChunkLoaded($x >> 4, $z >> 4))
			$level->loadChunk($x >> 4, $z >> 4, true);
	}

	public function hasBlockRestriction(int $count = 1) : bool {
		$this->restriction += $count;
		if ($this->restriction < $this->stopper)
			return false;
		$this->restriction = 0;
		return true;
	}

	/**
	 * @param float $value
	 */
	public function setMeter(float $value) : void {
		$this->meter = 100 / $value;
	}

	public function addMeter() : void {
		$round = round($this->gage += $this->meter);
		$name = $this->sender->getName();
		$id = $this->id;
		self::$message[$id] = Language::get('processing.meter', $id, $name, $round);
		foreach (self::$message as $message)
			$list = isset($list) ? $list . TextFormat::EOL . $message : $message;
		Server::getInstance()->broadcastTip($list);
	}

	public function startMessage(string $command) : void {
		$id = $this->id;
		$name = $this->sender->getName();
		$size = $this->getSize();
		Server::getInstance()->broadcastMessage(Language::get('processing.start', $id, $name, $command, $size));
	}

	public function endMessage(string $command) : void {
		$id = $this->id;
		$name = $this->sender->getName();
		Server::getInstance()->broadcastMessage(Language::get('processing.end', $id, $name, $command));
	}

}<?php

/** 
 * Copyright (c) 2018 CreeParker
 * 
 * <English>
 * This plugin is released under the MIT License.
 * http://opensource.org/licenses/mit-license.php
 *
 * <日本語>
 * このプラグインは、MITライセンスのもとで公開されています。
 * http://opensource.org/licenses/mit-license.php
 */

declare(strict_types = 1);

namespace WorldEditPlus;

use WorldEditPlus\command\defaults\BookCommand;
use WorldEditPlus\command\defaults\CancelCommand;
use WorldEditPlus\command\defaults\CloneCommand;
use WorldEditPlus\command\defaults\CylinderCommand;
use WorldEditPlus\command\defaults\FillCommand;
use WorldEditPlus\command\defaults\Pos1Command;
use WorldEditPlus\command\defaults\Pos2Command;
use WorldEditPlus\command\defaults\SphereCommand;
use WorldEditPlus\command\defaults\WandCommand;

use pocketmine\plugin\PluginBase;

class WorldEditPlus extends PluginBase {

	public static $pos1;

	public static $pos2;


	/** @var WorldEditPlus */
	public static $instance;

	public function onEnable() : void {

		self::$instance = $this;

		$resources = $this->getResources();
		foreach ($resources as $key => $value)
			$this->saveResource($key);
		$lang = $this->getConfig()->get('language');
		$path = $this->getDataFolder();
		$fall_path = $this->getFile();
		new Language($lang, $path, $fall_path);

		$this->getServer()->getPluginManager()->registerEvents((new EventListener), $this);

		$this->getServer()->getCommandMap()->registerAll('worldeditplus', [
			new BookCommand($this),
			new CancelCommand($this),
			new CloneCommand($this),
			new CylinderCommand($this),
			new FillCommand($this),
			new Pos1Command($this),
			new Pos2Command($this),
			#new SphereCommand($this),
			new WandCommand($this),
		]);
		
	}

}ˆƒ,ºßoyˆ“¥‘×s0XDt   GBMB