mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-16 10:49:10 +00:00
Added new Plugin and Permissions stuff :D
This commit is contained in:
parent
28c5443b0d
commit
af14c87572
@ -22,19 +22,13 @@
|
||||
namespace PocketMine;
|
||||
|
||||
use PocketMine\Network\Protocol\Info;
|
||||
use PocketMine\PMF\Plugin as PMFPlugin;
|
||||
use PocketMine\Utils\Config;
|
||||
use PocketMine\Utils\TextFormat;
|
||||
use PocketMine\Utils\Utils;
|
||||
use PocketMine\Plugin\PluginManager;
|
||||
|
||||
class PluginAPI extends \stdClass{
|
||||
private $server;
|
||||
private $plugins = array();
|
||||
private $randomNonce;
|
||||
|
||||
public function __construct(){
|
||||
$this->server = ServerAPI::request();
|
||||
$this->randomNonce = Utils::getRandomBytes(16, false);
|
||||
$this->server->api->console->register("plugins", "", array($this, "commandHandler"));
|
||||
$this->server->api->console->register("version", "", array($this, "commandHandler"));
|
||||
$this->server->api->ban->cmdWhitelist("version");
|
||||
@ -45,13 +39,14 @@ class PluginAPI extends \stdClass{
|
||||
switch($cmd){
|
||||
case "plugins":
|
||||
$output = "Plugins: ";
|
||||
foreach($this->getList() as $plugin){
|
||||
$output .= $plugin["name"] . ": " . $plugin["version"] . ", ";
|
||||
foreach(PluginManager::getPlugins() as $plugin){
|
||||
$d = $plugin->getDescription();
|
||||
$output .= $d->getName() . ": " . $d->getVersion() . ", ";
|
||||
}
|
||||
$output = $output === "Plugins: " ? "No plugins installed.\n" : substr($output, 0, -2) . "\n";
|
||||
break;
|
||||
case "version":
|
||||
$output = "PocketMine-MP " . VERSION . " 「" . CODENAME . "」 API #" . API_VERSION . " for Minecraft: PE " . MINECRAFT_VERSION . " protocol #" . Info::CURRENT_PROTOCOL;
|
||||
$output = "PocketMine-MP " . \PocketMine\VERSION . " 「" . \PocketMine\CODENAME . "」 API #" . \PocketMine\API_VERSION . " for Minecraft: PE " . \PocketMine\MINECRAFT_VERSION . " protocol #" . Info::CURRENT_PROTOCOL;
|
||||
if(\PocketMine\GIT_COMMIT !== str_repeat("00", 20)){
|
||||
$output .= " (git " . \PocketMine\GIT_COMMIT . ")";
|
||||
}
|
||||
@ -63,210 +58,9 @@ class PluginAPI extends \stdClass{
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
foreach($this->plugins as $p){
|
||||
$p[0]->__destruct();
|
||||
}
|
||||
unset($plugins);
|
||||
}
|
||||
|
||||
public function getList(){
|
||||
$list = array();
|
||||
foreach($this->plugins as $p){
|
||||
$list[] = $p[1];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function getAll(){
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
public function load($file){
|
||||
if(is_link($file) or is_dir($file) or !file_exists($file)){
|
||||
console("[ERROR] " . basename($file) . " is not a file");
|
||||
|
||||
return false;
|
||||
}
|
||||
if(strtolower(substr($file, -3)) === "pmf"){
|
||||
$pmf = new PMFPlugin($file);
|
||||
$info = $pmf->getPluginInfo();
|
||||
} else{
|
||||
$content = file_get_contents($file);
|
||||
$info = strstr($content, "*/", true);
|
||||
$content = str_repeat(PHP_EOL, substr_count($info, "\n")) . substr(strstr($content, "*/"), 2);
|
||||
if(preg_match_all('#([a-zA-Z0-9\-_]*)=([^\r\n]*)#u', $info, $matches) == 0){ //false or 0 matches
|
||||
console("[ERROR] Failed parsing of " . basename($file));
|
||||
|
||||
return false;
|
||||
}
|
||||
$info = array();
|
||||
foreach($matches[1] as $k => $i){
|
||||
$v = $matches[2][$k];
|
||||
switch(strtolower($v)){
|
||||
case "on":
|
||||
case "true":
|
||||
case "yes":
|
||||
$v = true;
|
||||
break;
|
||||
case "off":
|
||||
case "false":
|
||||
case "no":
|
||||
$v = false;
|
||||
break;
|
||||
}
|
||||
$info[$i] = $v;
|
||||
}
|
||||
$info["code"] = $content;
|
||||
$info["class"] = trim(strtolower($info["class"]));
|
||||
}
|
||||
if(!isset($info["name"]) or !isset($info["version"]) or !isset($info["class"]) or !isset($info["author"])){
|
||||
console("[ERROR] Failed parsing of " . basename($file));
|
||||
|
||||
return false;
|
||||
}
|
||||
console("[INFO] Loading plugin \"" . TextFormat::GREEN . $info["name"] . TextFormat::RESET . "\" " . TextFormat::AQUA . $info["version"] . TextFormat::RESET . " by " . TextFormat::AQUA . $info["author"] . TextFormat::RESET);
|
||||
if($info["class"] !== "none" and class_exists($info["class"])){
|
||||
console("[ERROR] Failed loading plugin: class already exists");
|
||||
|
||||
return false;
|
||||
}
|
||||
if(((!isset($pmf) and (include $file) === false) or (isset($pmf) and eval($info["code"]) === false)) and $info["class"] !== "none" and !class_exists($info["class"])){
|
||||
console("[ERROR] Failed loading {$info['name']}: evaluation error");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$className = $info["class"];
|
||||
$apiversion = array_map("intval", explode(",", (string) $info["apiversion"]));
|
||||
if(!in_array(API_VERSION, $apiversion)){
|
||||
console("[WARNING] Plugin \"" . $info["name"] . "\" may not be compatible with the API (" . $info["apiversion"] . " != " . API_VERSION . ")! It can crash or corrupt the server!");
|
||||
}
|
||||
|
||||
$identifier = $this->getIdentifier($info["name"], $info["author"]);
|
||||
|
||||
if($info["class"] !== "none"){
|
||||
$object = new $className($this->server->api, false);
|
||||
if(!($object instanceof Plugin)){
|
||||
console("[ERROR] Plugin \"" . $info["name"] . "\" doesn't use the Plugin Interface");
|
||||
if(method_exists($object, "__destruct")){
|
||||
$object->__destruct();
|
||||
}
|
||||
$object = null;
|
||||
unset($object);
|
||||
} else{
|
||||
$this->plugins[$identifier] = array($object, $info);
|
||||
}
|
||||
} else{
|
||||
$this->plugins[$identifier] = array(new DummyPlugin($this->server->api, false), $info);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getIdentifier($name, $author){
|
||||
return sha1(trim(strtolower($name)), true) ^ sha1(trim(strtolower($author)), true) ^ sha1($this->randomNonce, true);
|
||||
}
|
||||
|
||||
public function get($identifier){
|
||||
if($identifier instanceof Plugin){
|
||||
foreach($this->plugins as $p){
|
||||
if($p[0] === $identifier){
|
||||
return $p;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if(isset($this->plugins[$identifier])){
|
||||
return $this->plugins[$identifier];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function pluginsPath(){
|
||||
$path = join(DIRECTORY_SEPARATOR, array(\PocketMine\DATA . "plugins", ""));
|
||||
@mkdir($path);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
|
||||
public function configPath(Plugin $plugin){
|
||||
$p = $this->get($plugin);
|
||||
$identifier = $this->getIdentifier($p[1]["name"], $p[1]["author"]);
|
||||
if($p === false){
|
||||
return false;
|
||||
}
|
||||
$path = $this->pluginsPath() . $p[1]["name"] . DIRECTORY_SEPARATOR;
|
||||
$this->plugins[$identifier][1]["path"] = $path;
|
||||
@mkdir($path);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function createConfig(Plugin $plugin, $default = array()){
|
||||
$p = $this->get($plugin);
|
||||
if($p === false){
|
||||
return false;
|
||||
}
|
||||
$path = $this->configPath($plugin);
|
||||
$cnf = new Config($path . "config.yml", Config::YAML, $default);
|
||||
$cnf->save();
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function readYAML($file){
|
||||
return yaml_parse(preg_replace("#^([ ]*)([a-zA-Z_]{1}[^\:]*)\:#m", "$1\"$2\":", file_get_contents($file)));
|
||||
}
|
||||
|
||||
public function writeYAML($file, $data){
|
||||
return file_put_contents($file, yaml_emit($data, YAML_UTF8_ENCODING));
|
||||
}
|
||||
|
||||
public function init(){
|
||||
$this->server->event("server.start", array($this, "initAll"));
|
||||
$this->loadAll();
|
||||
}
|
||||
|
||||
private function loadAll(){
|
||||
$dir = dir($this->pluginsPath());
|
||||
while(false !== ($file = $dir->read())){
|
||||
if($file{0} !== "."){
|
||||
$ext = strtolower(substr($file, -3));
|
||||
if($ext === "php" or $ext === "pmf"){
|
||||
$this->load($dir->path . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function initAll(){
|
||||
console("[INFO] Starting plugins...");
|
||||
foreach($this->plugins as $p){
|
||||
$p[0]->init(); //ARGHHH!!! Plugin loading randomly fails!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface Plugin{
|
||||
public function __construct(ServerAPI $api, $server = false);
|
||||
|
||||
public function init();
|
||||
|
||||
public function __destruct();
|
||||
}
|
||||
|
||||
class DummyPlugin implements Plugin{
|
||||
public function __construct(ServerAPI $api, $server = false){
|
||||
}
|
||||
|
||||
public function init(){
|
||||
}
|
||||
|
||||
public function __destruct(){
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ use PocketMine\Network\Packet;
|
||||
use PocketMine\Network\Protocol\Info;
|
||||
use PocketMine\Network\RakNet\Info as RakNetInfo;
|
||||
use PocketMine\Network\RakNet\Packet as RakNetPacket;
|
||||
use PocketMine\Plugin\PluginManager;
|
||||
use PocketMine\Utils\Utils;
|
||||
use PocketMine\Utils\VersionString;
|
||||
|
||||
@ -301,12 +302,6 @@ class Server{
|
||||
public function addHandler($event, callable $callable, $priority = 5){
|
||||
if(!is_callable($callable)){
|
||||
return false;
|
||||
} elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"" . Deprecation::$events[$event] . "\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Adding handle to " . (is_array($callable) ? get_class($callable[0]) . "::" . $callable[1] : $callable) . "]");
|
||||
}
|
||||
$priority = (int) $priority;
|
||||
$hnid = $this->handCnt++;
|
||||
@ -346,12 +341,6 @@ class Server{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"" . Deprecation::$events[$event] . "\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Handler]");
|
||||
}
|
||||
|
||||
if($result !== false){
|
||||
@ -460,11 +449,11 @@ class Server{
|
||||
$p["rcon.password"] = "******";
|
||||
}
|
||||
$dump .= "server.properties: " . var_export($p, true) . "\r\n\r\n\r\n";
|
||||
if($this->api->plugin instanceof PluginAPI){
|
||||
$plist = $this->api->plugin->getList();
|
||||
if(class_exists("PocketMine\\Plugin\\PluginManager", false)){
|
||||
$dump .= "Loaded plugins:\r\n";
|
||||
foreach($plist as $p){
|
||||
$dump .= $p["name"] . " " . $p["version"] . " by " . $p["author"] . "\r\n";
|
||||
foreach(PluginManager::getPlugins() as $p){
|
||||
$d = $p->getDescription();
|
||||
$dump .= $d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . "\r\n";
|
||||
}
|
||||
$dump .= "\r\n\r\n";
|
||||
}
|
||||
@ -618,12 +607,6 @@ class Server{
|
||||
$ev($data, $event);
|
||||
}
|
||||
}
|
||||
} elseif(isset(Deprecation::$events[$event])){
|
||||
$sub = "";
|
||||
if(Deprecation::$events[$event] !== false){
|
||||
$sub = " Substitute \"" . Deprecation::$events[$event] . "\" found.";
|
||||
}
|
||||
console("[ERROR] Event \"$event\" has been deprecated.$sub [Trigger]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@ use PocketMine\Network\Protocol\Info;
|
||||
use PocketMine\Network\Query\QueryHandler;
|
||||
use PocketMine\Network\RCON\RCON;
|
||||
use PocketMine\Network\UPnP\UPnP;
|
||||
use PocketMine\Plugin\PluginManager;
|
||||
use PocketMine\PMF\Plugin;
|
||||
use PocketMine\Recipes\Crafting;
|
||||
use PocketMine\Tile\Tile;
|
||||
use PocketMine\Utils\Config;
|
||||
@ -220,7 +222,7 @@ class ServerAPI{
|
||||
}
|
||||
}
|
||||
|
||||
$this->apiList[] = $this->plugin = new PluginAPI();
|
||||
console("[INFO] Loaded ".count(PluginManager::loadPlugins(\PocketMine\DATA . "plugins/")). " plugin(s).");
|
||||
|
||||
}
|
||||
|
||||
@ -270,8 +272,9 @@ class ServerAPI{
|
||||
public function sendUsage(){
|
||||
console("[DEBUG] Sending usage data...", true, true, 2);
|
||||
$plist = "";
|
||||
foreach($this->plugin->getList() as $p){
|
||||
$plist .= str_replace(array(";", ":"), "", $p["name"]) . ":" . str_replace(array(";", ":"), "", $p["version"]) . ";";
|
||||
foreach(PluginManager::getPlugins() as $p){
|
||||
$d = $p->getDescription();
|
||||
$plist .= str_replace(array(";", ":"), "", $d->getName()) . ":" . str_replace(array(";", ":"), "", $d->getVersion()) . ";";
|
||||
}
|
||||
|
||||
$this->asyncOperation(ASYNC_CURL_POST, array(
|
||||
|
@ -59,11 +59,12 @@ class QueryHandler{
|
||||
public function regenerateInfo(){
|
||||
$str = "";
|
||||
$plist = "PocketMine-MP " . PocketMine\VERSION;
|
||||
$pl = $this->server->api->plugin->getList();
|
||||
$pl = PocketMine\Plugin\PluginManager::getPlugins();
|
||||
if(count($pl) > 0){
|
||||
$plist .= ":";
|
||||
foreach($pl as $p){
|
||||
$plist .= " " . str_replace(array(";", ":", " "), array("", "", "_"), $p["name"]) . " " . str_replace(array(";", ":", " "), array("", "", "_"), $p["version"]) . ";";
|
||||
$d = $p->getDescription();
|
||||
$plist .= " " . str_replace(array(";", ":", " "), array("", "", "_"), $d->getName()) . " " . str_replace(array(";", ":", " "), array("", "", "_"), $d->getVersion()) . ";";
|
||||
}
|
||||
$plist = substr($plist, 0, -1);
|
||||
}
|
||||
|
60
src/PocketMine/permission/Permissible.php
Normal file
60
src/PocketMine/permission/Permissible.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Permission;
|
||||
|
||||
use PocketMine;
|
||||
|
||||
interface Permissible extends ServerOperator{
|
||||
|
||||
/**
|
||||
* Checks if this instance has a permission overridden
|
||||
*
|
||||
* @param string|Permission $name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPermissionSet($name);
|
||||
|
||||
/**
|
||||
* Returns the permission value if overridden, or the default value if not
|
||||
*
|
||||
* @param string|Permission $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function hasPermission($name);
|
||||
|
||||
//TODO: Attachment
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function recalculatePermissions();
|
||||
|
||||
/**
|
||||
* TODO: Check this
|
||||
* @return Permission[]
|
||||
*/
|
||||
public function getEffectivePermissions();
|
||||
|
||||
}
|
130
src/PocketMine/permission/Permission.php
Normal file
130
src/PocketMine/permission/Permission.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Permission;
|
||||
|
||||
use PocketMine;
|
||||
|
||||
/**
|
||||
* Represents a permission
|
||||
*/
|
||||
class Permission{
|
||||
const DEFAULT_OP = "op";
|
||||
const DEFAULT_NOT_OP = "notop";
|
||||
const DEFAULT_TRUE = "true";
|
||||
const DEFAULT_FALSE = "false";
|
||||
|
||||
public static $DEFAULT_PERMISSION = self::DEFAULT_OP;
|
||||
|
||||
private $name;
|
||||
private $description;
|
||||
private $children = array();
|
||||
private $defaultValue;
|
||||
|
||||
/**
|
||||
* Creates a new Permission object to be attached to Permissible objects
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @param string $defaultValue
|
||||
* @param array $children
|
||||
*/
|
||||
public function __construct($name, $description = null, $defaultValue = null, array $children = array()){
|
||||
$this->name = $name;
|
||||
$this->description = $description !== null ? $description : "";
|
||||
$this->defaultValue = $defaultValue !== null ? $defaultValue : self::$DEFAULT_PERMISSION;
|
||||
$this->children = $children;
|
||||
|
||||
$this->recalculatePermissibles();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren(){
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefault(){
|
||||
return $this->defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setDefault($value){
|
||||
if($value !== $this->defaultValue){
|
||||
$this->defaultValue = $value;
|
||||
$this->recalculatePermissibles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(){
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
public function setDescription($value){
|
||||
$this->description = $value;
|
||||
}
|
||||
|
||||
public function getPermissibles(){
|
||||
//TODO: get from plugin manager
|
||||
//plugin handler -> getPermissionSubscriptions($this->name);
|
||||
return array();
|
||||
}
|
||||
|
||||
public function recalculatePermissibles(){
|
||||
//TODO: recalculate
|
||||
$perms = $this->getPermissibles();
|
||||
|
||||
//plugin handler -> recalculatePermissionDefaults($this);
|
||||
|
||||
foreach($perms as $p){
|
||||
$p->recalculatePermissions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function addParent($name){
|
||||
if($name instanceof Permission){
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,19 +19,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
//TODO: REMOVE
|
||||
namespace PocketMine\Permission;
|
||||
|
||||
namespace PocketMine;
|
||||
use PocketMine;
|
||||
|
||||
class Deprecation{
|
||||
public static $events = array(
|
||||
"server.tick" => "ServerAPI::schedule()",
|
||||
"server.time" => "time.change",
|
||||
"world.block.change" => "block.change",
|
||||
"block.drop" => "item.drop",
|
||||
"api.op.check" => "op.check",
|
||||
"api.player.offline.get" => "player.offline.get",
|
||||
"api.player.offline.save" => "player.offline.save",
|
||||
);
|
||||
interface ServerOperator{
|
||||
/**
|
||||
* Checks if the current object has operator permissions
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOp();
|
||||
|
||||
/**
|
||||
* Sets the operator permission for the current object
|
||||
*
|
||||
* @param bool $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOp($value);
|
||||
}
|
76
src/PocketMine/plugin/Plugin.php
Normal file
76
src/PocketMine/plugin/Plugin.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Plugin;
|
||||
|
||||
use PocketMine;
|
||||
|
||||
/**
|
||||
* It is recommended to use PluginBase for the actual plugin
|
||||
*
|
||||
*/
|
||||
interface Plugin{
|
||||
|
||||
/**
|
||||
* Called when the plugin is loaded, before calling onEnable()
|
||||
*/
|
||||
public function onLoad();
|
||||
|
||||
public function onEnable();
|
||||
|
||||
public function isEnabled();
|
||||
|
||||
public function onDisable();
|
||||
|
||||
public function isDisabled();
|
||||
|
||||
public function getDataFolder();
|
||||
|
||||
/**
|
||||
* @return PluginDescription
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Gets an embedded resource in the plugin file.
|
||||
*/
|
||||
public function getResource($filename);
|
||||
|
||||
public function saveResource($filename, $replace = false);
|
||||
|
||||
/**
|
||||
* Returns all the resources incrusted in the plugin
|
||||
*/
|
||||
public function getResources();
|
||||
|
||||
public function getConfig();
|
||||
|
||||
public function saveConfig();
|
||||
|
||||
public function saveDefaultConfig();
|
||||
|
||||
public function reloadConfig();
|
||||
|
||||
public function getServer();
|
||||
|
||||
public function getName();
|
||||
|
||||
}
|
202
src/PocketMine/plugin/PluginBase.php
Normal file
202
src/PocketMine/plugin/PluginBase.php
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Plugin;
|
||||
|
||||
use PocketMine;
|
||||
use PocketMine\Utils\Config;
|
||||
|
||||
abstract class PluginBase{
|
||||
/** @var PocketMine\Server */
|
||||
private $server;
|
||||
private $isEnabled = false;
|
||||
private $initialized = false;
|
||||
/** @var PluginDescription */
|
||||
private $description;
|
||||
private $dataFolder;
|
||||
private $config;
|
||||
/** @var string */
|
||||
private $configFile;
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* Called when the plugin is loaded, before calling onLoad()
|
||||
*/
|
||||
public function onLoad(){
|
||||
|
||||
}
|
||||
|
||||
public function onEnable(){
|
||||
|
||||
}
|
||||
|
||||
public final function isEnabled(){
|
||||
return $this->isEnabled === true;
|
||||
}
|
||||
|
||||
public final function setEnabled($boolean = true){
|
||||
if($this->isEnabled !== $boolean){
|
||||
$this->isEnabled = $boolean;
|
||||
if($this->isEnabled === true){
|
||||
$this->onEnable();
|
||||
}else{
|
||||
$this->onDisable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onDisable(){
|
||||
|
||||
}
|
||||
|
||||
public final function isDisabled(){
|
||||
return $this->isEnabled === false;
|
||||
}
|
||||
|
||||
public final function getDataFolder(){
|
||||
return $this->dataFolder;
|
||||
}
|
||||
|
||||
public final function getDescription(){
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
protected final function initialize(PocketMine\Server $server, PluginDescription $description, $dataFolder, $file){
|
||||
if($this->initialized === false){
|
||||
$this->initialized = true;
|
||||
$this->server = $server;
|
||||
$this->description = $description;
|
||||
$this->dataFolder = $dataFolder;
|
||||
$this->file = $file;
|
||||
$this->configFile = $this->dataFolder . "config.yml";
|
||||
}
|
||||
}
|
||||
|
||||
public final function isInitialized(){
|
||||
return $this->initialized;
|
||||
}
|
||||
|
||||
public function onCommand(CommandSender $sender, Command $command, $label, $args){
|
||||
return false;
|
||||
}
|
||||
|
||||
/* TODO
|
||||
public function getCommand($name){
|
||||
$this->get
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Gets an embedded resource on the plugin file.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return bool|string Resource data, or false
|
||||
*/
|
||||
public function getResource($filename){
|
||||
$filename = str_replace("\\", "/", $filename);
|
||||
if(isset($this->phar) and $this->phar instanceof \Phar){
|
||||
//TODO
|
||||
}else{
|
||||
if(file_exists($this->dataFolder . "resources/" . $filename)){
|
||||
return file_get_contents($this->dataFolder . "resources/" . $filename);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function saveResource($filename, $replace = false){
|
||||
if(trim($filename) === ""){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(($resource = $this->getResource($filename)) === false){
|
||||
return false;
|
||||
}
|
||||
|
||||
$out = $this->dataFolder . $filename;
|
||||
if(!file_exists($this->dataFolder)){
|
||||
@mkdir($this->dataFolder, 0755, true);
|
||||
}
|
||||
|
||||
if(file_exists($out) and $replace !== true){
|
||||
return false;
|
||||
}
|
||||
|
||||
return @file_put_contents($out, $resource) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the resources incrusted on the plugin
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getResources(){
|
||||
if(!$this->isPhar()){
|
||||
$resources = array();
|
||||
foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->dataFolder . "resources/")) as $resource){
|
||||
$resources[] = $resource;
|
||||
}
|
||||
return $resources;
|
||||
}
|
||||
}
|
||||
|
||||
public function getConfig(){
|
||||
if(!isset($this->config)){
|
||||
$this->reloadConfig();
|
||||
}
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
public function saveConfig(){
|
||||
if($this->getConfig()->save() === false){
|
||||
console("[SEVERE] Could not save config to ". $this->configFile);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function saveDefaultConfig(){
|
||||
if(!file_exists($this->configFile)){
|
||||
$this->saveResource("config.yml", false);
|
||||
}
|
||||
}
|
||||
|
||||
public function reloadConfig(){
|
||||
$this->config = new Config($this->configFile);
|
||||
if(($configStream = $this->getResource("config.yml")) !== false){
|
||||
$this->config->setDefaults(yaml_parse(config::fixYAMLIndexes($configStream)));
|
||||
}
|
||||
}
|
||||
|
||||
public final function getServer(){
|
||||
return $this->dataFolder;
|
||||
}
|
||||
|
||||
public final function getName()
|
||||
{
|
||||
return $this->description->getName();
|
||||
}
|
||||
|
||||
protected function getFile(){
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
}
|
207
src/PocketMine/plugin/PluginDescription.php
Normal file
207
src/PocketMine/plugin/PluginDescription.php
Normal file
@ -0,0 +1,207 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Plugin;
|
||||
|
||||
use PocketMine;
|
||||
use PocketMine\Permission\Permission;
|
||||
|
||||
class PluginDescription{
|
||||
private $name;
|
||||
private $main;
|
||||
private $api;
|
||||
private $depend = array();
|
||||
private $softDepend = array();
|
||||
private $loadBefore = array();
|
||||
private $version;
|
||||
private $commands = array();
|
||||
private $description = null;
|
||||
private $authors = array();
|
||||
private $website = null;
|
||||
private $order = PluginLoadOrder::POSTWORLD;
|
||||
|
||||
/**
|
||||
* @var Permission[]
|
||||
*/
|
||||
private $permissions = array();
|
||||
|
||||
/**
|
||||
* @param string $yamlString
|
||||
*/
|
||||
public function __construct($yamlString){
|
||||
$this->loadMap(\yaml_parse($yamlString));
|
||||
}
|
||||
|
||||
private function loadMap(array $plugin){
|
||||
$this->name = preg_replace("[^A-Za-z0-9 _.-]", "", $plugin["name"]);
|
||||
if($this->name === ""){
|
||||
trigger_error("Invalid PluginDescription name", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
$this->name = str_replace(" ", "_", $this->name);
|
||||
$this->version = $plugin["version"];
|
||||
$this->main = $plugin["main"];
|
||||
$this->api = !is_array($plugin["api"]) ? array($plugin["api"]) : $plugin["api"];
|
||||
if(stripos($this->main, "PocketMine\\") === 0){
|
||||
trigger_error("Invalid PluginDescription main, cannot start within the PocketMine namespace", E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: commands
|
||||
|
||||
if(isset($plugin["depend"])){
|
||||
$this->depend = (array) $plugin["depend"];
|
||||
}
|
||||
if(isset($plugin["softdepend"])){
|
||||
$this->softDepend = (array) $plugin["softdepend"];
|
||||
}
|
||||
if(isset($plugin["loadbefore"])){
|
||||
$this->loadBefore = (array) $plugin["loadbefore"];
|
||||
}
|
||||
|
||||
if(isset($plugin["website"])){
|
||||
$this->website = $plugin["website"];
|
||||
}
|
||||
if(isset($plugin["description"])){
|
||||
$this->description = $plugin["description"];
|
||||
}
|
||||
if(isset($plugin["load"])){
|
||||
$order = strtoupper($plugin["load"]);
|
||||
if(!defined("PocketMine\\Plugin\\PluginLoadOrder::" . $order)){
|
||||
trigger_error("Invalid PluginDescription load", E_USER_ERROR);
|
||||
return;
|
||||
}else{
|
||||
$this->order = constant("PocketMine\\Plugin\\PluginLoadOrder::" . $order);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($plugin["authors"])){
|
||||
$this->authors = $plugin["authors"];
|
||||
}elseif(isset($plugin["author"])){
|
||||
$this->authors = array($plugin["author"]);
|
||||
}else{
|
||||
$this->authors = array();
|
||||
}
|
||||
|
||||
//TODO: Do permissions
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCompatibleApis(){
|
||||
return $this->api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAuthors(){
|
||||
return $this->authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCommands(){
|
||||
return $this->commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDepend()
|
||||
{
|
||||
return $this->depend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLoadBefore()
|
||||
{
|
||||
return $this->loadBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMain()
|
||||
{
|
||||
return $this->main;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getOrder()
|
||||
{
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Permission[]
|
||||
*/
|
||||
public function getPermisions()
|
||||
{
|
||||
return $this->permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSoftDepend()
|
||||
{
|
||||
return $this->softDepend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getWebsite()
|
||||
{
|
||||
return $this->website;
|
||||
}
|
||||
}
|
41
src/PocketMine/plugin/PluginLoadOrder.php
Normal file
41
src/PocketMine/plugin/PluginLoadOrder.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Plugin;
|
||||
|
||||
use PocketMine;
|
||||
|
||||
abstract class PluginLoadOrder{
|
||||
/*
|
||||
* Load before loading other PocketMine API's.
|
||||
*/
|
||||
const SYSTEM = 0;
|
||||
|
||||
/*
|
||||
* The plugin will be loaded after the first world has been loaded/created.
|
||||
*/
|
||||
const PREWORLD = 1;
|
||||
|
||||
/*
|
||||
* The plugin will be loaded after the first world has been loaded/created.
|
||||
*/
|
||||
const POSTWORLD = 1;
|
||||
}
|
57
src/PocketMine/plugin/PluginLoader.php
Normal file
57
src/PocketMine/plugin/PluginLoader.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Plugin;
|
||||
|
||||
/**
|
||||
* Handles different types of plugins
|
||||
*/
|
||||
interface PluginLoader{
|
||||
|
||||
/**
|
||||
* Loads the plugin contained in $file
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return Plugin
|
||||
*/
|
||||
public function loadPlugin($file);
|
||||
|
||||
/**
|
||||
* Gets the PluginDescription from the file
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return PluginDescription
|
||||
*/
|
||||
public function getPluginDescription($file);
|
||||
|
||||
/**
|
||||
* Returns the filename patterns that this loader accepts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPluginFilters();
|
||||
|
||||
public function enablePlugin(Plugin $plugin);
|
||||
|
||||
public function disablePlugin(Plugin $plugin);
|
||||
}
|
439
src/PocketMine/plugin/PluginManager.php
Normal file
439
src/PocketMine/plugin/PluginManager.php
Normal file
@ -0,0 +1,439 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace PocketMine\Plugin;
|
||||
|
||||
use PocketMine;
|
||||
use PocketMine\Permission\Permission;
|
||||
use PocketMine\Permission\Permissible;
|
||||
|
||||
/**
|
||||
* Manages all the plugins, Permissions and Permissibles
|
||||
*/
|
||||
abstract class PluginManager{
|
||||
|
||||
/**
|
||||
* @var Plugin[]
|
||||
*/
|
||||
protected static $plugins = array();
|
||||
|
||||
/**
|
||||
* @var Permission[]
|
||||
*/
|
||||
protected static $permissions = array();
|
||||
|
||||
/**
|
||||
* @var Permission[]
|
||||
*/
|
||||
protected static $defaultPerms = array();
|
||||
|
||||
/**
|
||||
* @var Permission[]
|
||||
*/
|
||||
protected static $defaultPermsOp = array();
|
||||
|
||||
/**
|
||||
* @var Permissible[]
|
||||
*/
|
||||
protected static $permSubs = array();
|
||||
|
||||
/**
|
||||
* @var Permissible[]
|
||||
*/
|
||||
protected static $defSubs = array();
|
||||
|
||||
/**
|
||||
* @var Permissible[]
|
||||
*/
|
||||
protected static $defSubsOp = array();
|
||||
|
||||
/**
|
||||
* @var PluginLoader[]
|
||||
*/
|
||||
protected static $fileAssociations = array();
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return null|Plugin
|
||||
*/
|
||||
public static function getPlugin($name){
|
||||
if(isset(static::$plugins[$name])){
|
||||
return static::$plugins[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|PluginLoader $loader
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function registerInterface($loader){
|
||||
if(is_object($loader) and !($loader instanceof PluginLoader)){
|
||||
return false;
|
||||
}elseif(is_string($loader)){
|
||||
if(is_subclass_of($loader, "PocketMine\\Plugin\\PluginLoader")){
|
||||
$loader = new $loader;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static::$fileAssociations[spl_object_hash($loader)] = array($loader, $loader->getPluginFilters());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Plugin[]
|
||||
*/
|
||||
public static function getPlugins(){
|
||||
return static::$plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return Plugin
|
||||
*/
|
||||
public static function loadPlugin($path){
|
||||
foreach(static::$fileAssociations as $loader){
|
||||
if(preg_match($loader[1], basename($file)) > 0){
|
||||
$description = $loader[0]->getPluginDescription($path);
|
||||
if($description instanceof PluginDescription){
|
||||
return $loader[0]->loadPlugin($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $directory
|
||||
*
|
||||
* @return Plugin[]
|
||||
*/
|
||||
public static function loadPlugins($directory){
|
||||
if(is_dir($directory)){
|
||||
$plugins = array();
|
||||
$loadedPlugins = array();
|
||||
$dependencies = array();
|
||||
$softDependencies = array();
|
||||
foreach(new \IteratorIterator(new \DirectoryIterator($directory)) as $file){
|
||||
foreach(static::$fileAssociations as $loader){
|
||||
if(preg_match($loader[1], basename($file)) > 0){
|
||||
$description = $loader[0]->getPluginDescription($file);
|
||||
if($description instanceof PluginDescription){
|
||||
$name = $description->getName();
|
||||
if(stripos($name, "pocketmine") !== false or stripos($name, "minecraft") !== false or stripos($name, "mojang") !== false){
|
||||
console("[ERROR] Could not load plugin '".$name."': restricted name");
|
||||
continue;
|
||||
}elseif(strpos($name, " ") !== false){
|
||||
console("[WARNING] Plugin '".$name."' uses spaces in its name, this is discouraged");
|
||||
}
|
||||
if(isset($plugins[$name])){
|
||||
console("[ERROR] Could not load duplicate plugin '".$name."': plugin exists");
|
||||
continue;
|
||||
}
|
||||
|
||||
$compatible = false;
|
||||
|
||||
//Check multiple dependencies
|
||||
foreach($description->getCompatibleApis() as $version){
|
||||
//Format: majorVersion.minorVersion.patch
|
||||
$version = array_map("intval", explode(".", $version));
|
||||
$apiVersion = array_map("intval", explode(".", PocketMine\API_VERSION));
|
||||
|
||||
//Completely different API version
|
||||
if($version[0] !== $apiVersion[0]){
|
||||
continue;
|
||||
}
|
||||
|
||||
//If the plugin requires new API features, being backwards compatible
|
||||
if($version[1] > $apiVersion[1]){
|
||||
continue;
|
||||
}
|
||||
|
||||
$compatible = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if($compatible === false){
|
||||
console("[ERROR] Could not load plugin '".$name."': API version not compatible");
|
||||
continue;
|
||||
}
|
||||
|
||||
$plugins[$name] = $file;
|
||||
|
||||
$softDependencies[$name] = (array) $description->getSoftDepend();
|
||||
$dependencies[$name] = (array) $description->getDepend();
|
||||
|
||||
foreach($description->getLoadBefore() as $before){
|
||||
if(isset($softDependencies[$before])){
|
||||
$softDependencies[$before][] = $name;
|
||||
}else{
|
||||
$softDependencies[$before] = array($name);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(count($plugins) > 0){
|
||||
$missingDependency = true;
|
||||
foreach($plugins as $name => $file){
|
||||
if(isset($dependencies[$name])){
|
||||
foreach($dependencies[$name] as $key => $dependency){
|
||||
if(isset($loadedPlugins[$dependency])){
|
||||
unset($dependencies[$name][$key]);
|
||||
}elseif(!isset($plugins[$dependency])){
|
||||
console("[SEVERE] Could not load plugin '".$name."': Unknown dependency");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(count($dependencies[$name]) === 0){
|
||||
unset($dependencies[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($softDependencies[$name])){
|
||||
foreach($softDependencies[$name] as $key => $dependency){
|
||||
if(isset($loadedPlugins[$dependency])){
|
||||
unset($softDependencies[$name][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if(count($softDependencies[$name]) === 0){
|
||||
unset($softDependencies[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($dependencies[$name]) and !isset($softDependencies[$name])){
|
||||
unset($plugins[$name]);
|
||||
$missingDependency = false;
|
||||
if($plugin = static::loadPlugin($file) and $plugin instanceof Plugin){
|
||||
$loadedPlugins[$name] = $plugin;
|
||||
}else{
|
||||
console("[SEVERE] Could not load plugin '".$name."'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($missingDependency === true){
|
||||
foreach($plugins as $name => $file){
|
||||
if(!isset($dependencies[$name])){
|
||||
unset($softDependencies[$name]);
|
||||
unset($plugins[$name]);
|
||||
$missingDependency = false;
|
||||
if($plugin = static::loadPlugin($file) and $plugin instanceof Plugin){
|
||||
$loadedPlugins[$name] = $plugin;
|
||||
}else{
|
||||
console("[SEVERE] Could not load plugin '".$name."'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//No plugins loaded :(
|
||||
if($missingDependency === true){
|
||||
foreach($plugins as $name => $file){
|
||||
console("[SEVERE] Could not load plugin '".$name."': circular dependency detected");
|
||||
}
|
||||
$plugins = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $loadedPlugins;
|
||||
}else{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return null|Permission
|
||||
*/
|
||||
public static function getPermission($name){
|
||||
if(isset(static::$permissions[$name])){
|
||||
return static::$permissions[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Permission $permission
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function addPermission(Permission $permission){
|
||||
if(!isset(static::$permissions[$permission->getName()])){
|
||||
static::$permissions[$permission->getName()] = $permission;
|
||||
static::calculatePermissionDefault($permission);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|Permission $permission
|
||||
*/
|
||||
public function removePermission($permission){
|
||||
if($permission instanceof Permission){
|
||||
unset(static::$permissions[$permission->getName()]);
|
||||
}else{
|
||||
unset(static::$permissions[$permission]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $op
|
||||
*
|
||||
* @return Permission[]
|
||||
*/
|
||||
public static function getDefaultPermissions($op){
|
||||
if($op === true){
|
||||
return static::$defaultPermsOp;
|
||||
}else{
|
||||
return static::$defaultPerms;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Permission $permission
|
||||
*/
|
||||
public static function recalculatePermissionDefaults(Permission $permission){
|
||||
if(isset(static::$permissions[$permission->getName()])){
|
||||
unset(static::$defaultPermsOp[$permission->getName()]);
|
||||
unset(static::$defaultPerms[$permission->getName()]);
|
||||
static::calculatePermissionDefault($permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Permission $permission
|
||||
*/
|
||||
private static function calculatePermissionDefault(Permission $permission){
|
||||
if($permission->getDefault() === Permission::DEFAULT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
|
||||
static::$defaultPermsOp[$permission->getName()] = $permission;
|
||||
static::dirtyPermissibles(true);
|
||||
}
|
||||
|
||||
if($permission->getDefault() === Permission::DEFAULT_NOT_OP or $permission->getDefault() === Permission::DEFAULT_TRUE){
|
||||
static::$defaultPerms[$permission->getName()] = $permission;
|
||||
static::dirtyPermissibles(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $op
|
||||
*/
|
||||
private static function dirtyPermissibles($op){
|
||||
foreach(static::getDefaultPermSubscriptions($op) as $p){
|
||||
$p->recalculatePermissions();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $permission
|
||||
* @param Permissible $permissible
|
||||
*/
|
||||
public static function subscribeToPermission($permission, Permissible $permissible){
|
||||
if(!isset(static::$permSubs[$permission])){
|
||||
//TODO: Use WeakRef
|
||||
static::$permSubs[$permission] = array();
|
||||
}
|
||||
static::$permSubs[$permission][spl_object_hash($permissible)] = $permissible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $permission
|
||||
* @param Permissible $permissible
|
||||
*/
|
||||
public static function unsubscribeFromPermission($permission, Permissible $permissible){
|
||||
if(isset(static::$permSubs[$permission])){
|
||||
unset(static::$permSubs[$permission][spl_object_hash($permissible)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $permission
|
||||
*
|
||||
* @return Permissible[]
|
||||
*/
|
||||
public static function getPermissionSubscriptions($permission){
|
||||
if(isset(static::$permSubs[$permission])){
|
||||
return static::$permSubs[$permission];
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $op
|
||||
* @param Permissible $permissible
|
||||
*/
|
||||
public static function subscribeToDefaultPerms($op, Permissible $permissible){
|
||||
if($op === true){
|
||||
static::$defSubsOp[spl_object_hash($permissible)] = $permissible;
|
||||
}else{
|
||||
static::$defSubs[spl_object_hash($permissible)] = $permissible;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $op
|
||||
* @param Permissible $permissible
|
||||
*/
|
||||
public static function unsubscribeFromDefaultPerms($op, Permissible $permissible){
|
||||
if($op === true){
|
||||
unset(static::$defSubsOp[spl_object_hash($permissible)]);
|
||||
}else{
|
||||
unset(static::$defSubs[spl_object_hash($permissible)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $op
|
||||
*
|
||||
* @return Permissible[]
|
||||
*/
|
||||
public static function getDefaultPermSubscriptions($op){
|
||||
if($op === true){
|
||||
return static::$defSubsOp;
|
||||
}else{
|
||||
return static::$defSubs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Permission[]
|
||||
*/
|
||||
public static function getPermissions(){
|
||||
return static::$permissions;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user