PocketMine-MP 5.15.1 git-5ef247620a7c6301a849b54e5ef1009217729fc8
PluginDescription.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\plugin;
25
29use function array_map;
30use function array_values;
31use function get_debug_type;
32use function is_array;
33use function is_string;
34use function preg_match;
35use function str_replace;
36use function stripos;
37use function yaml_parse;
38
40 private const KEY_NAME = "name";
41 private const KEY_VERSION = "version";
42 private const KEY_MAIN = "main";
43 private const KEY_SRC_NAMESPACE_PREFIX = "src-namespace-prefix";
44 private const KEY_API = "api";
45 private const KEY_MCPE_PROTOCOL = "mcpe-protocol";
46 private const KEY_OS = "os";
47 private const KEY_DEPEND = "depend";
48 private const KEY_SOFTDEPEND = "softdepend";
49 private const KEY_LOADBEFORE = "loadbefore";
50 private const KEY_EXTENSIONS = "extensions";
51 private const KEY_WEBSITE = "website";
52 private const KEY_DESCRIPTION = "description";
53 private const KEY_LOGGER_PREFIX = "prefix";
54 private const KEY_LOAD = "load";
55 private const KEY_AUTHOR = "author";
56 private const KEY_AUTHORS = "authors";
57 private const KEY_PERMISSIONS = "permissions";
58
59 private const KEY_COMMANDS = "commands";
60 private const KEY_COMMAND_PERMISSION = "permission";
61 private const KEY_COMMAND_DESCRIPTION = self::KEY_DESCRIPTION;
62 private const KEY_COMMAND_USAGE = "usage";
63 private const KEY_COMMAND_ALIASES = "aliases";
64 private const KEY_COMMAND_PERMISSION_MESSAGE = "permission-message";
65
70 private array $map;
71
72 private string $name;
73 private string $main;
74 private string $srcNamespacePrefix = "";
76 private array $api;
78 private array $compatibleMcpeProtocols = [];
80 private array $compatibleOperatingSystems = [];
85 private array $extensions = [];
87 private array $depend = [];
89 private array $softDepend = [];
91 private array $loadBefore = [];
92 private string $version;
97 private array $commands = [];
98 private string $description = "";
100 private array $authors = [];
101 private string $website = "";
102 private string $prefix = "";
103 private PluginEnableOrder $order;
104
109 private array $permissions = [];
110
114 public function __construct(array|string $yamlString){
115 if(is_string($yamlString)){
116 $map = yaml_parse($yamlString);
117 if($map === false){
118 throw new PluginDescriptionParseException("YAML parsing error in plugin manifest");
119 }
120 if(!is_array($map)){
121 throw new PluginDescriptionParseException("Invalid structure of plugin manifest, expected array but have " . get_debug_type($map));
122 }
123 }else{
124 $map = $yamlString;
125 }
126 $this->loadMap($map);
127 }
128
133 private function loadMap(array $plugin) : void{
134 $this->map = $plugin;
135
136 $this->name = $plugin[self::KEY_NAME];
137 if(preg_match('/^[A-Za-z0-9 _.-]+$/', $this->name) === 0){
138 throw new PluginDescriptionParseException("Invalid Plugin name");
139 }
140 $this->name = str_replace(" ", "_", $this->name);
141 $this->version = (string) $plugin[self::KEY_VERSION];
142 $this->main = $plugin[self::KEY_MAIN];
143 if(stripos($this->main, "pocketmine\\") === 0){
144 throw new PluginDescriptionParseException("Invalid Plugin main, cannot start within the PocketMine namespace");
145 }
146
147 $this->srcNamespacePrefix = $plugin[self::KEY_SRC_NAMESPACE_PREFIX] ?? "";
148
149 $this->api = array_map("\strval", (array) ($plugin[self::KEY_API] ?? []));
150 $this->compatibleMcpeProtocols = array_map("\intval", (array) ($plugin[self::KEY_MCPE_PROTOCOL] ?? []));
151 $this->compatibleOperatingSystems = array_map("\strval", (array) ($plugin[self::KEY_OS] ?? []));
152
153 if(isset($plugin[self::KEY_COMMANDS]) && is_array($plugin[self::KEY_COMMANDS])){
154 foreach($plugin[self::KEY_COMMANDS] as $commandName => $commandData){
155 if(!is_string($commandName)){
156 throw new PluginDescriptionParseException("Invalid Plugin commands, key must be the name of the command");
157 }
158 if(!is_array($commandData)){
159 throw new PluginDescriptionParseException("Command $commandName has invalid properties");
160 }
161 if(!isset($commandData[self::KEY_COMMAND_PERMISSION]) || !is_string($commandData[self::KEY_COMMAND_PERMISSION])){
162 throw new PluginDescriptionParseException("Command $commandName does not have a valid permission set");
163 }
164 $this->commands[$commandName] = new PluginDescriptionCommandEntry(
165 $commandData[self::KEY_COMMAND_DESCRIPTION] ?? null,
166 $commandData[self::KEY_COMMAND_USAGE] ?? null,
167 $commandData[self::KEY_COMMAND_ALIASES] ?? [],
168 $commandData[self::KEY_COMMAND_PERMISSION],
169 $commandData[self::KEY_COMMAND_PERMISSION_MESSAGE] ?? null
170 );
171 }
172 }
173
174 if(isset($plugin[self::KEY_DEPEND])){
175 $this->depend = (array) $plugin[self::KEY_DEPEND];
176 }
177 if(isset($plugin[self::KEY_EXTENSIONS])){
178 $extensions = (array) $plugin[self::KEY_EXTENSIONS];
179 $isLinear = $extensions === array_values($extensions);
180 foreach($extensions as $k => $v){
181 if($isLinear){
182 $k = $v;
183 $v = "*";
184 }
185 $this->extensions[(string) $k] = array_map('strval', is_array($v) ? $v : [$v]);
186 }
187 }
188
189 $this->softDepend = (array) ($plugin[self::KEY_SOFTDEPEND] ?? $this->softDepend);
190
191 $this->loadBefore = (array) ($plugin[self::KEY_LOADBEFORE] ?? $this->loadBefore);
192
193 $this->website = (string) ($plugin[self::KEY_WEBSITE] ?? $this->website);
194
195 $this->description = (string) ($plugin[self::KEY_DESCRIPTION] ?? $this->description);
196
197 $this->prefix = (string) ($plugin[self::KEY_LOGGER_PREFIX] ?? $this->prefix);
198
199 if(isset($plugin[self::KEY_LOAD])){
200 $order = PluginEnableOrder::fromString($plugin[self::KEY_LOAD]);
201 if($order === null){
202 throw new PluginDescriptionParseException("Invalid Plugin \"" . self::KEY_LOAD . "\"");
203 }
204 $this->order = $order;
205 }else{
206 $this->order = PluginEnableOrder::POSTWORLD;
207 }
208
209 $this->authors = [];
210 if(isset($plugin[self::KEY_AUTHOR])){
211 if(is_array($plugin[self::KEY_AUTHOR])){
212 $this->authors = $plugin[self::KEY_AUTHOR];
213 }else{
214 $this->authors[] = $plugin[self::KEY_AUTHOR];
215 }
216 }
217 if(isset($plugin[self::KEY_AUTHORS])){
218 foreach($plugin[self::KEY_AUTHORS] as $author){
219 $this->authors[] = $author;
220 }
221 }
222
223 if(isset($plugin[self::KEY_PERMISSIONS])){
224 try{
225 $this->permissions = PermissionParser::loadPermissions($plugin[self::KEY_PERMISSIONS]);
226 }catch(PermissionParserException $e){
227 throw new PluginDescriptionParseException("Invalid Plugin \"" . self::KEY_PERMISSIONS . "\": " . $e->getMessage(), 0, $e);
228 }
229 }
230 }
231
232 public function getFullName() : string{
233 return $this->name . " v" . $this->version;
234 }
235
239 public function getCompatibleApis() : array{
240 return $this->api;
241 }
242
246 public function getCompatibleMcpeProtocols() : array{
247 return $this->compatibleMcpeProtocols;
248 }
249
253 public function getCompatibleOperatingSystems() : array{
254 return $this->compatibleOperatingSystems;
255 }
256
260 public function getAuthors() : array{
261 return $this->authors;
262 }
263
264 public function getPrefix() : string{
265 return $this->prefix;
266 }
267
272 public function getCommands() : array{
273 return $this->commands;
274 }
275
280 public function getRequiredExtensions() : array{
281 return $this->extensions;
282 }
283
287 public function getDepend() : array{
288 return $this->depend;
289 }
290
291 public function getDescription() : string{
292 return $this->description;
293 }
294
298 public function getLoadBefore() : array{
299 return $this->loadBefore;
300 }
301
302 public function getMain() : string{
303 return $this->main;
304 }
305
306 public function getSrcNamespacePrefix() : string{ return $this->srcNamespacePrefix; }
307
308 public function getName() : string{
309 return $this->name;
310 }
311
312 public function getOrder() : PluginEnableOrder{
313 return $this->order;
314 }
315
320 public function getPermissions() : array{
321 return $this->permissions;
322 }
323
327 public function getSoftDepend() : array{
328 return $this->softDepend;
329 }
330
331 public function getVersion() : string{
332 return $this->version;
333 }
334
335 public function getWebsite() : string{
336 return $this->website;
337 }
338
343 public function getMap() : array{
344 return $this->map;
345 }
346}
static loadPermissions(array $data, string $default=self::DEFAULT_FALSE)
__construct(array|string $yamlString)