Encapsulate plugin.yml commands handling inside PluginBase, removed CommandExecutor requirement from Plugin interface

This removes the need for custom Plugin implementations to implement onCommand().

In the future it's planned to remove plugin.yml commands completely and have them registered similarly to how events are handled.
This commit is contained in:
Dylan K. Taylor 2018-11-09 19:50:52 +00:00
parent 8b9ec5dde3
commit 3a6af3327f
4 changed files with 67 additions and 77 deletions

View File

@ -1644,7 +1644,7 @@ class Server{
$this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR, $this->logger);
$this->pluginManager = new PluginManager($this, $this->commandMap, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR);
$this->pluginManager = new PluginManager($this, ((bool) $this->getProperty("plugins.legacy-data-dir", true)) ? null : $this->getDataPath() . "plugin_data" . DIRECTORY_SEPARATOR);
$this->profilingTickRate = (float) $this->getProperty("settings.profile-report-trigger", 20);
$this->pluginManager->registerInterface(new PharPluginLoader($this->autoloader));
$this->pluginManager->registerInterface(new ScriptPluginLoader());

View File

@ -26,14 +26,13 @@ declare(strict_types=1);
*/
namespace pocketmine\plugin;
use pocketmine\command\CommandExecutor;
use pocketmine\scheduler\TaskScheduler;
use pocketmine\Server;
/**
* It is recommended to use PluginBase for the actual plugin
*/
interface Plugin extends CommandExecutor{
interface Plugin{
public function __construct(PluginLoader $loader, Server $server, PluginDescription $description, string $dataFolder, string $file);

View File

@ -24,13 +24,15 @@ declare(strict_types=1);
namespace pocketmine\plugin;
use pocketmine\command\Command;
use pocketmine\command\CommandExecutor;
use pocketmine\command\CommandSender;
use pocketmine\command\PluginCommand;
use pocketmine\command\PluginIdentifiableCommand;
use pocketmine\scheduler\TaskScheduler;
use pocketmine\Server;
use pocketmine\utils\Config;
abstract class PluginBase implements Plugin{
abstract class PluginBase implements Plugin, CommandExecutor{
/** @var PluginLoader */
private $loader;
@ -70,6 +72,8 @@ abstract class PluginBase implements Plugin{
$this->scheduler = new TaskScheduler($this->getFullName());
$this->onLoad();
$this->registerYamlCommands();
}
/**
@ -143,6 +147,63 @@ abstract class PluginBase implements Plugin{
return $this->logger;
}
/**
* Registers commands declared in the plugin manifest
*/
private function registerYamlCommands() : void{
$pluginCmds = [];
foreach($this->getDescription()->getCommands() as $key => $data){
if(strpos($key, ":") !== false){
$this->logger->error($this->server->getLanguage()->translateString("pocketmine.plugin.commandError", [$key, $this->getDescription()->getFullName()]));
continue;
}
if(is_array($data)){ //TODO: error out if it isn't
$newCmd = new PluginCommand($key, $this);
if(isset($data["description"])){
$newCmd->setDescription($data["description"]);
}
if(isset($data["usage"])){
$newCmd->setUsage($data["usage"]);
}
if(isset($data["aliases"]) and is_array($data["aliases"])){
$aliasList = [];
foreach($data["aliases"] as $alias){
if(strpos($alias, ":") !== false){
$this->logger->error($this->server->getLanguage()->translateString("pocketmine.plugin.aliasError", [$alias, $this->getDescription()->getFullName()]));
continue;
}
$aliasList[] = $alias;
}
$newCmd->setAliases($aliasList);
}
if(isset($data["permission"])){
if(is_bool($data["permission"])){
$newCmd->setPermission($data["permission"] ? "true" : "false");
}elseif(is_string($data["permission"])){
$newCmd->setPermission($data["permission"]);
}else{
$this->logger->error("Permission must be a string, " . gettype($data["permission"]) . " given for command $key");
}
}
if(isset($data["permission-message"])){
$newCmd->setPermissionMessage($data["permission-message"]);
}
$pluginCmds[] = $newCmd;
}
}
if(count($pluginCmds) > 0){
$this->server->getCommandMap()->registerAll($this->getDescription()->getName(), $pluginCmds);
}
}
/**
* @param string $name
*

View File

@ -23,8 +23,6 @@ declare(strict_types=1);
namespace pocketmine\plugin;
use pocketmine\command\PluginCommand;
use pocketmine\command\SimpleCommandMap;
use pocketmine\event\Event;
use pocketmine\event\EventPriority;
use pocketmine\event\HandlerList;
@ -45,9 +43,6 @@ class PluginManager{
/** @var Server */
private $server;
/** @var SimpleCommandMap */
private $commandMap;
/**
* @var Plugin[]
*/
@ -67,13 +62,11 @@ class PluginManager{
private $pluginDataDirectory;
/**
* @param Server $server
* @param SimpleCommandMap $commandMap
* @param null|string $pluginDataDirectory
* @param Server $server
* @param null|string $pluginDataDirectory
*/
public function __construct(Server $server, SimpleCommandMap $commandMap, ?string $pluginDataDirectory){
public function __construct(Server $server, ?string $pluginDataDirectory){
$this->server = $server;
$this->commandMap = $commandMap;
$this->pluginDataDirectory = $pluginDataDirectory;
if($this->pluginDataDirectory !== null){
if(!file_exists($this->pluginDataDirectory)){
@ -167,12 +160,6 @@ class PluginManager{
$plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed);
$this->plugins[$plugin->getDescription()->getName()] = $plugin;
$pluginCommands = $this->parseYamlCommands($plugin);
if(count($pluginCommands) > 0){
$this->commandMap->registerAll($plugin->getDescription()->getName(), $pluginCommands);
}
return $plugin;
}catch(\Throwable $e){
$this->server->getLogger()->logException($e);
@ -425,63 +412,6 @@ class PluginManager{
}
}
/**
* @param Plugin $plugin
*
* @return PluginCommand[]
*/
protected function parseYamlCommands(Plugin $plugin) : array{
$pluginCmds = [];
foreach($plugin->getDescription()->getCommands() as $key => $data){
if(strpos($key, ":") !== false){
$this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.commandError", [$key, $plugin->getDescription()->getFullName()]));
continue;
}
if(is_array($data)){
$newCmd = new PluginCommand($key, $plugin);
if(isset($data["description"])){
$newCmd->setDescription($data["description"]);
}
if(isset($data["usage"])){
$newCmd->setUsage($data["usage"]);
}
if(isset($data["aliases"]) and is_array($data["aliases"])){
$aliasList = [];
foreach($data["aliases"] as $alias){
if(strpos($alias, ":") !== false){
$this->server->getLogger()->critical($this->server->getLanguage()->translateString("pocketmine.plugin.aliasError", [$alias, $plugin->getDescription()->getFullName()]));
continue;
}
$aliasList[] = $alias;
}
$newCmd->setAliases($aliasList);
}
if(isset($data["permission"])){
if(is_bool($data["permission"])){
$newCmd->setPermission($data["permission"] ? "true" : "false");
}elseif(is_string($data["permission"])){
$newCmd->setPermission($data["permission"]);
}else{
throw new \InvalidArgumentException("Permission must be a string or boolean, " . gettype($data["permission"]) . " given");
}
}
if(isset($data["permission-message"])){
$newCmd->setPermissionMessage($data["permission-message"]);
}
$pluginCmds[] = $newCmd;
}
}
return $pluginCmds;
}
public function disablePlugins(){
foreach($this->getPlugins() as $plugin){
$this->disablePlugin($plugin);