From 56eaeade4857b1720b93bd280e6650b4fd3b6c46 Mon Sep 17 00:00:00 2001 From: Alejandro Liu Date: Tue, 8 Nov 2016 06:38:32 +0100 Subject: [PATCH] 1.2.4 --- README.md | 61 +++-- plugin.yml | 7 +- src/aliuly/worldprotect/Main.php | 255 +++++++++++++++--- src/aliuly/worldprotect/MaxPlayerMgr.php | 46 ++++ src/aliuly/worldprotect/NoExplodeMgr.php | 29 +- .../worldprotect/PluginCallbackTask.php | 65 +++++ src/aliuly/worldprotect/WpBordersMgr.php | 32 ++- src/aliuly/worldprotect/WpListener.php | 22 +- src/aliuly/worldprotect/WpMotdMgr.php | 39 ++- src/aliuly/worldprotect/WpProtectMgr.php | 135 ++++++---- src/aliuly/worldprotect/WpPvpMgr.php | 30 ++- 11 files changed, 536 insertions(+), 185 deletions(-) create mode 100644 src/aliuly/worldprotect/MaxPlayerMgr.php create mode 100644 src/aliuly/worldprotect/PluginCallbackTask.php diff --git a/README.md b/README.md index 2be0310..2672a8a 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,14 @@ Basic Usage: * /wp unprotect|unlock [level] * /wp lock [level] * /wp protect [level] -* /wp pvp [level] [on|off] +* /wp pvp [level] [on|off|spawn] * /wp noexplode [level] [off|world|spawn] * /wp border [level] [x1 z1 x2 z2|none] * /wp max [level] [count] * /wp add [level] *player* * /wp rm [level] *player* * /wp motd [level] [text] +* /wp unbreakable [level] [id id id] Documentation ------------- @@ -54,10 +55,8 @@ It is able to: * Show a text file when players enter a world. To explain players what is allowed (or not allowed) in specific worlds. For example you could warn players when they are entering a PvP world. +* Create unbreakable blocks. -Note that limiting players in a world is only supported by -[ManyWorlds](http://forums.pocketmine.net/plugins/manyworlds.1042/) -and any plugin that uses ManyWorlds teleport functionality. ### Commands: @@ -87,9 +86,10 @@ Protect: Per-world PvP: -* wp pvp [level] [on|off] +* wp pvp [level] [on|off|spawn] If nothing is specified it will show the PvP status of the current - level. Otherwise PvP will either be activated|de-activated. + level. Otherwise PvP will either be activated|de-activated. If set + to `spawn`, PvP is turned off in the spawn area of this world. No Explode: @@ -123,6 +123,13 @@ Access to these commands is controlled by standard PocketMine permission system. When a world's `auth` list is defined, access to these commands are restricted to the people in the `auth` list. +Unbreakable blocks: + +* wp unbreakable [level] [id ...] + Will add the *id* to the list of unbreakable blocks for this world. +* wp breakable [level] [id ...] + Will remove the *id* from the list of unbreakable blocks for this world. + ### Configuration In the plugin's config.yml file you can have: @@ -134,13 +141,9 @@ In the plugin's config.yml file you can have: per-world-pvp: true motd: true no-explode: true + unbreakable: true -* player-limits: Enables the per world player limits -* world-borders: Enables the world border module -* world-protect: Enables the anti-griefing module -* per-world-pvp: Enables per world PvP functionality -* no-explode: Enables explosion protection -* motd : Enable per world MOTD text +Control what modules are active. ### Permission Nodes: @@ -153,30 +156,44 @@ In the plugin's config.yml file you can have: * wp.cmd.limit - Allow control to limit functionality * wp.cmd.wpmotd - Allow editing the motd * wp.cmd.noexplode - no explode command access +* wp.cmd.addrm - Allow modifying the auth list +* wp.cmd.unbreakable - Allow modifying the unbreakable block list ### ManyWorlds -The World Limit functionality requires the use of ManyWorlds teleport. -Also, if ManyWorlds is installed, the +If ManyWorlds is installed, the /mw ls [level] -Will show additional information. +Will show additional information. Also, you can enter: -### Issues + /wp ls [level] -* World names can not contain spaces. -* Placing a sign on worlds that do not allow placing blocks will crash - the MCPE client. +To get world details. -### TODO - -* Prevent PvP in spawn. pvp spawn +### Issues +* World names can not contain spaces. Changes ------- +* 1.2.4: CallbackTask + * Removed CallbackTask deprecation warnings +* 1.2.3: Suggested change + * Simpler border setting using a single "range" number +* 1.2.2: protection overview (un-published) + * Added an overview of protected worlds +* 1.2.1: BugFix + * Positions are not configured correctly. +* 1.2.0: Update + * Bugfix in sending motd text + * Bugfixes WpProtect + * wp ls/ld - will call ManyWorlds. Needs ManyWorlds v1.3.2. + * Fixed Signs Tiles being left all over... + * Added stop PvP in spawn areas + * Added Unbreakable blocks + * Max players per world should now work *without* ManyWorlds. * 1.1.1 : bugfix * Fixes bugs reported by [Crash Archive](http://crash.pocketmine.net/search) * 1.1.0: no-explode diff --git a/plugin.yml b/plugin.yml index 8f5de0b..96b30c4 100644 --- a/plugin.yml +++ b/plugin.yml @@ -5,7 +5,7 @@ softdepend: [ManyWorlds] name: WorldProtect description: protect worlds from griefers, pvp, limits and borders -version: 1.1.1 +version: 1.2.4 author: aliuly commands: @@ -49,4 +49,7 @@ permissions: description: "Allow editing the motd" wp.cmd.addrm: default: op - description: "Allow modifying the auth list" \ No newline at end of file + description: "Allow modifying the auth list" + wp.cmd.unbreakable: + default: op + description: "Modify unbreakable block list" \ No newline at end of file diff --git a/src/aliuly/worldprotect/Main.php b/src/aliuly/worldprotect/Main.php index 0a235fc..d7dbaf6 100644 --- a/src/aliuly/worldprotect/Main.php +++ b/src/aliuly/worldprotect/Main.php @@ -10,6 +10,7 @@ use pocketmine\utils\TextFormat; use pocketmine\utils\Config; use pocketmine\math\Vector3; +use pocketmine\item\Item; class Main extends PluginBase implements CommandExecutor { const MIN_BORDER = 32; @@ -19,6 +20,8 @@ class Main extends PluginBase implements CommandExecutor { protected $spam; const SPAM_DELAY = 5; static private $aliases = [ + "ubab" => "unbreakable", + "bab" => "breakable", "unprotect" => "unlock", "open" => "unlock", "notnt" => "noexplode", @@ -39,12 +42,13 @@ private function inGame(CommandSender $sender,$msg = true) { public function onEnable(){ $defaults = [ "settings" => [ - "player-limits" => true, + "player-limits" => false, "world-borders" => true, "world-protect" => true, "per-world-pvp" => true, "motd" => true, "no-explode" => true, + "unbreakable" => true, ], ]; if (!is_dir($this->getDataFolder())) mkdir($this->getDataFolder()); @@ -53,16 +57,18 @@ public function onEnable(){ if ($cfg["settings"]["player-limits"] && $this->getServer()->getPluginManager()->getPlugin("ManyWorlds")==null){ $this->getLogger()->info(TextFormat::RED. - "player-limits functionality ONLY works with the ". + "player-limits functionality ". + TextFormat::AQUA."WITHOUT"); + $this->getLogger()->info(TextFormat::RED."the ". TextFormat::WHITE."ManyWorlds". - TextFormat::RED." plugin"); - $cfg["settings"]["player-limits"] = false; + TextFormat::RED." plugin is experimental"); + //$cfg["settings"]["player-limits"] = false; } $this->listeners = []; $this->listeners["main"] = new WpListener($this); if ($cfg["settings"]["motd"]) $this->listeners["motd"] = new WpMotdMgr($this); - if ($cfg["settings"]["world-protect"]) + if ($cfg["settings"]["world-protect"] || $cfg["settings"]["unbreakable"]) $this->listeners["protect"] = new WpProtectMgr($this); if ($cfg["settings"]["world-borders"]) $this->listeners["borders"] = new WpBordersMgr($this); @@ -70,12 +76,28 @@ public function onEnable(){ $this->listeners["pvp"] = new WpPvpMgr($this); if ($cfg["settings"]["no-explode"]) $this->listeners["no-explode"] = new NoExplodeMgr($this); + if ($cfg["settings"]["player-limits"]) + $this->listeners["player-limits"] = new MaxPlayerMgr($this); $this->settings = $cfg["settings"]; $this->wcfg = []; $this->spam = []; } + protected function wpPvpMode($level) { + if (isset($this->wcfg[$level]["pvp"])) { + $x = $this->wcfg[$level]["pvp"]; + echo __METHOD__.",".__LINE__."-$x\n"; + if ($x === "spawn") { + return TextFormat::YELLOW."spawn"; + } elseif ($x) { + return TextFormat::RED."ON"; + } else { + return TextFormat::GREEN."OFF"; + } + } + return TextFormat::RED."ON"; + } //////////////////////////////////////////////////////////////////////// // // Event handlers... @@ -122,13 +144,30 @@ public function showMotd($name,$level) { if (is_array($this->wcfg[$level]["motd"])) { $ticks = 10; foreach ($this->wcfg[$level]["motd"] as $ln) { - getServer()->getScheduler()->scheduleDelayedTask(new CallbackTask([$player,"sendMessage"],[$ln]),$ticks); + $this->getServer()->getScheduler()->scheduleDelayedTask(new PluginCallbackTask($this,[$player,"sendMessage"],[$ln]),$ticks); $ticks += 10; } } else { $player->sendMessage($this->wcfg[$level]["motd"]); } } + // + // Unbreakable + // + public function checkUnbreakable($pname,$level,$blkid) { + if (!isset($this->wcfg[$level]["ubab"])) return false; + if (!count($this->wcfg[$level]["ubab"])) return false; + // Check if user is in auth list... + if (isset($this->wcfg[$level]["auth"]) + && count($this->wcfg[$level]["auth"]) + && isset($this->wcfg[$level]["auth"][$pname])) return false; + $player = $this->getServer()->getPlayer($pname); + if ($player && $player->hasPermission("wp.cmd.protect.auth")) + return false; + if (isset($this->wcfg[$level]["ubab"][$blkid])) return true; + return false; + } + // // World protect // @@ -163,8 +202,17 @@ public function checkNoExplode($x,$y,$z,$level) { // // PvP callback // - public function checkPvP($level) { + public function checkPvP($level,$x,$y,$z) { if (!isset($this->wcfg[$level]["pvp"])) return true; + if ($this->wcfg[$level]["pvp"] === "spawn") { + // Check spawn position + $lv = $this->getServer()->getLevelByName($level); + if (!$lv) return true; + $sp = $lv->getSpawnLocation(); + $dist = $sp->distance(new Vector3($x,$y,$z)); + if ($dist < $this->getServer()->getSpawnRadius()) return false; + return true; + } return $this->wcfg[$level]["pvp"]; } // @@ -220,6 +268,11 @@ public function onCommand(CommandSender $sender, Command $cmd, $label, array $ar case "rm": if (!$this->access($sender,"wp.cmd.addrm")) return false; return $this->worldProtectRm($sender,$args); + case "unbreakable": + case "breakable": + if (!$this->access($sender,"wp.cmd.unbreakable")) return false; + if (!$this->settings["unbreakable"]) return false; + return $this->worldUBAB($sender,$scmd,$args); case "unlock": case "lock": case "protect": @@ -248,6 +301,18 @@ public function onCommand(CommandSender $sender, Command $cmd, $label, array $ar return $this->worldMotdCmd($sender,$args); case "help": return $this->helpCmd($sender,$args); + case "ls": + if (count($args) == 0 || + (count($args) == 1 && is_numeric($args[0]))) { + return $this->wpList($sender,$args); + } + case "ld": + // These commands actually come from ManyWorlds... + $pm = $this->getServer()->getPluginManager()->getPlugin("ManyWorlds"); + if ($pm) { + array_unshift($args,$scmd); + return $pm->onCommand($sender,$cmd,$label,$args); + } default: $sender->sendMessage(TextFormat::RED."Unknown sub command: ". TextFormat::RESET.$scmd); @@ -278,13 +343,18 @@ private function helpCmd(CommandSender $sender,$args) { "unlock" => ["[level]","Unprotects a world"], "lock"=>["[level]","Locked. Nobody (including op) can build"], "protect"=>["[level]","Only authorized people can build"], - "pvp"=>["[level] [on|off]","Enable|disable pvp"], + "pvp"=>["[level] [on|off|spawn]","Enable|disable pvp"], "noexplode" =>["[level] [off|world|spawn]", "Stop explosions in world or spawn area"], "border" => ["[level] [x1 z1 x2 z2|none]", "Creates a border in [level] defined by x1,z1 to x2,z2"], "max" => ["[level] [value]", "Limits the number of players in a world to [value] use 0 or -1 to remove limits"], + "unbreakable" => [ "[level] ", + "Sets blocks to unbreakable status" ], + "breakable" => [ "[level] ", + "Remove blocks from unbreakable status" ], + ]; if (count($args)) { foreach ($args as $c) { @@ -309,7 +379,56 @@ private function helpCmd(CommandSender $sender,$args) { } return true; } - + private function attrList($wcfg) { + $attr = []; + if (isset($wcfg["motd"])) { + $attr[] = "motd"; + } + if (isset($wcfg["protect"])) $attr[] = $wcfg["protect"]; + if (isset($wcfg["pvp"])) { + if ($wcfg["pvp"] === "spawn") { + $attr[] = "pvp:spawn"; + } elseif ($wcfg["pvp"]) { + $attr[] = "pvp:on"; + } else { + $attr[] = "pvp:off"; + } + } + if (isset($wcfg["no-explode"])) + $attr[] = "notnt:".$wcfg["no-explode"]; + if (isset($wcfg["border"])) $attr[] = "border"; + if (isset($wcfg["auth"])) + $attr[] = "auth(".count($wcfg["auth"]).")"; + return $attr; + } + private function wpList(CommandSender $c,$args) { + $dir = $this->getServer()->getDataPath(). "worlds"; + if (!is_dir($dir)) { + $sender->sendMessage("[WP] Missing path $dir"); + return true; + } + $dh = opendir($dir); + if (!$dh) return false; + while (($file = readdir($dh)) !== false) { + if ($file == '.' || $file == '..') continue; + if (!$this->getServer()->isLevelGenerated($file)) continue; + $attrs = []; + if (isset($this->wcfg[$file])) { + $attrs = $this->attrList($this->wcfg[$file]); + } else { + $f = "$dir/$file/wpcfg.yml"; + if (is_file($f)) { + $attrs=$this->attrList((new Config($f,Config::YAML))->getAll()); + } + } + $txt = $file; + if (count($attrs)) { + $txt.=" (".implode(", ",$attrs).")"; + } + $c->sendMessage($txt); + } + return true; + } private function motdCmd(CommandSender $sender,$args) { if (count($args) == 0) { if (!$this->inGame($sender)) return true; @@ -399,6 +518,48 @@ private function worldProtectRm(CommandSender $sender,$args) { return true; } // + // Unbreakable blocks + // + private function worldUBAB(CommandSender $sender,$mode,$args) { + if (count($args) == 0) return false; + if ($this->getServer()->isLevelGenerated($args[0])) { + $level = array_shift($args); + } else { + if (!$this->inGame($sender)) return true; + $level = $sender->getLevel()->getName(); + } + if (!$this->doLoadWorldConfig($sender,$level)) return true; + if (!$this->isAuth($sender,$level)) return true; + if(!count($args)) { + if(isset($this->wcfg[$level]["ubab"])) { + $lst = ""; + foreach ($this->wcfg[$level]["ubab"] as $b) { + $lst .= (strlen($lst)>0 ? ", " : "").$b; + } + $sender->sendMessage("Unbreakables(". + count($this->wcfg[$level]["ubab"])."): ". + $lst); + } else { + $sender->sendMessage("No unbreakable blocks in $level"); + } + return true; + } + if ($mode == "breakable") { + foreach ($args as $i) { + $item = Item::fromString($i); + unset($this->wcfg[$level]["ubab"][$item->getId()]); + } + } else { + foreach ($args as $i) { + $item = Item::fromString($i); + if ($item->getId() == Item::AIR) continue; + $this->wcfg[$level]["ubab"][$item->getId()] = $i."(".$item->getId().")"; + } + } + $this->saveWorldConfig($level); + return true; + } + // // World protect // private function worldProtectMode(CommandSender $sender,$mode,$args) { @@ -493,7 +654,9 @@ private function worldPvpMode(CommandSender $sender,$args) { $level = $sender->getLevel()->getName(); $mode = "show"; } elseif (count($args) == 1) { - if (strtolower($args[0]) == "on" || strtolower($args[0]) == "off") { + if (strtolower($args[0]) == "on" || + strtolower($args[0]) == "off" || + strtolower($args[0]) == "spawn") { if (!$this->inGame($sender)) return true; $mode = strtolower($args[0]); $level = $sender->getLevel()->getName(); @@ -510,20 +673,27 @@ private function worldPvpMode(CommandSender $sender,$args) { if (!$this->doLoadWorldConfig($sender,$level)) return true; if ($mode == "show") { $sender->sendMessage("PvP status for $level is ". - ($this->checkPvP($level) ? - TextFormat::RED."ON" : - TextFormat::GREEN."OFF")); + $this->wpPvpMode($level)); return true; } if (!$this->isAuth($sender,$level)) return true; if ($mode == "on") { - if ($this->checkPvP($level)) { + if (!isset($this->wcfg[$level]["pvp"]) || + $this->wcfg[$level]["pvp"] === true) { $sender->sendMessage("PvP status unchanged"); return true; } $this->wcfg[$level]["pvp"] = true; + } elseif ($mode == "spawn") { + if (isset($this->wcfg[$level]["pvp"]) && + $this->wcfg[$level]["pvp"] === "spawn") { + $sender->sendMessage("PvP status unchanged"); + return true; + } + $this->wcfg[$level]["pvp"] = "spawn"; } else { - if (!$this->checkPvP($level)) { + if (isset($this->wcfg[$level]["pvp"]) && + $this->wcfg[$level]["pvp"] == false) { $sender->sendMessage("PvP status unchanged"); return true; } @@ -536,6 +706,14 @@ private function worldPvpMode(CommandSender $sender,$args) { // World borders private function worldBorderCmd(CommandSender $sender,$args) { + // [level] [x1 z1 x2 z2] + // [level] [number] + // [level] [none] + // [[x1 z1 x2 z2] + // [number] + // [none] + // + if (count($args) == 4) { if (!$this->inGame($sender)) return true; $level = $sender->getLevel()->getName(); @@ -550,16 +728,36 @@ private function worldBorderCmd(CommandSender $sender,$args) { } else { $level = array_shift($args); } + } elseif (count($args) == 0) { + if (!$this->inGame($sender)) return false; + $level = $sender->getLevel()->getName(); } else { return $this->helpCmd($sender,["border"]); } if (!$this->doLoadWorldConfig($sender,$level)) return true; if (count($args) == 0) { + if(!isset($this->wcfg[$level]["border"])) { + $sender->sendMessage("[WP] No border for $level"); + return true; + } list($x1,$z1,$x2,$z2) = $this->wcfg[$level]["border"]; $sender->sendMessage("[WP] Border for $level is ($x1,$z1)-($x2,$z2)"); return true; } if (!$this->isAuth($sender,$level)) return true; + if (count($args) == 1 && is_numeric($args[0])) { + // Range was given... + $l = $this->getServer()->getLevelByName($level); + if ($l == null) { + $sender->sendMessage("[WP] Unable to load $level"); + return true; + } + $range = intval($args[0]); + $pos = $l->getSpawnLocation(); + $args = [ $pos->getX() - $range, $pos->getZ() - $range, + $pos->getX() + $range, $pos->getZ() + $range ]; + } + if (count($args) == 4) { list($x1,$z1,$x2,$z2) = $args; if ($x1 > $x2) list($x1,$x2) = [$x2,$x1]; @@ -570,6 +768,7 @@ private function worldBorderCmd(CommandSender $sender,$args) { } $this->wcfg[$level]["border"] = [$x1,$z1,$x2,$z2]; } else { + if (!isset($this->wcfg[$level]["border"])) { $sender->sendMessage("[WP] No border for $level currently"); return true; @@ -695,30 +894,26 @@ public function getWorldInfo($level) { } } if (isset($this->wcfg[$level]["protect"])) - $txt[] = "Protect Status: ".$this->wcfg[$level]["protect"]; - if ($this->checkPvP($level)) { - $txt[] = "PvP: ".TextFormat::RED."ON"; - } else { - $txt[] = "PvP: ".TextFormat::GREEN."OFF"; - } + $txt[] = TextFormat::AQUA."Protect Status: ". + TextFormat::WHITE.$this->wcfg[$level]["protect"]; + $txt[] = TextFormat::AQUA."PvP: ".$this->wpPvpMode($level); if (isset($this->wcfg[$level]["no-explode"])) { if ($this->wcfg[$level]["no-explode"] == "world") { - $txt[] = "NoExplode: ".TextFormat::GREEN."world"; + $txt[] = TextFormat::AQUA."NoExplode: ".TextFormat::GREEN."world"; } elseif ($this->wcfg[$level]["no-explode"] == "spawn") { - $txt[] = "NoExplode: ".TextFormat::YELLOW."spawn"; + $txt[] = TextFormat::AQUA."NoExplode: ".TextFormat::YELLOW."spawn"; } else { - $txt[]= "NoExplode: ".TextFormat::RED.$this->wcfg[$level]["no-explode"]; + $txt[]= TextFormat::AQUA."NoExplode: ".TextFormat::RED.$this->wcfg[$level]["no-explode"]; } } if (isset($this->wcfg[$level]["border"])) { - $txt[] = "World Borders:".implode(",",$this->wcfg[$level]["border"]); - } - if (isset($this->wcfg[$level]["max-players"])) { - $txt[] = "Max-Players: ".$this->wcfg[$level]["max-players"]; + $txt[] = TextFormat::AQUA."World Borders:". + TextFormat::WHITE.implode(",",$this->wcfg[$level]["border"]); } if (isset($this->wcfg[$level]["auth"]) && count($this->wcfg[$level]["auth"])) { - $txt[] = "Auth-List(".count($this->wcfg[$level]["auth"])."):". - implode(", ",$this->wcfg[$level]["auth"]); + $txt[] = TextFormat::AQUA. + "Auth-List(".count($this->wcfg[$level]["auth"])."):". + TextFormat::WHITE.implode(", ",$this->wcfg[$level]["auth"]); } return $txt; } diff --git a/src/aliuly/worldprotect/MaxPlayerMgr.php b/src/aliuly/worldprotect/MaxPlayerMgr.php new file mode 100644 index 0000000..9115186 --- /dev/null +++ b/src/aliuly/worldprotect/MaxPlayerMgr.php @@ -0,0 +1,46 @@ +owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + } + public function onTeleport(EntityTeleportEvent $ev){ + if ($ev->isCancelled()) return; + $et = $ev->getEntity(); + if (!($et instanceof Player)) return; + + $from = $ev->getFrom()->getLevel(); + $to = $ev->getTo()->getLevel(); + if (!$from) { + // THIS SHOULDN'T HAPPEN! + return; + } + if (!$to) { + // Somebody did not initialize the level properly! + // But we return because they do not intent to change worlds + return; + } + + $from = $from->getName(); + $to = $to->getName(); + + if ($from == $to) return; + $max = $this->owner->getPlayerLimit($to); + if ($max == 0) return; + $np = count($this->owner->getServer()->getLevelByName($to)->getPlayers()); + if($np >= $max) { + $ev->setCancelled(); + $et->sendMessage("Unable to teleport to $to\nWorld is full"); + $this->owner->getLogger()->info("$to is FULL"); + } + } +} diff --git a/src/aliuly/worldprotect/NoExplodeMgr.php b/src/aliuly/worldprotect/NoExplodeMgr.php index e33defc..4b2a242 100644 --- a/src/aliuly/worldprotect/NoExplodeMgr.php +++ b/src/aliuly/worldprotect/NoExplodeMgr.php @@ -7,18 +7,19 @@ use pocketmine\utils\TextFormat; class NoExplodeMgr implements Listener { - public $owner; - public function __construct(Plugin $plugin) { - $this->owner = $plugin; - $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); - } - public function onExplode(EntityExplodeEvent $ev){ - //echo __METHOD__.",".__LINE__."\n"; - $et = $ev->getEntity(); - if ($this->owner->checkNoExplode($et->getX(),$et->getY(),$et->getZ(), - $et->getLevel()->getName())) return; - $ev->setCancelled(); - $this->owner->getLogger()->info(TextFormat::RED. - "Explosion was stopped in ".$et->getLevel()->getName()); - } + public $owner; + public function __construct(Plugin $plugin) { + $this->owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + } + public function onExplode(EntityExplodeEvent $ev){ + //echo __METHOD__.",".__LINE__."\n"; + if ($ev->isCancelled()) return; + $et = $ev->getEntity(); + if ($this->owner->checkNoExplode($et->getX(),$et->getY(),$et->getZ(), + $et->getLevel()->getName())) return; + $ev->setCancelled(); + $this->owner->getLogger()->info(TextFormat::RED. + "Explosion was stopped in ".$et->getLevel()->getName()); + } } diff --git a/src/aliuly/worldprotect/PluginCallbackTask.php b/src/aliuly/worldprotect/PluginCallbackTask.php new file mode 100644 index 0000000..ae7cc86 --- /dev/null +++ b/src/aliuly/worldprotect/PluginCallbackTask.php @@ -0,0 +1,65 @@ +callable = $callable; + $this->args = $args; + $this->args[] = $this; + } + + /** + * @return callable + */ + public function getCallable(){ + return $this->callable; + } + + public function onRun($currentTicks){ + $c = $this->callable; + $args = $this->args; + $args[] = $currentTicks; + $c(...$args); + } + +} diff --git a/src/aliuly/worldprotect/WpBordersMgr.php b/src/aliuly/worldprotect/WpBordersMgr.php index 2b9945d..ba8a523 100644 --- a/src/aliuly/worldprotect/WpBordersMgr.php +++ b/src/aliuly/worldprotect/WpBordersMgr.php @@ -3,25 +3,23 @@ use pocketmine\plugin\PluginBase as Plugin; use pocketmine\event\Listener; - use pocketmine\event\player\PlayerMoveEvent; - use pocketmine\Player; -use pocketmine\scheduler\CallbackTask; class WpBordersMgr implements Listener { - public $owner; - public function __construct(Plugin $plugin) { - $this->owner = $plugin; - $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); - } - public function onPlayerMove(PlayerMoveEvent $ev) { - $pl = $ev->getPlayer(); - $pos = $ev->getTo(); - if ($this->owner->checkMove($pl->getLevel()->getName(), - $pos->getX(),$pos->getZ())) return; - $this->owner->msg($pl,"You have reached the end of the world"); - $ev->setCancelled(); - } -} \ No newline at end of file + public $owner; + public function __construct(Plugin $plugin) { + $this->owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + } + public function onPlayerMove(PlayerMoveEvent $ev) { + if ($ev->isCancelled()) return; + $pl = $ev->getPlayer(); + $pos = $ev->getTo(); + if ($this->owner->checkMove($pl->getLevel()->getName(), + $pos->getX(),$pos->getZ())) return; + $this->owner->msg($pl,"You have reached the end of the world"); + $ev->setCancelled(); + } +} diff --git a/src/aliuly/worldprotect/WpListener.php b/src/aliuly/worldprotect/WpListener.php index c8d6123..7e903c8 100644 --- a/src/aliuly/worldprotect/WpListener.php +++ b/src/aliuly/worldprotect/WpListener.php @@ -8,15 +8,15 @@ class WpListener implements Listener { - public function __construct(Plugin $plugin) { - $this->owner = $plugin; - $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); - } - // Make sure configs are loaded/unloaded - public function onLevelLoad(LevelLoadEvent $e) { - $this->owner->loadWorldConfig($e->getLevel()->getName()); - } - public function onLevelUnload(LevelUnloadEvent $e) { - $this->owner->unloadWorldConfig($e->getLevel()->getName()); - } + public function __construct(Plugin $plugin) { + $this->owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + } + // Make sure configs are loaded/unloaded + public function onLevelLoad(LevelLoadEvent $e) { + $this->owner->loadWorldConfig($e->getLevel()->getName()); + } + public function onLevelUnload(LevelUnloadEvent $e) { + $this->owner->unloadWorldConfig($e->getLevel()->getName()); + } } diff --git a/src/aliuly/worldprotect/WpMotdMgr.php b/src/aliuly/worldprotect/WpMotdMgr.php index 4f7463d..e04bde5 100644 --- a/src/aliuly/worldprotect/WpMotdMgr.php +++ b/src/aliuly/worldprotect/WpMotdMgr.php @@ -7,27 +7,26 @@ use pocketmine\event\entity\EntityLevelChangeEvent; use pocketmine\Player; -use pocketmine\scheduler\CallbackTask; class WpMotdMgr implements Listener { - public $owner; + public $owner; - public function __construct(Plugin $plugin) { - $this->owner = $plugin; - $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); - } - private function showMotd($name,$level,$ticks=10) { - $this->owner->getServer()->getScheduler()->scheduleDelayedTask(new CallbackTask([$this->owner,"showMotd"],[$name,$level]),$ticks); - } - public function onJoin(PlayerJoinEvent $ev) { - $pl = $ev->getPlayer(); - $this->showMotd($pl->getName(),$pl->getLevel()->getName()); - } - public function onLevelChange(EntityLevelChangeEvent $ev) { - $pl = $ev->getEntity(); - if (!($pl instanceof Player)) return; - $level = $ev->getTarget()->getName(); - $this->showMotd($pl->getName(),$level); - } -} \ No newline at end of file + public function __construct(Plugin $plugin) { + $this->owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + } + private function showMotd($name,$level,$ticks=10) { + $this->owner->getServer()->getScheduler()->scheduleDelayedTask(new PluginCallbackTask($this->owner,[$this->owner,"showMotd"],[$name,$level]),$ticks); + } + public function onJoin(PlayerJoinEvent $ev) { + $pl = $ev->getPlayer(); + $this->showMotd($pl->getName(),$pl->getLevel()->getName()); + } + public function onLevelChange(EntityLevelChangeEvent $ev) { + $pl = $ev->getEntity(); + if (!($pl instanceof Player)) return; + $level = $ev->getTarget()->getName(); + $this->showMotd($pl->getName(),$level); + } +} diff --git a/src/aliuly/worldprotect/WpProtectMgr.php b/src/aliuly/worldprotect/WpProtectMgr.php index cc6ca7b..f970571 100644 --- a/src/aliuly/worldprotect/WpProtectMgr.php +++ b/src/aliuly/worldprotect/WpProtectMgr.php @@ -8,70 +8,95 @@ use pocketmine\event\block\BlockBreakEvent; use pocketmine\event\block\BlockPlaceEvent; use pocketmine\event\block\SignChangeEvent; +use pocketmine\tile\Sign; +use pocketmine\math\Vector3; //use pocketmine\event\player\PlayerInteractEvent; // Not used for now... //use pocketmine\event\entity\EntityExplodeEvent; // Also not used... class WpProtectMgr implements Listener { - public $owner; - protected $signs; + public $owner; + protected $signs; - static protected function blockAddr(Block $block) { - $l = $block->getLevel()->getName(); - $x = $block->getX(); - $y = $block->getY(); - $z = $block->getZ(); - return implode(":",[$l,$x,$y,$z]); - } + static protected function blockAddr(Block $block) { + $l = $block->getLevel()->getName(); + $x = $block->getX(); + $y = $block->getY(); + $z = $block->getZ(); + return implode(":",[$l,$x,$y,$z]); + } + public function __construct(Plugin $plugin) { + $this->owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + $signs = []; + } + public function onBlockBreak(BlockBreakEvent $ev){ + if ($ev->isCancelled()) return; + $pl = $ev->getPlayer(); + if ($this->owner->checkUnbreakable($pl->getName(), + $pl->getLevel()->getName(), + $ev->getBlock()->getId())) { + $ev->setCancelled(); + $this->owner->msg($pl,"It cannot be broken"); + return; + } + if ($this->owner->checkBlockPlaceBreak($pl->getName(), + $pl->getLevel()->getName())) return; + $this->owner->msg($pl,"You are not allowed to do that here"); + $ev->setCancelled(); + } + public function onSignChanged(SignChangeEvent $ev){ + if ($ev->isCancelled()) return; + $h = self::blockAddr($ev->getBlock()); + if (!isset($this->signs[$h])) return; + list($id,$meta,$cnt,$time) = $this->signs[$h]; - public function __construct(Plugin $plugin) { - $this->owner = $plugin; - $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); - $signs = []; - } + // API check... + $api = explode(".",$this->owner->getServer()->getApiVersion()); + if (intval($api[1]) < 12) { + if ($cnt == 0) { + $this->signs[$h][2] = 1; + return; + } + } + unset($this->signs[$h]); + $block =$ev->getBlock(); + $l = $block->getLevel(); + $x = $block->getX(); + $y = $block->getY(); + $z = $block->getZ(); + $l->setBlockIdAt($x,$y,$z,$id); + $l->setBlockDataAt($x,$y,$z,$meta); - public function onBlockBreak(BlockBreakEvent $ev){ - $pl = $ev->getPlayer(); - if ($this->owner->checkBlockPlaceBreak($pl->getName(), - $pl->getLevel()->getName())) return; - $this->owner->msg($pl,"You are not allowed to do that here"); - $ev->setCancelled(); - } - public function onSignChanged(SignChangeEvent $ev){ - $h = self::blockAddr($ev->getBlock()); - if (!isset($this->signs[$h])) return; + $tt = new PluginCallbackTask($this->owner,[$this,"ripSign"],[$l->getName(),$x,$y,$z]); + $this->owner->getServer()->getScheduler()->scheduleDelayedTask($tt,10); + } - list($id,$meta,$cnt,$time) = $this->signs[$h]; - if ($cnt == 0) { - $this->signs[$h][2] = 1; - return; - } - unset($this->sings[$h]); - $block =$ev->getBlock(); - $l = $block->getLevel(); - $x = $block->getX(); - $y = $block->getY(); - $z = $block->getZ(); - $l->setBlockIdAt($x,$y,$z,$id); - $l->setBlockDataAt($x,$y,$z,$meta); - } + public function ripSign($level,$x,$y,$z) { + $l = $this->owner->getServer()->getLevelByName($level); + if (!$l) return; + $sign = $l->getTile(new Vector3($x,$y,$z)); + if ($sign instanceof Sign) $sign->close(); + } - public function onBlockPlace(BlockPlaceEvent $ev){ - $pl = $ev->getPlayer(); - if ($this->owner->checkBlockPlaceBreak($pl->getName(), - $pl->getLevel()->getName())) return; - $this->owner->msg($pl,"You are not allowed to do that here"); - $id = $ev->getBlock()->getId(); - if ($id == 63) { - // Oh no.. placing a SignPost! - $h = self::blockAddr($ev->getBlock()); - $this->signs[$h] = [ $ev->getBlockReplaced()->getId(), - $ev->getBlockReplaced()->getDamage(), - 0, time() ]; - return; - } - $ev->setCancelled(); - } -} \ No newline at end of file + public function onBlockPlace(BlockPlaceEvent $ev){ + if ($ev->isCancelled()) return; + $pl = $ev->getPlayer(); + if ($this->owner->checkBlockPlaceBreak($pl->getName(), + $pl->getLevel()->getName())) return; + $this->owner->msg($pl,"You are not allowed to do that here"); + $id = $ev->getBlock()->getId(); + + if ($id == Block::SIGN_POST || $id == Block::WALL_SIGN) { + // Oh no.. placing a SignPost! + $h = self::blockAddr($ev->getBlock()); + $this->signs[$h] = [ $ev->getBlockReplaced()->getId(), + $ev->getBlockReplaced()->getDamage(), + 0, time() ]; + return; + } + $ev->setCancelled(); + } +} diff --git a/src/aliuly/worldprotect/WpPvpMgr.php b/src/aliuly/worldprotect/WpPvpMgr.php index 4b81ff9..03d19a6 100644 --- a/src/aliuly/worldprotect/WpPvpMgr.php +++ b/src/aliuly/worldprotect/WpPvpMgr.php @@ -4,23 +4,25 @@ use pocketmine\plugin\PluginBase as Plugin; use pocketmine\event\Listener; - use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\Player; class WpPvpMgr implements Listener { - public $owner; - public function __construct(Plugin $plugin) { - $this->owner = $plugin; - $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); - } - public function onPvP(EntityDamageEvent $ev) { - if(!($ev instanceof EntityDamageByEntityEvent)) return; - if (!($ev->getEntity() instanceof Player && $ev->getDamager() instanceof Player)) return; - if ($this->owner->checkPvP($ev->getEntity()->getLevel()->getName())) return; - $this->owner->msg($ev->getDamager(),"You are not allowed to do that here"); - $ev->setCancelled(); - } -} \ No newline at end of file + public $owner; + public function __construct(Plugin $plugin) { + $this->owner = $plugin; + $this->owner->getServer()->getPluginManager()->registerEvents($this, $this->owner); + } + public function onPvP(EntityDamageEvent $ev) { + if ($ev->isCancelled()) return; + if(!($ev instanceof EntityDamageByEntityEvent)) return; + if (!(($pl = $ev->getEntity()) instanceof Player + && $ev->getDamager() instanceof Player)) return; + if ($this->owner->checkPvP($pl->getLevel()->getName(), + $pl->getX(),$pl->getY(),$pl->getZ())) return; + $this->owner->msg($ev->getDamager(),"You are not allowed to do that here"); + $ev->setCancelled(); + } +}