diff --git a/MatchManagerSuite/MatchManagerMultipleConfigManager.php b/MatchManagerSuite/MatchManagerMultipleConfigManager.php index bcbabf4..447e7ef 100644 --- a/MatchManagerSuite/MatchManagerMultipleConfigManager.php +++ b/MatchManagerSuite/MatchManagerMultipleConfigManager.php @@ -2,35 +2,37 @@ namespace MatchManagerSuite; -use FML\Controls\Frame; +use FML\Controls\Labels\Label_Button; use FML\Controls\Labels\Label_Text; -use FML\Controls\Label; use FML\Controls\Quad; +use FML\Controls\Frame; +use FML\Controls\Entry; +use FML\Components\CheckBox; +use FML\Controls\Quads\Quad_BgsPlayerCard; use FML\ManiaLink; +use FML\Script\Features\Paging; +use ManiaControl\Manialinks\LabelLine; +use ManiaControl\Manialinks\ManialinkManager; +use ManiaControl\Manialinks\ManialinkPageAnswerListener; + use ManiaControl\Callbacks\CallbackListener; use ManiaControl\Callbacks\CallbackManager; -use ManiaControl\Callbacks\Callbacks; use ManiaControl\Logger; use ManiaControl\ManiaControl; -use ManiaControl\Manialinks\ManialinkPageAnswerListener; use ManiaControl\Players\Player; -use ManiaControl\Players\PlayerManager; use ManiaControl\Plugins\Plugin; -use ManiaControl\Settings\Setting; -use ManiaControl\Settings\SettingManager; +use ManiaControl\Plugins\PluginManager; use ManiaControl\Commands\CommandListener; - if (!class_exists('MatchManagerSuite\MatchManagerCore')) { - $this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is needed to use MatchManager Multiple Config Manager plugin. Install it and restart Maniacontrol'); - Logger::logError('MatchManager Core is needed to use MatchManager Multiple Config Manager plugin. Install it and restart Maniacontrol'); + $this->maniaControl->getChat()->sendErrorToAdmins('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol'); + Logger::logError('MatchManager Core is required to use one of MatchManager plugin. Install it and restart Maniacontrol'); return false; } use MatchManagerSuite\MatchManagerCore; - /** - * MatchManager Widgets + * MatchManager Multiple Config Manager * * @author Beu * @license http://www.gnu.org/licenses/ GNU General Public License, Version 3 @@ -49,6 +51,14 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener, const DB_MATCHCONFIG = 'MatchManager_MatchConfigs'; + const ML_ID = 'MatchManager.MultiConfigManager.UI'; + const ML_ACTION_REMOVE_CONFIG = 'MatchManager.MultiConfigManager.RemoveConfig'; + const ML_ACTION_LOAD_CONFIG = 'MatchManager.MultiConfigManager.LoadConfig'; + const ML_ACTION_LOAD_CONFIG_PAGE = 'MatchManager.MultiConfigManager.LoadConfigPage'; + const ML_ACTION_SAVE_CONFIG = 'MatchManager.MultiConfigManager.SaveConfig'; + const ML_ACTION_SAVE_CONFIG_PAGE = 'MatchManager.MultiConfigManager.SaveConfigPage'; + const ML_NAME_CONFIGNAME = 'MatchManager.MultiConfigManager.ConfigName'; + /* * Private properties */ @@ -56,7 +66,6 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener, private $maniaControl = null; private $MatchManagerCore = null; - /** * @param \ManiaControl\ManiaControl $maniaControl * @see \ManiaControl\Plugins\Plugin::prepare() @@ -113,8 +122,13 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener, throw new \Exception('MatchManager Core is needed to use MatchManager Players Pause plugin'); } - $this->initTables(); + $this->maniaControl->getCallbackManager()->registerCallbackListener(PluginManager::CB_PLUGIN_UNLOADED, $this, 'handlePluginUnloaded'); + $this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_PLAYERMANIALINKPAGEANSWER, $this, 'handleManialinkPageAnswer'); + $this->maniaControl->getCommandManager()->registerCommandListener('matchconfig', $this, 'showConfigListUI', true, 'Start a match'); + + + $this->initTables(); return true; } @@ -124,6 +138,19 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener, public function unload() { } + /** + * handlePluginUnloaded + * + * @param string $pluginClass + * @param Plugin $plugin + * @return void + */ + public function handlePluginUnloaded(string $pluginClass, Plugin $plugin) { + if ($pluginClass == self::MATCHMANAGERCORE_PLUGIN) { + $this->maniaControl->getChat()->sendErrorToAdmins(self::PLUGIN_NAME . " disabled because MatchManager Core is now disabled"); + $this->maniaControl->getPluginManager()->deactivatePlugin((get_class())); + } + } /** * Initialize needed database tables @@ -144,5 +171,475 @@ class MatchManagerMultipleConfigManager implements ManialinkPageAnswerListener, } } + /** + * handleManialinkPageAnswer + * + * @param array $callback + * @return void + */ + public function handleManialinkPageAnswer(array $callback) { + Logger::log("handleManialinkPageAnswer"); + $actionId = $callback[1][2]; + $actionArray = explode('.', $actionId); + if ($actionArray[0] != "MatchManager" || $actionArray[1] != "MultiConfigManager") { + return; + } + $login = $callback[1][1]; + $player = $this->maniaControl->getPlayerManager()->getPlayer($login); + if ($player->authLevel <= 0) { + return; + } + + $action = $actionArray[0] . '.' . $actionArray[1] . '.' . $actionArray[2]; + + switch ($action) { + case self::ML_ACTION_REMOVE_CONFIG: + $id = intval($actionArray[3]); + Logger::log("[MatchManagerMultipleConfigManager] Removing config: " . $id); + $mysqli = $this->maniaControl->getDatabase()->getMysqli(); + + $query = $mysqli->prepare('DELETE FROM `'. self::DB_MATCHCONFIG .'` WHERE id = ?;'); + $query->bind_param('i', $id); + if (!$query->execute()) { + trigger_error('Error executing MySQL query: ' . $query->error); + } + $this->showConfigListUI(array(), $player); + break; + case self::ML_ACTION_LOAD_CONFIG_PAGE: + $this->showConfigListUI(array(), $player); + break; + case self::ML_ACTION_LOAD_CONFIG: + $id = intval($actionArray[3]); + // Hide loading before because it can take few seconds + $this->maniaControl->getManialinkManager()->hideManialink(ManialinkManager::MAIN_MLID, $login); + $this->loadConfig($id); + break; + case self::ML_ACTION_SAVE_CONFIG_PAGE: + $this->showSaveConfigUI($player); + break; + case self::ML_ACTION_SAVE_CONFIG: + if ($callback[1][3][0]["Value"]) { + $this->showConfigListUI(array(), $player); + $this->saveConfig($callback[1][3]); + $this->showConfigListUI(array(), $player); + } + break; + } + } + + /** + * loadConfig + * + * @param int $id + * @return void + */ + private function loadConfig(int $id) { + if ($this->MatchManagerCore->getMatchStatus()) { + Logger::logError("Impossible to load config during a match"); + $this->maniaControl->getChat()->sendErrorToAdmins('Impossible to load config during a match'); + return; + } + $mysqli = $this->maniaControl->getDatabase()->getMysqli(); + + $query = $mysqli->prepare('SELECT name,config FROM `'. self::DB_MATCHCONFIG .'` WHERE id = ?;'); + $query->bind_param('i', $id); + + if (!$query->execute()) { + trigger_error('Error executing MySQL query: ' . $query->error); + } + $mysqlresult = $query->get_result(); + + $result = array(); + while ($row = $mysqlresult->fetch_assoc()) { + array_push($result, $row); + } + + if ($result[0] && $result[0]["config"]) { + $allconfigs = json_decode($result[0]["config"],true); + if ($allconfigs != null) { + Logger::log("[MatchManagerMultipleConfigManager] Loading config: " . $id); + $someconfignotloaded = false; + foreach ($allconfigs as $plugin => $configs) { + $pluginclass = $this->maniaControl->getPluginManager()->getPlugin($plugin); + if ($pluginclass != null) { + foreach ($configs as $name => $value) { + $setting = $this->maniaControl->getSettingManager()->getSettingObject($pluginclass, $name); + if ($setting != null) { + if ($setting->value != $value) { + Logger::log("Saving new setting " . $name); + $setting->value = $value; + $this->maniaControl->getSettingManager()->saveSetting($setting); + } + } else { + $someconfignotloaded = true; + Logger::log("Unable to load setting: " . $name); + } + } + } + } + if ($someconfignotloaded) { + $this->maniaControl->getChat()->sendErrorToAdmins('One or more settings could not be imported'); + } + $this->maniaControl->getChat()->sendSuccessToAdmins('MatchManager Config "' . $result[0]["name"] . '" loaded'); + } + } + } + + /** + * saveConfig + * + * @param array $fields + * @return void + */ + private function saveConfig(array $fields) { + Logger::log("[MatchManagerMultipleConfigManager] Saving current config"); + $result = array(); + $configname = ""; + $gamemodebase = ""; + + foreach($fields as $field) { + if ($field["Name"] == self::ML_NAME_CONFIGNAME) { + $configname = $field["Value"]; + continue; + } + if (strpos($field["Name"], self::ML_ACTION_SAVE_CONFIG) === 0) { + if ($field["Value"] == "1") { + $class = substr($field["Name"],strlen(self::ML_ACTION_SAVE_CONFIG) + 1); + $result[$class] = array(); + $settings = $this->maniaControl->getSettingManager()->getSettingsByClass($class); + foreach ($settings as $setting) { + $result[$class][$setting->setting] = $setting->value; + + if ($setting->setting == MatchManagerCore::SETTING_MATCH_GAMEMODE_BASE) { + $gamemodebase = $setting->value; + } + } + } + } + } + + if ($configname == "" || count($result) == 0 || $gamemodebase == "") { + return; + } + + $config = json_encode($result); + + $mysqli = $this->maniaControl->getDatabase()->getMysqli(); + $query = $mysqli->prepare('INSERT INTO `' . self::DB_MATCHCONFIG . '` (`name`,`gamemodebase`,`config`) VALUES (?, ?, ?);'); + $query->bind_param('sss', $configname, $gamemodebase, $config); + if (!$query->execute()) { + trigger_error('Error executing MySQL query: ' . $query->error); + } + } + + + /** + * Shows a ManiaLink list with the local records. + * + * @api + * @param array $chat + * @param Player $player + */ + public function showConfigListUI(array $chat, Player $player) { + Logger::log("showConfigListUI"); + $width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth(); + $height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight(); + + // create manialink + $maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID); + $script = $maniaLink->getScript(); + $paging = new Paging(); + $script->addFeature($paging); + + // Main frame + $frame = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultListFrame($script, $paging); + $maniaLink->addChild($frame); + + // Start offsets + $posX = -$width / 2; + $posY = $height / 2; + + // Predefine Description Label + $descriptionLabel = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultDescriptionLabel(); + $frame->addChild($descriptionLabel); + + // Headline + $headFrame = new Frame(); + $frame->addChild($headFrame); + $headFrame->setY($posY - 5); + + $labelLine = new LabelLine($headFrame); + $labelLine->addLabelEntryText('ID', $posX + 5); + $labelLine->addLabelEntryText('Name', $posX + 15); + $labelLine->addLabelEntryText('Game mode base', $posX + 70); + $labelLine->addLabelEntryText('Date', $posX + 110); + $labelLine->addLabelEntryText('Actions', $width / 2 - 16); + $labelLine->render(); + + $index = 0; + $posY = $height / 2 - 10; + $pageFrame = null; + + // get data + $mysqli = $this->maniaControl->getDatabase()->getMysqli(); + $query = 'SELECT `id`,`name`,`gamemodebase`,`date` FROM `' . self::DB_MATCHCONFIG . '` ORDER BY id DESC'; + $result = $mysqli->query($query); + if ($mysqli->error) { + trigger_error($mysqli->error, E_USER_ERROR); + } + + while ($config = $result->fetch_object()) { + if ($index % 16 === 0) { + $pageFrame = new Frame(); + $frame->addChild($pageFrame); + $posY = $height / 2 - 10; + $paging->addPageControl($pageFrame); + } + + $configFrame = new Frame(); + $pageFrame->addChild($configFrame); + + if ($index % 2 === 0) { + $lineQuad = new Quad_BgsPlayerCard(); + $configFrame->addChild($lineQuad); + $lineQuad->setSize($width, 4); + $lineQuad->setSubStyle($lineQuad::SUBSTYLE_BgPlayerCardBig); + $lineQuad->setZ(-0.001); + } + + $labelLine = new LabelLine($configFrame); + $labelLine->addLabelEntryText($config->id, $posX + 5, 13); + $labelLine->addLabelEntryText($config->name, $posX + 15, 52); + $labelLine->addLabelEntryText($config->gamemodebase, $posX + 70, 31); + $labelLine->addLabelEntryText($config->date, $posX + 100, $width / 2 - ($posX + 110)); + $labelLine->render(); + + // Remove Config button + $removeButton = new Label_Button(); + $configFrame->addChild($removeButton); + $removeButton->setX($width / 2 - 5); + $removeButton->setZ(0.2); + $removeButton->setSize(3, 3); + $removeButton->setTextSize(1); + $removeButton->setText(''); + $removeButton->setTextColor('a00'); + + $confirmFrame = $this->buildConfirmFrame($maniaLink, $posY, $config->id, true); + $removeButton->addToggleFeature($confirmFrame); + $description = 'Remove Config: ' . $config->name; + $removeButton->addTooltipLabelFeature($descriptionLabel, $description); + + // Load config button + if (!$this->MatchManagerCore->getMatchStatus()) { + $loadLabel = new Label_Button(); + $configFrame->addChild($loadLabel); + $loadLabel->setX($width / 2 - 9); + $loadLabel->setZ(0.2); + $loadLabel->setSize(3, 3); + $loadLabel->setTextSize(1); + $loadLabel->setText(''); + $loadLabel->setTextColor('0f0'); + + $confirmFrame = $this->buildConfirmFrame($maniaLink, $posY, $config->id); + $loadLabel->addToggleFeature($confirmFrame); + $description = 'Load Config: ' . $config->name; + $loadLabel->addTooltipLabelFeature($descriptionLabel, $description); + } + $configFrame->setY($posY); + + $posY -= 4; + $index++; + } + + //Search for Map-Name + $mapNameButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton( + 'Save current config', + 35, + 5, + self::ML_ACTION_SAVE_CONFIG_PAGE + ); + $frame->addChild($mapNameButton); + $mapNameButton->setPosition(-$width / 2 + 110, -36); + + // Render and display xml + $this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $player, self::ML_ID); + } + + /** + * Shows a ManiaLink list with the local records. + * + * @api + * @param array $chat + * @param Player $player + */ + public function showSaveConfigUI(Player $player) { + Logger::log("showConfigListUI"); + $width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth(); + $height = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsHeight(); + + // create manialink + $maniaLink = new ManiaLink(ManialinkManager::MAIN_MLID); + $script = $maniaLink->getScript(); + $paging = new Paging(); + $script->addFeature($paging); + + // Main frame + $frame = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultListFrame($script, $paging); + $maniaLink->addChild($frame); + + // Start offsets + $posX = -$width / 2; + $posY = $height / 2 -12; + + // Predefine Description Label + $descriptionLabel = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultDescriptionLabel(); + $frame->addChild($descriptionLabel); + + // Headline + $headFrame = new Frame(); + $frame->addChild($headFrame); + $headFrame->setY($posY + 7); + + $labelLine = new LabelLine($headFrame); + $labelLine->addLabelEntryText('Plugin Name', $posX + 5); + $labelLine->addLabelEntryText('Save', $width / 2 - 20); + $labelLine->setTextSize(2); + $labelLine->setPrefix('$o'); + $labelLine->render(); + + $index = 0; + $lineHeight = 5; + $pageFrame = null; + + // get data + $plugins = $this->maniaControl->getSettingManager()->getSettingClasses(); + + foreach ($plugins as $class) { + if (strpos($class, "MatchManagerSuite\\") !== 0) { + continue; + } + + if ($index % 12 === 0) { + $pageFrame = new Frame(); + $frame->addChild($pageFrame); + $posY = $height / 2 - 12; + $paging->addPageControl($pageFrame); + } + $settingFrame = new Frame(); + $pageFrame->addChild($settingFrame); + $settingFrame->setY($posY); + + $nameLabel = new Label_Text(); + $settingFrame->addChild($nameLabel); + $nameLabel->setHorizontalAlign($nameLabel::LEFT); + $nameLabel->setX($width * -0.46); + $nameLabel->setSize($width * 0.6, $lineHeight); + $nameLabel->setStyle($nameLabel::STYLE_TextCardSmall); + $nameLabel->setTextSize(2); + $nameLabel->setText($class); + $nameLabel->setTextColor('fff'); + + $quad = new Quad(); + $quad->setPosition($width * 0.4, 0, -0.01); + $quad->setSize(4, 4); + $checkBox = new CheckBox(self::ML_ACTION_SAVE_CONFIG . '.' . $class, true, $quad); + $settingFrame->addChild($checkBox); + + $posY -= $lineHeight; + + $index++; + } + + $backButton = new Label_Button(); + $frame->addChild($backButton); + $backButton->setStyle($backButton::STYLE_CardMain_Quit); + $backButton->setHorizontalAlign($backButton::LEFT); + $backButton->setScale(0.5); + $backButton->setText('Back'); + $backButton->setPosition(-$width / 2 + 5, -$height / 2 + 5); + $backButton->setAction(self::ML_ACTION_LOAD_CONFIG_PAGE); + + //Search for Map-Name + $mapNameButton = $this->maniaControl->getManialinkManager()->getElementBuilder()->buildRoundTextButton( + 'Save with the name:', + 35, + 5, + self::ML_ACTION_SAVE_CONFIG + ); + $frame->addChild($mapNameButton); + $mapNameButton->setPosition(-$width / 2 + 60, -35); + + $entry = new Entry(); + $frame->addChild($entry); + $entry->setStyle(Label_Text::STYLE_TextValueSmall); + $entry->setHorizontalAlign($entry::LEFT); + $entry->setPosition(-$width / 2 + 80, -35); + $entry->setTextSize(1); + $entry->setSize($width * 0.25, 4); + $entry->setName(self::ML_NAME_CONFIGNAME); + + // Render and display xml + $this->maniaControl->getManialinkManager()->displayWidget($maniaLink, $player, self::ML_ID); + } + + + /** + * Builds the confirmation frame + * + * @param ManiaLink $maniaLink + * @param float $posY + * @param bool $mapUid + * @param bool $remove + * @return Frame + */ + public function buildConfirmFrame(Manialink $maniaLink, $posY, $configId, $remove = false) { + $width = $this->maniaControl->getManialinkManager()->getStyleManager()->getListWidgetsWidth(); + $quadStyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowStyle(); + $quadSubstyle = $this->maniaControl->getManialinkManager()->getStyleManager()->getDefaultMainWindowSubStyle(); + + $confirmFrame = new Frame(); + $maniaLink->addChild($confirmFrame); + $confirmFrame->setPosition($width / 2 + 6, $posY); + $confirmFrame->setVisible(false); + $confirmFrame->setZ(ManialinkManager::MAIN_MANIALINK_Z_VALUE); + + $quad = new Quad(); + $confirmFrame->addChild($quad); + $quad->setStyles($quadStyle, $quadSubstyle); + $quad->setSize(13, 4); + $quad->setZ(-0.5); + + $quad = new Quad_BgsPlayerCard(); + $confirmFrame->addChild($quad); + $quad->setSubStyle($quad::SUBSTYLE_BgCardSystem); + $quad->setSize(12, 3.5); + $quad->setZ(-0.3); + + $label = new Label_Button(); + $confirmFrame->addChild($label); + $label->setText('Sure?'); + $label->setTextSize(1); + $label->setScale(0.90); + $label->setX(-1.3); + + $buttLabel = new Label_Button(); + $confirmFrame->addChild($buttLabel); + $buttLabel->setPosition(4, 0, 0.2); + $buttLabel->setSize(3, 3); + + if ($remove) { + $buttLabel->setTextSize(1); + $buttLabel->setTextColor('a00'); + $buttLabel->setText(''); + $quad->setAction(self::ML_ACTION_REMOVE_CONFIG . '.' . $configId); + } else { + $buttLabel->setTextSize(1); + $buttLabel->setTextColor('0f0'); + $buttLabel->setText(''); + $quad->setAction(self::ML_ACTION_LOAD_CONFIG . '.' . $configId); + } + + return $confirmFrame; + } } \ No newline at end of file