diff --git a/src/plugin/PluginLoadTriageEntry.php b/src/plugin/PluginLoadTriageEntry.php new file mode 100644 index 000000000..5a1a875de --- /dev/null +++ b/src/plugin/PluginLoadTriageEntry.php @@ -0,0 +1,42 @@ +file; } + + public function getLoader() : PluginLoader{ return $this->loader; } + + public function getDescription() : PluginDescription{ return $this->description; } +} \ No newline at end of file diff --git a/src/plugin/PluginManager.php b/src/plugin/PluginManager.php index 7b963af7e..63a444233 100644 --- a/src/plugin/PluginManager.php +++ b/src/plugin/PluginManager.php @@ -178,77 +178,7 @@ class PluginManager{ if($loader->canLoadPlugin($path)){ $description = $loader->getPluginDescription($path); if($description instanceof PluginDescription){ - $language = $this->server->getLanguage(); - $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); - - $dataFolder = $this->getDataDirectory($path, $description->getName()); - if(file_exists($dataFolder) and !is_dir($dataFolder)){ - $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $description->getName(), - KnownTranslationFactory::pocketmine_plugin_badDataFolder($dataFolder) - ))); - return null; - } - if(!file_exists($dataFolder)){ - mkdir($dataFolder, 0777, true); - } - - $prefixed = $loader->getAccessProtocol() . $path; - $loader->loadPlugin($prefixed); - - $mainClass = $description->getMain(); - if(!class_exists($mainClass, true)){ - $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $description->getName(), - KnownTranslationFactory::pocketmine_plugin_mainClassNotFound() - ))); - return null; - } - if(!is_a($mainClass, Plugin::class, true)){ - $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( - $description->getName(), - KnownTranslationFactory::pocketmine_plugin_mainClassWrongType(Plugin::class) - ))); - return null; - } - - $permManager = PermissionManager::getInstance(); - $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); - $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); - foreach($description->getPermissions() as $default => $perms){ - foreach($perms as $perm){ - $permManager->addPermission($perm); - switch($default){ - case PermissionParser::DEFAULT_TRUE: - $everyoneRoot->addChild($perm->getName(), true); - break; - case PermissionParser::DEFAULT_OP: - $opRoot->addChild($perm->getName(), true); - break; - case PermissionParser::DEFAULT_NOT_OP: - //TODO: I don't think anyone uses this, and it currently relies on some magic inside PermissibleBase - //to ensure that the operator override actually applies. - //Explore getting rid of this. - //The following grants this permission to anyone who has the "everyone" root permission. - //However, if the operator root node (which has higher priority) is present, the - //permission will be denied instead. - $everyoneRoot->addChild($perm->getName(), true); - $opRoot->addChild($perm->getName(), false); - break; - default: - break; - } - } - } - - /** - * @var Plugin $plugin - * @see Plugin::__construct() - */ - $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/resources/")); - $this->plugins[$plugin->getDescription()->getName()] = $plugin; - - return $plugin; + $this->internalLoadPlugin($path, $loader, $description); } } } @@ -256,6 +186,80 @@ class PluginManager{ return null; } + private function internalLoadPlugin(string $path, PluginLoader $loader, PluginDescription $description) : ?Plugin{ + $language = $this->server->getLanguage(); + $this->server->getLogger()->info($this->server->getLanguage()->translate(KnownTranslationFactory::pocketmine_plugin_load($description->getFullName()))); + + $dataFolder = $this->getDataDirectory($path, $description->getName()); + if(file_exists($dataFolder) and !is_dir($dataFolder)){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_badDataFolder($dataFolder) + ))); + return null; + } + if(!file_exists($dataFolder)){ + mkdir($dataFolder, 0777, true); + } + + $prefixed = $loader->getAccessProtocol() . $path; + $loader->loadPlugin($prefixed); + + $mainClass = $description->getMain(); + if(!class_exists($mainClass, true)){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassNotFound() + ))); + return null; + } + if(!is_a($mainClass, Plugin::class, true)){ + $this->server->getLogger()->error($language->translate(KnownTranslationFactory::pocketmine_plugin_loadError( + $description->getName(), + KnownTranslationFactory::pocketmine_plugin_mainClassWrongType(Plugin::class) + ))); + return null; + } + + $permManager = PermissionManager::getInstance(); + $opRoot = $permManager->getPermission(DefaultPermissions::ROOT_OPERATOR); + $everyoneRoot = $permManager->getPermission(DefaultPermissions::ROOT_USER); + foreach($description->getPermissions() as $default => $perms){ + foreach($perms as $perm){ + $permManager->addPermission($perm); + switch($default){ + case PermissionParser::DEFAULT_TRUE: + $everyoneRoot->addChild($perm->getName(), true); + break; + case PermissionParser::DEFAULT_OP: + $opRoot->addChild($perm->getName(), true); + break; + case PermissionParser::DEFAULT_NOT_OP: + //TODO: I don't think anyone uses this, and it currently relies on some magic inside PermissibleBase + //to ensure that the operator override actually applies. + //Explore getting rid of this. + //The following grants this permission to anyone who has the "everyone" root permission. + //However, if the operator root node (which has higher priority) is present, the + //permission will be denied instead. + $everyoneRoot->addChild($perm->getName(), true); + $opRoot->addChild($perm->getName(), false); + break; + default: + break; + } + } + } + + /** + * @var Plugin $plugin + * @see Plugin::__construct() + */ + $plugin = new $mainClass($loader, $this->server, $description, $dataFolder, $prefixed, new DiskResourceProvider($prefixed . "/resources/")); + $this->plugins[$plugin->getDescription()->getName()] = $plugin; + + return $plugin; + } + /** * @param string[]|null $newLoaders * @phpstan-param list> $newLoaders @@ -330,7 +334,7 @@ class PluginManager{ ))); continue; } - $plugins[$name] = $file; + $plugins[$name] = new PluginLoadTriageEntry($file, $loader, $description); $softDependencies[$name] = array_merge($softDependencies[$name] ?? [], $description->getSoftDepend()); $dependencies[$name] = $description->getDepend(); @@ -347,7 +351,7 @@ class PluginManager{ while(count($plugins) > 0){ $loadedThisLoop = 0; - foreach($plugins as $name => $file){ + foreach($plugins as $name => $entry){ if(isset($dependencies[$name])){ foreach($dependencies[$name] as $key => $dependency){ if(isset($loadedPlugins[$dependency]) or $this->getPlugin($dependency) instanceof Plugin){ @@ -389,7 +393,7 @@ class PluginManager{ if(!isset($dependencies[$name]) and !isset($softDependencies[$name])){ unset($plugins[$name]); $loadedThisLoop++; - if(($plugin = $this->loadPlugin($file, $loaders)) instanceof Plugin){ + if(($plugin = $this->internalLoadPlugin($entry->getFile(), $entry->getLoader(), $entry->getDescription())) instanceof Plugin){ $loadedPlugins[$name] = $plugin; } }