From 5b884d7a9c69885a30b84fd29762cb614cfeea54 Mon Sep 17 00:00:00 2001 From: Max Klaversma Date: Wed, 16 Apr 2014 22:53:14 +0200 Subject: [PATCH] Plugins can now be installed via the settings UI. --- application/core/Plugins/PluginManager.php | 5 +- application/core/Update/PluginInstallMenu.php | 2 +- application/core/Update/UpdateManager.php | 138 +++++++++++++----- 3 files changed, 108 insertions(+), 37 deletions(-) diff --git a/application/core/Plugins/PluginManager.php b/application/core/Plugins/PluginManager.php index c7d51f5c..5bc91e90 100644 --- a/application/core/Plugins/PluginManager.php +++ b/application/core/Plugins/PluginManager.php @@ -119,6 +119,7 @@ class PluginManager { return false; } array_push($this->pluginClasses, $pluginClass); + sort($this->pluginClasses); return true; } @@ -221,7 +222,7 @@ class PluginManager { * * @param string $directory */ - private function loadPluginFiles($directory = '') { + public function loadPluginFiles($directory = '') { $pluginFiles = scandir($directory); foreach($pluginFiles as $pluginFile) { if (stripos($pluginFile, '.') === 0) { @@ -315,7 +316,7 @@ class PluginManager { * @param string $className * @return bool */ - private function getSavedPluginStatus($className) { + public function getSavedPluginStatus($className) { $mysqli = $this->maniaControl->database->mysqli; $pluginStatusQuery = "SELECT `active` FROM `" . self::TABLE_PLUGINS . "` WHERE `className` = ?;"; diff --git a/application/core/Update/PluginInstallMenu.php b/application/core/Update/PluginInstallMenu.php index 58bd5fcc..49ff69be 100644 --- a/application/core/Update/PluginInstallMenu.php +++ b/application/core/Update/PluginInstallMenu.php @@ -30,7 +30,7 @@ use ManiaControl\Players\Player; * @license http://www.gnu.org/licenses/ GNU General Public License, Version 3 */ class PluginInstallMenu implements CallbackListener, ConfiguratorMenu, ManialinkPageAnswerListener { - const SETTING_PERMISSION_INSTALL_PLUGINS = 'Install plugins'; + const SETTING_PERMISSION_INSTALL_PLUGINS = 'Install plugins'; const ACTION_PREFIX_INSTALLPLUGIN = 'PluginInstallMenu.Install.'; /** diff --git a/application/core/Update/UpdateManager.php b/application/core/Update/UpdateManager.php index 5e0c8094..df9bf554 100644 --- a/application/core/Update/UpdateManager.php +++ b/application/core/Update/UpdateManager.php @@ -75,7 +75,6 @@ class UpdateManager implements CallbackListener, CommandListener, TimerListener $this->maniaControl->commandManager->registerCommandListener('checkupdate', $this, 'handle_CheckUpdate', true); $this->maniaControl->commandManager->registerCommandListener('coreupdate', $this, 'handle_CoreUpdate', true); $this->maniaControl->commandManager->registerCommandListener('pluginupdate', $this, 'handle_PluginUpdate', true); - $this->maniaControl->commandManager->registerCommandListener('pluginlist', $this, 'handle_PluginList', true); $this->currentBuildDate = $this->getNightlyBuildDate(); @@ -247,6 +246,7 @@ class UpdateManager implements CallbackListener, CommandListener, TimerListener public function handleManialinkPageAnswer(array $callback) { $actionId = $callback[1][2]; $update = (strpos($actionId, PluginMenu::ACTION_PREFIX_UPDATEPLUGIN) === 0); + $install = (strpos($actionId, PluginInstallMenu::ACTION_PREFIX_INSTALLPLUGIN) === 0); $login = $callback[1][1]; $player = $this->maniaControl->playerManager->getPlayer($login); @@ -263,6 +263,18 @@ class UpdateManager implements CallbackListener, CommandListener, TimerListener } } } + + if($install) { + $pluginId = substr($actionId, strlen(PluginInstallMenu::ACTION_PREFIX_INSTALLPLUGIN)); + + $url = ManiaControl::URL_WEBSERVICE . 'plugins?id=' . $pluginId; + $dataJson = FileUtil::loadFile($url); + $pluginVersions = json_decode($dataJson); + if ($pluginVersions && isset($pluginVersions[0])) { + $pluginData = $pluginVersions[0]; + $this->installPlugin($pluginData, $player, true); + } + } } /** @@ -351,39 +363,6 @@ class UpdateManager implements CallbackListener, CommandListener, TimerListener $this->checkPluginsUpdate($player); } - /** - * Handle //pluginlist command - * - * @param array $chatCallback - * @param Player $player - */ - public function handle_PluginList(array $chatCallback, Player $player) { - if (!$this->maniaControl->authenticationManager->checkPermission($player, self::SETTING_PERMISSION_UPDATE)) { - $this->maniaControl->authenticationManager->sendNotAllowed($player); - return; - } - - $url = ManiaControl::URL_WEBSERVICE . 'plugins'; - $dataJson = FileUtil::loadFile($url); - $pluginList = json_decode($dataJson); - if (!$pluginList || !isset($pluginList[0])) { - $this->maniaControl->chat->sendInformation('Pluginlist could not be retrieved from the Web Services!', $player->login); - } - - $pluginClasses = $this->maniaControl->pluginManager->getPluginClasses(); - $pluginIds = array(); - /** @var Plugin $class */ - foreach($pluginClasses as $class) { - $pluginIds[] = $class::getId(); - } - - foreach($pluginList as $plugin) { - if(!in_array($plugin->id, $pluginIds)) { - $this->maniaControl->chat->sendInformation($plugin->name.' (v'.$plugin->currentVersion->version.') - '.$plugin->description, $player->login); - } - } - } - /** * Checks if there are outdated plugins active. * @param Player $player @@ -536,6 +515,97 @@ class UpdateManager implements CallbackListener, CommandListener, TimerListener }); } + /** + * Update pluginfile + * + * @param $pluginData + * @param Player $player + * @param bool $reopen + */ + private function installPlugin($pluginData, Player $player, $reopen = false) { + $this->maniaControl->fileReader->loadFile($pluginData->currentVersion->url, function ($installFileContent, $error) use (&$updateData, &$player, &$pluginData, &$reopen) { + $pluginsDirectory = ManiaControlDir . '/plugins/'; + $pluginFiles = scandir($pluginsDirectory); + + $this->maniaControl->log('[UPDATE] Now installing '.$pluginData->name.' ...'); + $this->maniaControl->chat->sendInformation('Now installing '.$pluginData->name.' ...', $player->login); + + $tempDir = ManiaControlDir . '/temp/'; + if (!is_dir($tempDir)) { + mkdir($tempDir); + } + $installFileName = $tempDir . $pluginData->currentVersion->zipfile; + + $bytes = file_put_contents($installFileName, $installFileContent); + if (!$bytes || $bytes <= 0) { + trigger_error("Couldn't save plugin Zip."); + $this->maniaControl->chat->sendError('Install failed: Couldn\'t save plugin zip!', $player->login); + return false; + } + $zip = new \ZipArchive(); + $result = $zip->open($installFileName); + if ($result !== true) { + trigger_error("Couldn't open plugin Zip. ({$result})"); + $this->maniaControl->chat->sendError('Install failed: Couldn\'t open plugin zip!', $player->login); + return false; + } + + $zip->extractTo(ManiaControlDir.'/plugins'); + $zip->close(); + unlink($installFileName); + @rmdir($tempDir); + + $pluginFilesAfter = scandir($pluginsDirectory); + $newFiles = array_diff($pluginFilesAfter, $pluginFiles); + + $classesBefore = get_declared_classes(); + foreach($newFiles as $newFile) { + $filePath = $pluginsDirectory . $newFile; + + if (is_file($filePath)) { + $success = include_once $filePath; + if (!$success) { + trigger_error("Error loading File '{$filePath}'!"); + } + continue; + } + + $dirPath = $pluginsDirectory . $newFile; + if (is_dir($dirPath)) { + $this->maniaControl->pluginManager->loadPluginFiles($dirPath); + continue; + } + } + $classesAfter = get_declared_classes(); + + $newClasses = array_diff($classesAfter, $classesBefore); + foreach($newClasses as $className) { + if (!$this->maniaControl->pluginManager->isPluginClass($className)) { + continue; + } + + /** @var Plugin $className */ + $this->maniaControl->pluginManager->addPluginClass($className); + $className::prepare($this->maniaControl); + + if ($this->maniaControl->pluginManager->isPluginActive($className)) { + continue; + } + if (!$this->maniaControl->pluginManager->getSavedPluginStatus($className)) { + continue; + } + } + + $this->maniaControl->log('[UPDATE] Successfully installed '.$pluginData->name.'!'); + $this->maniaControl->chat->sendSuccess('Successfully installed '.$pluginData->name.'!', $player->login); + + if ($reopen) { + $menuId = $this->maniaControl->configurator->getMenuId('Install Plugins'); + $this->maniaControl->configurator->reopenMenu($player, $menuId); + } + }); + } + /** * Set Core Update Data *