├── .gitignore
├── LICENSE
├── README.md
├── plugin.yml
└── src
├── DevTools
├── ConsoleScript.php
├── DevTools.php
└── commands
│ ├── DevToolsCommand.php
│ └── ExtractPluginCommand.php
└── FolderPluginLoader
├── FolderPluginLoader.php
└── Main.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Development Tools for PocketMine-MP
2 |
3 | ### Warning: This version is for the new PocketMine-MP API
4 |
5 | This program is free software: you can redistribute it and/or modify
6 | it under the terms of the GNU Lesser General Public License as published by
7 | the Free Software Foundation, either version 3 of the License, or
8 | (at your option) any later version.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU Lesser General Public License for more details.
14 |
15 | You should have received a copy of the GNU Lesser General Public License
16 | along with this program. If not, see .
17 |
18 |
19 | ## Installation
20 | - Drop it into the PocketMine's `plugins/` folder.
21 | - Restart the server. The plugin will be loaded
22 |
23 | ## Usage
24 | * _/makeplugin _: Creates a Phar plugin archive for its distribution
25 | * _/makeserver_: Creates a PocketMine-MP Phar archive
26 | * _/checkperm [playerName]_: Checks a permission node
27 |
28 | ## Create .phar from console
29 | Download [DevTools.phar](https://github.com/PocketMine/DevTools/releases)
30 |
31 | php -dphar.readonly=0 DevTools.phar \
32 | --make="./plugin/" \
33 | --relative="./plugin/" \
34 | --out "plugin.phar"
35 |
36 | or [ConsoleScript.php](https://github.com/PocketMine/DevTools/blob/master/src/DevTools/ConsoleScript.php)
37 |
38 | php -dphar.readonly=0 ConsoleScript.php \
39 | --make="./plugin/" \
40 | --relative="./plugin/" \
41 | --out "plugin.phar"
42 |
--------------------------------------------------------------------------------
/plugin.yml:
--------------------------------------------------------------------------------
1 | name: DevTools
2 | main: DevTools\DevTools
3 | version: 1.11.0
4 | api: 2.0.0
5 | load: STARTUP
6 | author: PocketMine Team
7 | description: Helps develop and distribute PocketMine-MP plugins
8 | website: https://github.com/PocketMine/DevTools
9 | commands:
10 | makeserver:
11 | description: Creates a PocketMine-MP Phar
12 | usage: "/makeserver"
13 | permission: devtools.command.makeserver
14 | makeplugin:
15 | description: Creates a Phar plugin from one in source code form
16 | usage: "/makeplugin "
17 | permission: devtools.command.makeplugin
18 | checkperm:
19 | description: Checks a permission value for the current sender, or a player
20 | usage: "/checkperm [playerName]"
21 | permission: "devtools.command.checkperm;devtools.command.checkperm.other"
22 | permissions:
23 | devtools:
24 | default: op
25 | description: "Allows using all the DevTools things"
26 | children:
27 | devtools.command:
28 | default: op
29 | description: "Allows using all the DevTools commands"
30 | children:
31 | devtools.command.makeplugin:
32 | default: op
33 | description: "Allows the creation of Phar plugins"
34 | devtools.command.extractplugin:
35 | default: op
36 | description: "Allows the extraction of Phar plugins"
37 | devtools.command.makeserver:
38 | default: op
39 | description: "Allows the creation of a PocketMine-MP Phar"
40 | devtools.command.checkperm:
41 | default: true
42 | description: "Allows checking a permission value"
43 | children:
44 | devtools.command.checkperm.other:
45 | default: op
46 | description: "Allows checking others permission value"
47 |
--------------------------------------------------------------------------------
/src/DevTools/ConsoleScript.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | */
17 |
18 | const VERSION = "1.11.0";
19 |
20 | $opts = getopt("", ["make:", "relative:", "out:", "entry:", "compress"]);
21 |
22 | if(!isset($opts["make"])){
23 | echo "== PocketMine-MP DevTools CLI interface ==\n\n";
24 | echo "Usage: ". PHP_BINARY ." -dphar.readonly=0 ".$argv[0]." --make --relative --entry \"relativeSourcePath.php\" --out \n";
25 | exit(0);
26 | }
27 |
28 | if(ini_get("phar.readonly") == 1){
29 | echo "Set phar.readonly to 0 with -dphar.readonly=0\n";
30 | exit(1);
31 | }
32 |
33 | $folderPath = rtrim(str_replace("\\", "/", realpath($opts["make"])), "/") . "/";
34 | $relativePath = isset($opts["relative"]) ? rtrim(str_replace("\\", "/", realpath($opts["relative"])), "/") . "/" : $folderPath;
35 | $pharName = isset($opts["out"]) ? $opts["out"] : "output.phar";
36 |
37 |
38 |
39 | if(!is_dir($folderPath)){
40 | echo $folderPath ." is not a folder\n";
41 | exit(1);
42 | }
43 |
44 | echo "\nCreating ".$pharName."...\n";
45 | $phar = new \Phar($pharName);
46 | if($metadata["name"] === "DevTools"){
47 | $phar->setStub('setStub('setMetadata([
56 | "name" => $metadata["name"],
57 | "version" => $metadata["version"],
58 | "main" => $metadata["main"],
59 | "api" => $metadata["api"],
60 | "depend" => (isset($metadata["depend"]) ? $metadata["depend"] : ""),
61 | "description" => (isset($metadata["description"]) ?$metadata["description"] : ""),
62 | "authors" => (isset($metadata["authors"]) ? $metadata["authors"] : ""),
63 | "website" => (isset($metadata["website"]) ? $metadata["website"] : ""),
64 | "creationDate" => time()
65 | ]);
66 | $phar->setStub('getMetadata() as $key => $value){echo ucfirst($key).": ".(is_array($value) ? implode(", ", $value):$value)."\n";}} __HALT_COMPILER();');
67 | }else{
68 | echo "Missing entry point or plugin.yml\n";
69 | exit(1);
70 | }
71 | }
72 | $phar->setSignatureAlgorithm(\Phar::SHA1);
73 | $phar->startBuffering();
74 | echo "Adding files...\n";
75 | $maxLen = 0;
76 | $count = 0;
77 | foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folderPath)) as $file){
78 | $path = rtrim(str_replace(["\\", $relativePath], ["/", ""], $file), "/");
79 | if($path{0} === "." or strpos($path, "/.") !== false){
80 | continue;
81 | }
82 | $phar->addFile($file, $path);
83 | if(strlen($path) > $maxLen){
84 | $maxLen = strlen($path);
85 | }
86 | echo "\r[".(++$count)."] ".str_pad($path, $maxLen, " ");
87 | }
88 |
89 | $phar->stopBuffering();
90 |
91 | echo "Done!\n";
92 | exit(0);
--------------------------------------------------------------------------------
/src/DevTools/DevTools.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | */
17 |
18 | namespace DevTools;
19 |
20 | use DevTools\commands\ExtractPluginCommand;
21 | use FolderPluginLoader\FolderPluginLoader;
22 | use pocketmine\command\Command;
23 | use pocketmine\command\CommandExecutor;
24 | use pocketmine\command\CommandSender;
25 | use pocketmine\network\protocol\Info;
26 | use pocketmine\permission\Permission;
27 | use pocketmine\Player;
28 | use pocketmine\plugin\Plugin;
29 | use pocketmine\plugin\PluginBase;
30 | use pocketmine\plugin\PluginLoadOrder;
31 | use pocketmine\Server;
32 | use pocketmine\utils\TextFormat;
33 |
34 | class DevTools extends PluginBase implements CommandExecutor{
35 |
36 | public function onLoad(){
37 | $this->getServer()->getCommandMap()->register("devtools", new ExtractPluginCommand($this));
38 | }
39 |
40 | public function onEnable(){
41 | @mkdir($this->getDataFolder());
42 |
43 | if(!class_exists("FolderPluginLoader\\FolderPluginLoader", false)){
44 | $this->getServer()->getPluginManager()->registerInterface("FolderPluginLoader\\FolderPluginLoader");
45 | $this->getServer()->getPluginManager()->loadPlugins($this->getServer()->getPluginPath(), ["FolderPluginLoader\\FolderPluginLoader"]);
46 | $this->getLogger()->info("Registered folder plugin loader");
47 | $this->getServer()->enablePlugins(PluginLoadOrder::STARTUP);
48 | }
49 | }
50 |
51 | public function onCommand(CommandSender $sender, Command $command, $label, array $args){
52 | switch($command->getName()){
53 | case "makeplugin":
54 | if(isset($args[0]) and $args[0] === "FolderPluginLoader"){
55 | return $this->makePluginLoader($sender, $command, $label, $args);
56 | }else{
57 | return $this->makePluginCommand($sender, $command, $label, $args);
58 | }
59 | case "makeserver":
60 | return $this->makeServerCommand($sender, $command, $label, $args);
61 | case "checkperm":
62 | return $this->permissionCheckCommand($sender, $command, $label, $args);
63 | default:
64 | return false;
65 | }
66 | }
67 |
68 | private function permissionCheckCommand(CommandSender $sender, Command $command, $label, array $args){
69 | $target = $sender;
70 | if(!isset($args[0])){
71 | return false;
72 | }
73 | $node = strtolower($args[0]);
74 | if(isset($args[1])){
75 | if(($player = $this->getServer()->getPlayer($args[1])) instanceof Player){
76 | $target = $player;
77 | }else{
78 | return false;
79 | }
80 | }
81 |
82 | if($target !== $sender and !$sender->hasPermission("devtools.command.checkperm.other")){
83 | $sender->sendMessage(TextFormat::RED . "You do not have permissions to check other players.");
84 | return true;
85 | }else{
86 | $sender->sendMessage(TextFormat::GREEN . "---- ".TextFormat::WHITE . "Permission node ".$node.TextFormat::GREEN. " ----");
87 | $perm = $this->getServer()->getPluginManager()->getPermission($node);
88 | if($perm instanceof Permission){
89 | $desc = TextFormat::GOLD . "Description: ".TextFormat::WHITE . $perm->getDescription()."\n";
90 | $desc .= TextFormat::GOLD . "Default: ".TextFormat::WHITE . $perm->getDefault()."\n";
91 | $children = "";
92 | foreach($perm->getChildren() as $name => $true){
93 | $children .= $name . ", ";
94 | }
95 | $desc .= TextFormat::GOLD . "Children: ".TextFormat::WHITE . substr($children, 0, -2)."\n";
96 | }else{
97 | $desc = TextFormat::RED . "Permission does not exist\n";
98 | $desc .= TextFormat::GOLD . "Default: ".TextFormat::WHITE . Permission::$DEFAULT_PERMISSION."\n";
99 | }
100 | $sender->sendMessage($desc);
101 | $sender->sendMessage(TextFormat::YELLOW . $target->getName() . TextFormat::WHITE . " has it set to ".($target->hasPermission($node) === true ? TextFormat::GREEN . "true" : TextFormat::RED . "false"));
102 | return true;
103 | }
104 | }
105 |
106 | private function makePluginLoader(CommandSender $sender, Command $command, $label, array $args){
107 | $pharPath = $this->getDataFolder() . DIRECTORY_SEPARATOR . "FolderPluginLoader.phar";
108 | if(file_exists($pharPath)){
109 | $sender->sendMessage("Phar plugin already exists, overwriting...");
110 | @unlink($pharPath);
111 | }
112 | $phar = new \Phar($pharPath);
113 | $phar->setMetadata([
114 | "name" => "FolderPluginLoader",
115 | "version" => "1.0.0",
116 | "main" => "FolderPluginLoader\\Main",
117 | "api" => ["1.0.0"],
118 | "depend" => [],
119 | "description" => "Loader of folder plugins",
120 | "authors" => ["PocketMine Team"],
121 | "website" => "https://github.com/PocketMine/DevTools",
122 | "creationDate" => time()
123 | ]);
124 | $phar->setStub('setSignatureAlgorithm(\Phar::SHA1);
126 | $phar->startBuffering();
127 |
128 | $phar->addFromString("plugin.yml", "name: FolderPluginLoader\nversion: 1.0.0\nmain: FolderPluginLoader\\Main\napi: [1.0.0]\nload: STARTUP\n");
129 | $phar->addFile($this->getFile() . "src/FolderPluginLoader/FolderPluginLoader.php", "src/FolderPluginLoader/FolderPluginLoader.php");
130 | $phar->addFile($this->getFile() . "src/FolderPluginLoader/Main.php", "src/FolderPluginLoader/Main.php");
131 |
132 | foreach($phar as $file => $finfo){
133 | /** @var \PharFileInfo $finfo */
134 | if($finfo->getSize() > (1024 * 512)){
135 | $finfo->compress(\Phar::GZ);
136 | }
137 | }
138 | $phar->stopBuffering();
139 | $sender->sendMessage("Folder plugin loader has been created on ".$pharPath);
140 | return true;
141 | }
142 |
143 | private function makePluginCommand(CommandSender $sender, Command $command, $label, array $args){
144 | $pluginName = trim(implode(" ", $args));
145 | if($pluginName === "" or !(($plugin = Server::getInstance()->getPluginManager()->getPlugin($pluginName)) instanceof Plugin)){
146 | $sender->sendMessage(TextFormat::RED . "Invalid plugin name, check the name case.");
147 | return true;
148 | }
149 | $description = $plugin->getDescription();
150 |
151 | if(!($plugin->getPluginLoader() instanceof FolderPluginLoader)){
152 | $sender->sendMessage(TextFormat::RED . "Plugin ".$description->getName()." is not in folder structure.");
153 | return true;
154 | }
155 |
156 | $pharPath = $this->getDataFolder() . DIRECTORY_SEPARATOR . $description->getName()."_v".$description->getVersion().".phar";
157 | if(file_exists($pharPath)){
158 | $sender->sendMessage("Phar plugin already exists, overwriting...");
159 | @unlink($pharPath);
160 | }
161 | $phar = new \Phar($pharPath);
162 | $phar->setMetadata([
163 | "name" => $description->getName(),
164 | "version" => $description->getVersion(),
165 | "main" => $description->getMain(),
166 | "api" => $description->getCompatibleApis(),
167 | "depend" => $description->getDepend(),
168 | "description" => $description->getDescription(),
169 | "authors" => $description->getAuthors(),
170 | "website" => $description->getWebsite(),
171 | "creationDate" => time()
172 | ]);
173 | if($description->getName() === "DevTools"){
174 | $phar->setStub('setStub('getName() .' v'.$description->getVersion().'\nThis file has been generated using DevTools v'.$this->getDescription()->getVersion().' at '.date("r").'\n----------------\n";if(extension_loaded("phar")){$phar = new \Phar(__FILE__);foreach($phar->getMetadata() as $key => $value){echo ucfirst($key).": ".(is_array($value) ? implode(", ", $value):$value)."\n";}} __HALT_COMPILER();');
177 | }
178 | $phar->setSignatureAlgorithm(\Phar::SHA1);
179 | $reflection = new \ReflectionClass("pocketmine\\plugin\\PluginBase");
180 | $file = $reflection->getProperty("file");
181 | $file->setAccessible(true);
182 | $filePath = rtrim(str_replace("\\", "/", $file->getValue($plugin)), "/") . "/";
183 | $phar->startBuffering();
184 | foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($filePath)) as $file){
185 | $path = ltrim(str_replace(["\\", $filePath], ["/", ""], $file), "/");
186 | if($path{0} === "." or strpos($path, "/.") !== false){
187 | continue;
188 | }
189 | $phar->addFile($file, $path);
190 | $sender->sendMessage("[DevTools] Adding $path");
191 | }
192 |
193 | foreach($phar as $file => $finfo){
194 | /** @var \PharFileInfo $finfo */
195 | if($finfo->getSize() > (1024 * 512)){
196 | $finfo->compress(\Phar::GZ);
197 | }
198 | }
199 | $phar->stopBuffering();
200 | $sender->sendMessage("Phar plugin ".$description->getName() ." v".$description->getVersion()." has been created on ".$pharPath);
201 | return true;
202 | }
203 |
204 | private function makeServerCommand(CommandSender $sender, Command $command, $label, array $args){
205 | $server = $sender->getServer();
206 | $pharPath = $this->getDataFolder() . DIRECTORY_SEPARATOR . $server->getName()."_".$server->getPocketMineVersion().".phar";
207 | if(file_exists($pharPath)){
208 | $sender->sendMessage("Phar file already exists, overwriting...");
209 | @unlink($pharPath);
210 | }
211 | $phar = new \Phar($pharPath);
212 | $phar->setMetadata([
213 | "name" => $server->getName(),
214 | "version" => $server->getPocketMineVersion(),
215 | "api" => $server->getApiVersion(),
216 | "minecraft" => $server->getVersion(),
217 | "protocol" => Info::CURRENT_PROTOCOL,
218 | "creationDate" => time()
219 | ]);
220 | $phar->setStub('setSignatureAlgorithm(\Phar::SHA1);
222 | $phar->startBuffering();
223 |
224 | $filePath = substr(\pocketmine\PATH, 0, 7) === "phar://" ? \pocketmine\PATH : realpath(\pocketmine\PATH) . "/";
225 | $filePath = rtrim(str_replace("\\", "/", $filePath), "/") . "/";
226 | foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($filePath . "src")) as $file){
227 | $path = ltrim(str_replace(["\\", $filePath], ["/", ""], $file), "/");
228 | if($path{0} === "." or strpos($path, "/.") !== false or substr($path, 0, 4) !== "src/"){
229 | continue;
230 | }
231 | $phar->addFile($file, $path);
232 | $sender->sendMessage("[DevTools] Adding $path");
233 | }
234 | foreach($phar as $file => $finfo){
235 | /** @var \PharFileInfo $finfo */
236 | if($finfo->getSize() > (1024 * 512)){
237 | $finfo->compress(\Phar::GZ);
238 | }
239 | }
240 | $phar->stopBuffering();
241 |
242 | $sender->sendMessage($server->getName() . " " . $server->getPocketMineVersion() . " Phar file has been created on ".$pharPath);
243 |
244 | return true;
245 | }
246 |
247 | }
--------------------------------------------------------------------------------
/src/DevTools/commands/DevToolsCommand.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | */
17 |
18 | namespace DevTools\commands;
19 |
20 | use DevTools\DevTools;
21 | use pocketmine\command\Command;
22 | use pocketmine\command\PluginIdentifiableCommand;
23 |
24 | abstract class DevToolsCommand extends Command implements PluginIdentifiableCommand{
25 | /** @var \pocketmine\plugin\Plugin */
26 | private $owningPlugin;
27 |
28 | public function __construct($name, DevTools $plugin){
29 | parent::__construct($name);
30 | $this->owningPlugin = $plugin;
31 | $this->usageMessage = "";
32 | }
33 |
34 | public function getPlugin(){
35 | return $this->owningPlugin;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/DevTools/commands/ExtractPluginCommand.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | */
17 |
18 | namespace DevTools\commands;
19 |
20 | use DevTools\DevTools;
21 | use pocketmine\command\CommandSender;
22 | use pocketmine\plugin\PharPluginLoader;
23 | use pocketmine\plugin\Plugin;
24 | use pocketmine\Server;
25 | use pocketmine\utils\TextFormat;
26 |
27 | class ExtractPluginCommand extends DevToolsCommand{
28 |
29 | public function __construct(DevTools $plugin){
30 | parent::__construct("extractplugin", $plugin);
31 | $this->setUsage("/extractplugin ");
32 | $this->setDescription("Extracts the source code from a Phar plugin");
33 | $this->setPermission("devtools.command.extractplugin");
34 | }
35 |
36 | public function execute(CommandSender $sender, $commandLabel, array $args){
37 | if(!$this->getPlugin()->isEnabled()){
38 | return false;
39 | }
40 |
41 | if(!$this->testPermission($sender)){
42 | return false;
43 | }
44 |
45 | if(count($args) === 0){
46 | $sender->sendMessage(TextFormat::RED . "Usage: ".$this->usageMessage);
47 | return true;
48 | }
49 |
50 | $pluginName = trim(implode(" ", $args));
51 | if($pluginName === "" or !(($plugin = Server::getInstance()->getPluginManager()->getPlugin($pluginName)) instanceof Plugin)){
52 | $sender->sendMessage(TextFormat::RED . "Invalid plugin name, check the name case.");
53 | return true;
54 | }
55 | $description = $plugin->getDescription();
56 |
57 | if(!($plugin->getPluginLoader() instanceof PharPluginLoader)){
58 | $sender->sendMessage(TextFormat::RED . "Plugin ".$description->getName()." is not in Phar structure.");
59 | return true;
60 | }
61 |
62 | $folderPath = $this->getPlugin()->getDataFolder() . DIRECTORY_SEPARATOR . $description->getName()."_v".$description->getVersion()."/";
63 | if(file_exists($folderPath)){
64 | $sender->sendMessage("Plugin already exists, overwriting...");
65 | }else{
66 | @mkdir($folderPath);
67 | }
68 |
69 | $reflection = new \ReflectionClass("pocketmine\\plugin\\PluginBase");
70 | $file = $reflection->getProperty("file");
71 | $file->setAccessible(true);
72 | $pharPath = str_replace("\\", "/", rtrim($file->getValue($plugin), "\\/"));
73 |
74 | foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($pharPath)) as $fInfo){
75 | $path = $fInfo->getPathname();
76 | @mkdir(dirname($folderPath . str_replace($pharPath, "", $path)), 0755, true);
77 | file_put_contents($folderPath . str_replace($pharPath, "", $path), file_get_contents($path));
78 | }
79 | $sender->sendMessage("Source plugin ".$description->getName() ." v".$description->getVersion()." has been created on ".$folderPath);
80 | return true;
81 | }
82 | }
--------------------------------------------------------------------------------
/src/FolderPluginLoader/FolderPluginLoader.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | */
17 |
18 | namespace FolderPluginLoader;
19 |
20 | use pocketmine\event\plugin\PluginDisableEvent;
21 | use pocketmine\event\plugin\PluginEnableEvent;
22 | use pocketmine\plugin\Plugin;
23 | use pocketmine\plugin\PluginBase;
24 | use pocketmine\plugin\PluginDescription;
25 | use pocketmine\plugin\PluginLoader;
26 | use pocketmine\Server;
27 | use pocketmine\utils\MainLogger;
28 | use pocketmine\utils\TextFormat;
29 |
30 | class FolderPluginLoader implements PluginLoader{
31 |
32 | /** @var Server */
33 | private $server;
34 |
35 | /**
36 | * @param Server $server
37 | */
38 | public function __construct(Server $server){
39 | $this->server = $server;
40 | }
41 |
42 | /**
43 | * Loads the plugin contained in $file
44 | *
45 | * @param string $file
46 | *
47 | * @return Plugin
48 | */
49 | public function loadPlugin($file){
50 | if(is_dir($file) and file_exists($file . "/plugin.yml") and file_exists($file . "/src/")){
51 | if(($description = $this->getPluginDescription($file)) instanceof PluginDescription){
52 | MainLogger::getLogger()->info(TextFormat::LIGHT_PURPLE."Loading source plugin " . $description->getFullName());
53 | $dataFolder = dirname($file) . DIRECTORY_SEPARATOR . $description->getName();
54 | if(file_exists($dataFolder) and !is_dir($dataFolder)){
55 | trigger_error("Projected dataFolder '" . $dataFolder . "' for " . $description->getName() . " exists and is not a directory", E_USER_WARNING);
56 |
57 | return null;
58 | }
59 |
60 |
61 | $className = $description->getMain();
62 | $this->server->getLoader()->addPath($file . "/src");
63 |
64 | if(class_exists($className, true)){
65 | $plugin = new $className();
66 | $this->initPlugin($plugin, $description, $dataFolder, $file);
67 |
68 | return $plugin;
69 | }else{
70 | trigger_error("Couldn't load source plugin " . $description->getName() . ": main class not found", E_USER_WARNING);
71 |
72 | return null;
73 | }
74 | }
75 | }
76 |
77 | return null;
78 | }
79 |
80 | /**
81 | * Gets the PluginDescription from the file
82 | *
83 | * @param string $file
84 | *
85 | * @return PluginDescription
86 | */
87 | public function getPluginDescription($file){
88 | if(is_dir($file) and file_exists($file . "/plugin.yml")){
89 | $yaml = @file_get_contents($file . "/plugin.yml");
90 | if($yaml != ""){
91 | return new PluginDescription($yaml);
92 | }
93 | }
94 |
95 | return null;
96 | }
97 |
98 | /**
99 | * Returns the filename patterns that this loader accepts
100 | *
101 | * @return array
102 | */
103 | public function getPluginFilters(){
104 | return "/[^\\.]/";
105 | }
106 |
107 | /**
108 | * @param PluginBase $plugin
109 | * @param PluginDescription $description
110 | * @param string $dataFolder
111 | * @param string $file
112 | */
113 | private function initPlugin(PluginBase $plugin, PluginDescription $description, $dataFolder, $file){
114 | $plugin->init($this, $this->server, $description, $dataFolder, $file);
115 | $plugin->onLoad();
116 | }
117 |
118 | /**
119 | * @param Plugin $plugin
120 | */
121 | public function enablePlugin(Plugin $plugin){
122 | if($plugin instanceof PluginBase and !$plugin->isEnabled()){
123 | MainLogger::getLogger()->info("Enabling " . $plugin->getDescription()->getFullName());
124 |
125 | $plugin->setEnabled(true);
126 |
127 | Server::getInstance()->getPluginManager()->callEvent(new PluginEnableEvent($plugin));
128 | }
129 | }
130 |
131 | /**
132 | * @param Plugin $plugin
133 | */
134 | public function disablePlugin(Plugin $plugin){
135 | if($plugin instanceof PluginBase and $plugin->isEnabled()){
136 | MainLogger::getLogger()->info("Disabling " . $plugin->getDescription()->getFullName());
137 |
138 | Server::getInstance()->getPluginManager()->callEvent(new PluginDisableEvent($plugin));
139 |
140 | $plugin->setEnabled(false);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/FolderPluginLoader/Main.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This program is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | */
17 |
18 | namespace FolderPluginLoader;
19 |
20 | use pocketmine\plugin\PluginBase;
21 | use pocketmine\plugin\PluginLoadOrder;
22 |
23 | class Main extends PluginBase{
24 |
25 | public function onLoad(){
26 |
27 | }
28 |
29 | public function onEnable(){
30 | $this->getServer()->getPluginManager()->registerInterface("FolderPluginLoader\\FolderPluginLoader");
31 | $this->getServer()->getPluginManager()->loadPlugins($this->getServer()->getPluginPath(), ["FolderPluginLoader\\FolderPluginLoader"]);
32 | $this->getServer()->enablePlugins(PluginLoadOrder::STARTUP);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------