Implemented first version of PresetPlugin for GameModes
This commit is contained in:
		
							
								
								
									
										380
									
								
								plugins/MCTeam/GameModePresetsPlugin.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										380
									
								
								plugins/MCTeam/GameModePresetsPlugin.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,380 @@ | ||||
| <?php | ||||
|  | ||||
| namespace MCTeam; | ||||
|  | ||||
| use ManiaControl\Admin\AuthenticationManager; | ||||
| use ManiaControl\Callbacks\TimerListener; | ||||
| use ManiaControl\Commands\CommandListener; | ||||
| use ManiaControl\Files\FileUtil; | ||||
| use ManiaControl\ManiaControl; | ||||
| use ManiaControl\Players\Player; | ||||
| use ManiaControl\Plugins\Plugin; | ||||
|  | ||||
| /** | ||||
|  * ManiaControl GameMode Presets Plugin | ||||
|  * | ||||
|  * @author    ManiaControl Team <mail@maniacontrol.com> | ||||
|  * @copyright 2014-2020 ManiaControl Team | ||||
|  * @license   http://www.gnu.org/licenses/ GNU General Public License, Version 3 | ||||
|  */ | ||||
| class GameModePresetsPlugin implements Plugin, CommandListener, TimerListener { | ||||
| 	/* | ||||
| 	 * Constants | ||||
| 	 */ | ||||
| 	const PLUGIN_ID      = 9; | ||||
| 	const PLUGIN_VERSION = 0.1; | ||||
| 	const PLUGIN_NAME    = 'GameMode Presets Plugin'; | ||||
| 	const PLUGIN_AUTHOR  = 'MCTeam'; | ||||
|  | ||||
| 	const PRESET_SETTING_MODE_NUMBER = 'Mode Number'; | ||||
| 	const PRESET_SETTING_SCRIPT_NAME = 'Script Name'; | ||||
|  | ||||
| 	const SETTING_MAP_ACTION_ON_LOADMODE          = 'Map Action on //loadmode'; | ||||
| 	const SETTING_MAP_ACTION_DELAY_ON_LOADMODE    = 'Map Action Delay on //loadmode (in ms)'; | ||||
| 	const SETTING_PERMISSION_LOAD_GAMEMODE_PRESET = 'Permission load GameMode Preset'; | ||||
| 	const SETTING_PERMISSION_SAVE_GAMEMODE_PRESET = 'Permission save GameMode Preset'; | ||||
|  | ||||
| 	const MAP_ACTION_ON_LOADMODE_NONE    = 'None'; | ||||
| 	const MAP_ACTION_ON_LOADMODE_RESTART = 'Restart Map'; | ||||
| 	const MAP_ACTION_ON_LOADMODE_SKIP    = 'Skip Map'; | ||||
|  | ||||
| 	const TABLE_GAMEMODEPRESETS = 'mc_gamemodepresets'; | ||||
|  | ||||
| 	/* | ||||
| 	 * Private properties | ||||
| 	 */ | ||||
| 	/** @var ManiaControl $maniaControl * */ | ||||
| 	private $maniaControl = null; | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::prepare() | ||||
| 	 */ | ||||
| 	public static function prepare(ManiaControl $maniaControl) { | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::load() | ||||
| 	 */ | ||||
| 	public function load(ManiaControl $maniaControl) { | ||||
| 		$this->maniaControl = $maniaControl; | ||||
|  | ||||
| 		// Authentication Permission Level | ||||
| 		$this->maniaControl->getAuthenticationManager()->definePluginPermissionLevel( | ||||
| 			$this, | ||||
| 			self::SETTING_PERMISSION_LOAD_GAMEMODE_PRESET, | ||||
| 			AuthenticationManager::AUTH_LEVEL_ADMIN, | ||||
| 			AuthenticationManager::AUTH_LEVEL_MODERATOR | ||||
| 		); | ||||
| 		$this->maniaControl->getAuthenticationManager()->definePluginPermissionLevel( | ||||
| 			$this, | ||||
| 			self::SETTING_PERMISSION_SAVE_GAMEMODE_PRESET, | ||||
| 			AuthenticationManager::AUTH_LEVEL_SUPERADMIN, | ||||
| 			AuthenticationManager::AUTH_LEVEL_MODERATOR | ||||
| 		); | ||||
|  | ||||
| 		// Settings | ||||
| 		$this->maniaControl->getSettingManager()->initSetting( | ||||
| 			$this, | ||||
| 			self::SETTING_MAP_ACTION_ON_LOADMODE, | ||||
| 			array( | ||||
| 				self::MAP_ACTION_ON_LOADMODE_NONE, | ||||
| 				self::MAP_ACTION_ON_LOADMODE_RESTART, | ||||
| 				self::MAP_ACTION_ON_LOADMODE_SKIP, | ||||
| 			) | ||||
| 		); | ||||
| 		$this->maniaControl->getSettingManager()->initSetting( | ||||
| 			$this, | ||||
| 			self::SETTING_MAP_ACTION_DELAY_ON_LOADMODE, | ||||
| 			1000 | ||||
| 		); | ||||
| 		 | ||||
| 		// Commands | ||||
| 		$this->maniaControl->getCommandManager()->registerCommandListener(array('loadmode', 'modeload'), $this, 'commandLoadMode', true, 'Loads the mode settings from the given preset name.'); | ||||
| 		$this->maniaControl->getCommandManager()->registerCommandListener(array('savemode', 'modesave'), $this, 'commandSaveMode', true, 'Saves the mode settings under the given preset name.'); | ||||
|  | ||||
| 		$this->initTables(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Initialize needed database tables | ||||
| 	 */ | ||||
| 	private function initTables() { | ||||
| 		$mysqli = $this->maniaControl->getDatabase()->getMysqli(); | ||||
| 		$query  = "CREATE TABLE IF NOT EXISTS `" . self::TABLE_GAMEMODEPRESETS . "` ( | ||||
| 				`index` int(11) NOT NULL AUTO_INCREMENT, | ||||
| 				`name` varchar(20) NOT NULL, | ||||
| 				`settings` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, | ||||
| 				PRIMARY KEY (`index`), | ||||
| 				UNIQUE KEY (`name`) | ||||
| 				) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;"; | ||||
| 		$mysqli->query($query); | ||||
| 		if ($mysqli->error) { | ||||
| 			trigger_error($mysqli->error, E_USER_ERROR); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Fetch preset from database | ||||
| 	 * @param string $name | ||||
| 	 * @return array|null | ||||
| 	 */ | ||||
| 	private function fetchPreset($name) { | ||||
| 		$mysqli = $this->maniaControl->getDatabase()->getMysqli(); | ||||
| 		$query  = "SELECT `settings` | ||||
| 				FROM `" . self::TABLE_GAMEMODEPRESETS . "` | ||||
| 				WHERE `name` LIKE ?;"; | ||||
|  | ||||
| 		$statement = $mysqli->prepare($query); | ||||
| 		if ($mysqli->error || !$statement) { | ||||
| 			trigger_error($mysqli->error, E_USER_ERROR); | ||||
| 			return null; | ||||
| 		} | ||||
|  | ||||
| 		$statement->bind_param('s', $name); | ||||
| 		$statement->execute(); | ||||
| 		if ($statement->error) { | ||||
| 			trigger_error($statement->error); | ||||
| 			$statement->close(); | ||||
| 			return null; | ||||
| 		} | ||||
|  | ||||
| 		$settings = null; | ||||
| 		$statement->store_result(); | ||||
| 		$statement->bind_result($settings); | ||||
| 		$statement->fetch(); | ||||
| 		$statement->free_result(); | ||||
|  | ||||
| 		return json_decode($settings, true); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Fetch preset from database | ||||
| 	 * @param string $name | ||||
| 	 * @return array|null | ||||
| 	 */ | ||||
| 	private function storePreset($name) { | ||||
| 		$modeNumber = $this->maniaControl->getClient()->getGameMode(); | ||||
| 		$scriptName = $this->maniaControl->getClient()->getScriptName()['CurrentValue']; | ||||
| 		$settings = null; | ||||
| 		if ($modeNumber === 0) { | ||||
| 			$settings = $this->maniaControl->getClient()->getModeScriptSettings(); | ||||
| 		} else { | ||||
| 			$settings = $this->maniaControl->getClient()->execute('GetCurrentGameInfo'); | ||||
| 		} | ||||
|  | ||||
| 		$settings[self::PRESET_SETTING_MODE_NUMBER] = $modeNumber; | ||||
| 		$settings[self::PRESET_SETTING_SCRIPT_NAME] = $scriptName; | ||||
| 		$settings = json_encode($settings); | ||||
|  | ||||
| 		$mysqli = $this->maniaControl->getDatabase()->getMysqli(); | ||||
| 		$query  = "INSERT INTO `" . self::TABLE_GAMEMODEPRESETS . "` | ||||
| 				(`name`, `settings`) VALUES (?, ?) | ||||
| 				ON DUPLICATE KEY UPDATE `settings` = VALUES(`settings`);"; | ||||
|  | ||||
| 		$statement = $mysqli->prepare($query); | ||||
| 		if ($mysqli->error || !$statement) { | ||||
| 			trigger_error($mysqli->error, E_USER_ERROR); | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		$statement->bind_param('ss', $name, $settings); | ||||
| 		$statement->execute(); | ||||
| 		if ($statement->error) { | ||||
| 			trigger_error($statement->error); | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		$statement->close(); | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Load Script | ||||
| 	 * @param string $scriptName | ||||
| 	 */ | ||||
| 	private function loadScript($scriptName) { | ||||
|         static $scriptsDir = null; | ||||
|         if ($scriptsDir === null) | ||||
|         { | ||||
|             $scriptsDataDir = FileUtil::shortenPath($this->maniaControl->getServer()->getDirectory()->getScriptsFolder()); | ||||
|             if ($this->maniaControl->getServer()->checkAccess($scriptsDataDir)) | ||||
|             { | ||||
|                 $gameShort = $this->maniaControl->getMapManager()->getCurrentMap()->getGame(); | ||||
|                 $game = ''; | ||||
|                 switch ($gameShort) | ||||
|                 { | ||||
|                     case 'qm': $game = 'QuestMania'; break; | ||||
|                     case 'sm': $game = 'ShootMania'; break; | ||||
|                     case 'tm': $game = 'TrackMania'; break; | ||||
|                 } | ||||
|  | ||||
|                 if ($game != '') | ||||
|                 { | ||||
|                     $scriptsDir = $scriptsDataDir.DIRECTORY_SEPARATOR.'Modes'.DIRECTORY_SEPARATOR.$game.DIRECTORY_SEPARATOR; | ||||
|                     if (!$this->maniaControl->getServer()->checkAccess($scriptsDir)) | ||||
|                         $scriptsDir = null; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if ($scriptsDir === null) | ||||
|                 throw new \Exception('Scripts directory not found, unable to load different scripts!'); | ||||
| 		} | ||||
| 		 | ||||
| 		$scriptPath = $scriptsDir.$scriptName; | ||||
| 		if (!file_exists($scriptPath)) | ||||
| 			throw new \Exception('Script not found ('.$scriptPath.').'); | ||||
|  | ||||
| 		$scriptText = file_get_contents($scriptPath); | ||||
|  | ||||
|         $this->maniaControl->getClient()->setModeScriptText($scriptText); | ||||
|         $this->maniaControl->getClient()->setScriptName($scriptName); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Handle //loadmode command | ||||
| 	 * | ||||
| 	 * @param array                        $chatCallback | ||||
| 	 * @param \ManiaControl\Players\Player $player | ||||
| 	 */ | ||||
| 	public function commandLoadMode(array $chatCallback, Player $player) { | ||||
| 		if (!$this->maniaControl->getAuthenticationManager()->checkPluginPermission($this, $player, self::SETTING_PERMISSION_LOAD_GAMEMODE_PRESET)) { | ||||
| 			$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		// Check for delayed shutdown | ||||
| 		$params = explode(' ', $chatCallback[1][2]); | ||||
| 		if (count($params) < 2) { | ||||
| 			$this->maniaControl->getChat()->sendError('You must provide a gamemode preset name to load settings from!', $player); | ||||
| 			return; | ||||
| 		} elseif (count($params) > 2) { | ||||
| 			$this->maniaControl->getChat()->sendError('You can only provide one gamemode preset name to load settings from!', $player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$presetName = strtolower($params[1]); | ||||
| 		$presetSettings = $this->fetchPreset($presetName); | ||||
| 		if (!$presetSettings) { | ||||
| 			$this->maniaControl->getChat()->sendError('The gamemode preset $<$fff' . $presetName . '$> does not exist!', $player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$modeNumber = $presetSettings[self::PRESET_SETTING_MODE_NUMBER]; | ||||
| 		$scriptName = $presetSettings[self::PRESET_SETTING_SCRIPT_NAME]; | ||||
| 		unset($presetSettings[self::PRESET_SETTING_MODE_NUMBER]); | ||||
| 		unset($presetSettings[self::PRESET_SETTING_SCRIPT_NAME]); | ||||
|  | ||||
| 		// this is a hack, because this setting always throws errors otherwise | ||||
| 		$presetSettings['S_MatchmakingRematchRatio'] = floatval($presetSettings['S_MatchmakingRematchRatio']); | ||||
|  | ||||
| 		try { | ||||
| 			$this->maniaControl->getClient()->setGameMode($modeNumber); | ||||
| 			if ($modeNumber === 0) { | ||||
| 				$this->loadScript($scriptName); | ||||
|         		$this->maniaControl->getClient()->setModeScriptSettings($presetSettings); | ||||
| 			} else { | ||||
| 				$this->maniaControl->getClient()->setScriptName($scriptName); | ||||
| 				$this->maniaControl->getClient()->execute('SetGameInfos', $presetSettings); | ||||
| 			} | ||||
| 		} catch (\Exception $e) { | ||||
| 			$this->maniaControl->getChat()->sendException($e, $player); | ||||
| 			$this->maniaControl->getChat()->sendError('Unable to load gamemode preset $<$fff' . $presetName . '$>!', $player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$this->maniaControl->getChat()->sendSuccess($player->getEscapedNickname() . ' loaded gamemode preset $<$fff' . $presetName . '$>!'); | ||||
| 		$this->maniaControl->getTimerManager()->registerOneTimeListening( | ||||
| 			$this, | ||||
| 			function () { | ||||
| 				$mapActionOnLoadmode = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MAP_ACTION_ON_LOADMODE); | ||||
| 				switch ($mapActionOnLoadmode) { | ||||
| 					case self::MAP_ACTION_ON_LOADMODE_NONE: | ||||
| 					break; | ||||
| 					case self::MAP_ACTION_ON_LOADMODE_RESTART: | ||||
| 						$this->maniaControl->getMapManager()->getMapActions()->restartMap(); | ||||
| 					break; | ||||
| 					case self::MAP_ACTION_ON_LOADMODE_SKIP: | ||||
| 						$this->maniaControl->getMapManager()->getMapActions()->skipMap(); | ||||
| 					break; | ||||
| 				} | ||||
| 			}, | ||||
| 			$this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MAP_ACTION_DELAY_ON_LOADMODE) | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Handle //savemode command | ||||
| 	 * | ||||
| 	 * @param array                        $chatCallback | ||||
| 	 * @param \ManiaControl\Players\Player $player | ||||
| 	 */ | ||||
| 	public function commandSaveMode(array $chatCallback, Player $player) { | ||||
| 		if (!$this->maniaControl->getAuthenticationManager()->checkPluginPermission($this, $player, self::SETTING_PERMISSION_LOAD_GAMEMODE_PRESET)) { | ||||
| 			$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		// Check for delayed shutdown | ||||
| 		$params = explode(' ', $chatCallback[1][2]); | ||||
| 		if (count($params) < 2) { | ||||
| 			$this->maniaControl->getChat()->sendError('You must provide a gamemode preset name to save settings into!', $player); | ||||
| 			return; | ||||
| 		} elseif (count($params) > 2) { | ||||
| 			$this->maniaControl->getChat()->sendError('You can only provide one gamemode preset name to save settings into!', $player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$presetName = strtolower($params[1]); | ||||
| 		try { | ||||
| 			$this->storePreset($presetName); | ||||
| 		} catch (\Exception $e) { | ||||
| 			$this->maniaControl->getChat()->sendException($e, $player); | ||||
| 			$this->maniaControl->getChat()->sendError('Unable to save gamemode preset $<$fff' . $presetName . '$>!', $player); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$this->maniaControl->getChat()->sendSuccess($player->getEscapedNickname() . ' saved gamemode settings in preset $<$fff"' . $presetName . '"$>!'); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::getId() | ||||
| 	 */ | ||||
| 	public static function getId() { | ||||
| 		return self::PLUGIN_ID; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::getName() | ||||
| 	 */ | ||||
| 	public static function getName() { | ||||
| 		return self::PLUGIN_NAME; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::getVersion() | ||||
| 	 */ | ||||
| 	public static function getVersion() { | ||||
| 		return self::PLUGIN_VERSION; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::getAuthor() | ||||
| 	 */ | ||||
| 	public static function getAuthor() { | ||||
| 		return self::PLUGIN_AUTHOR; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::getDescription() | ||||
| 	 */ | ||||
| 	public static function getDescription() { | ||||
| 		return "Plugin offers presets functionalites for GameModes"; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @see \ManiaControl\Plugins\Plugin::unload() | ||||
| 	 */ | ||||
| 	public function unload() { | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user