some improvements
This commit is contained in:
		
				
					committed by
					
						 Steffen Schröder
						Steffen Schröder
					
				
			
			
				
	
			
			
			
						parent
						
							6ccb5117ae
						
					
				
				
					commit
					c38f6011b8
				
			
							
								
								
									
										108
									
								
								application/core/Server/RankingManager.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								application/core/Server/RankingManager.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Class managing Rankings | ||||
|  * | ||||
|  * @author steeffeen & kremsy | ||||
|  */ | ||||
| namespace ManiaControl\Server; | ||||
|  | ||||
|  | ||||
| use ManiaControl\Callbacks\CallbackListener; | ||||
| use ManiaControl\Callbacks\CallbackManager; | ||||
| use ManiaControl\ManiaControl; | ||||
|  | ||||
| class RankingManager implements CallbackListener { | ||||
| 	/** | ||||
| 	 * Private Properties | ||||
| 	 */ | ||||
| 	private $rankings = array(); | ||||
|  | ||||
| 	/** | ||||
| 	 * @return mixed | ||||
| 	 */ | ||||
| 	public function getRankings() { | ||||
| 		return $this->rankings; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Construct player manager | ||||
| 	 * | ||||
| 	 * @param \ManiaControl\ManiaControl $maniaControl | ||||
| 	 */ | ||||
| 	public function __construct(ManiaControl $maniaControl) { //TODO statistic wins | ||||
| 		$this->maniaControl = $maniaControl; | ||||
|  | ||||
| 		//Register Callbacks | ||||
| 		$this->maniaControl->callbackManager->registerCallbackListener(CallbackManager::CB_MP_MODESCRIPTCALLBACK, $this, 'handleCallbacks'); | ||||
| 		$this->maniaControl->callbackManager->registerCallbackListener(CallbackManager::CB_MP_MODESCRIPTCALLBACKARRAY, $this, 'handleCallbacks'); | ||||
| 		$this->maniaControl->callbackManager->registerCallbackListener(CallbackManager::CB_MC_ONINIT, $this, 'onInit'); | ||||
| 		//TODO won message at end of the map (disable as setting) | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 *    Initialize the Rankings | ||||
| 	 */ | ||||
| 	public function onInit() { | ||||
| 		$this->maniaControl->client->triggerModeScriptEvent('LibXmlRpc_GetRankings', ''); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Handle stats on callbacks | ||||
| 	 * | ||||
| 	 * @param array $callback | ||||
| 	 */ | ||||
| 	public function handleCallbacks(array $callback) { | ||||
| 		$callbackName = $callback[1][0]; | ||||
|  | ||||
| 		//TODO not tested in TrackMania | ||||
| 		switch($callbackName) { | ||||
| 			case 'LibXmlRpc_Rankings': | ||||
| 			case 'updateRankings': | ||||
| 				$this->updateRankings($callback[1][1][0]); | ||||
| 				break; | ||||
| 			case 'endRound': | ||||
| 			case 'beginRound': | ||||
| 			case 'endMap': | ||||
| 			case 'endMap1': | ||||
| 				$this->updateRankings($callback[1]); | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Update Game Rankings | ||||
| 	 * | ||||
| 	 * @param $data | ||||
| 	 */ | ||||
| 	private function updateRankings($data) { | ||||
| 		$scores = explode(';', $data); | ||||
| 		foreach($scores as $player) { | ||||
| 			if (strpos($player, ':') !== false) { | ||||
| 				$tmp                     = explode(':', $player); | ||||
| 				$this->rankings[$tmp[0]] = $tmp[1]; | ||||
| 			} | ||||
| 		} | ||||
| 		array_multisort($this->rankings, SORT_DESC, SORT_NUMERIC); | ||||
|  | ||||
| 		//TODO if Local Records activated-> sort asc | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Get the Current Leading Players (as Login Array) | ||||
| 	 * | ||||
| 	 * @return array|null | ||||
| 	 */ | ||||
| 	public function getLeaders() { | ||||
| 		$leaders = array(); | ||||
| 		$prev    = -1; | ||||
| 		foreach($this->rankings as $player => $score) { | ||||
| 			if ($prev != -1 && $prev < $score) { | ||||
| 				return $leaders; | ||||
| 			} | ||||
| 			array_push($leaders, $leader); | ||||
| 			$prev = $score; | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| }  | ||||
| @@ -33,7 +33,7 @@ class Server implements CallbackListener { | ||||
| 	public $dataDirectory = ''; | ||||
| 	public $serverCommands = null; | ||||
| 	public $usageReporter = null; | ||||
|  | ||||
| 	public $rankingManager = null; | ||||
|  | ||||
| 	/** | ||||
| 	 * Private Properties | ||||
| @@ -52,6 +52,7 @@ class Server implements CallbackListener { | ||||
|  | ||||
| 		$this->serverCommands = new ServerCommands($maniaControl); | ||||
| 		$this->usageReporter  = new UsageReporter($maniaControl); | ||||
| 		$this->rankingManager = new RankingManager($maniaControl); | ||||
|  | ||||
| 		// Register for callbacks | ||||
| 		$this->maniaControl->callbackManager->registerCallbackListener(CallbackManager::CB_MC_ONINIT, $this, 'onInit'); | ||||
|   | ||||
| @@ -74,9 +74,9 @@ class SimpleStatsList implements ManialinkPageAnswerListener, CallbackListener, | ||||
| 		$this->registerStat(StatisticCollector::STAT_ON_DEATH, 50, "D"); | ||||
| 		$this->registerStat(StatisticCollector::STAT_ON_CAPTURE, 60, "C"); | ||||
|  | ||||
| 		$this->registerStat(StatisticManager::SPECIAL_STAT_KD_RATIO, 70, "K/D", 10, StatisticManager::STAT_TYPE_FLOAT); | ||||
| 		$this->registerStat(StatisticManager::SPECIAL_STAT_LASER_ACC, 80, "Lacc", 13, StatisticManager::STAT_TYPE_FLOAT); | ||||
| 		$this->registerStat(StatisticManager::SPECIAL_STAT_HITS_PH, 85, "H/h", 13, StatisticManager::STAT_TYPE_FLOAT); | ||||
| 		$this->registerStat(StatisticManager::SPECIAL_STAT_KD_RATIO, 70, "K/D", 12, StatisticManager::STAT_TYPE_FLOAT); | ||||
| 		$this->registerStat(StatisticManager::SPECIAL_STAT_LASER_ACC, 80, "Lacc", 15, StatisticManager::STAT_TYPE_FLOAT); | ||||
| 		$this->registerStat(StatisticManager::SPECIAL_STAT_HITS_PH, 85, "H/h", 15, StatisticManager::STAT_TYPE_FLOAT); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -90,7 +90,7 @@ class SimpleStatsList implements ManialinkPageAnswerListener, CallbackListener, | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	public function registerStat($statName, $order, $headShortCut, $width = 8, $format = StatisticManager::STAT_TYPE_INT) { | ||||
| 	public function registerStat($statName, $order, $headShortCut, $width = 10, $format = StatisticManager::STAT_TYPE_INT) { | ||||
| 		$this->statArray[$order]                 = array(); | ||||
| 		$this->statArray[$order]["Name"]         = $statName; | ||||
| 		$this->statArray[$order]["HeadShortCut"] = '$o' . $headShortCut; | ||||
|   | ||||
| @@ -23,6 +23,7 @@ class StatisticCollector implements CallbackListener { | ||||
| 	 * Statistics | ||||
| 	 */ | ||||
| 	const STAT_PLAYTIME                  = 'Play Time'; | ||||
| 	const STAT_MAP_WINS                  = 'Map Wins'; | ||||
| 	const STAT_ON_SHOOT                  = 'Shots'; | ||||
| 	const STAT_ON_NEARMISS               = 'Near Misses'; | ||||
| 	const STAT_ON_CAPTURE                = 'Captures'; | ||||
| @@ -53,6 +54,7 @@ class StatisticCollector implements CallbackListener { | ||||
| 	private $maniaControl = null; | ||||
| 	private $onShootArray = array(); | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Construct player manager | ||||
| 	 * | ||||
| @@ -81,6 +83,7 @@ class StatisticCollector implements CallbackListener { | ||||
| 	public function onInit(array $callback) { | ||||
| 		//Define Stats MetaData | ||||
| 		$this->maniaControl->statisticManager->defineStatMetaData(self::STAT_PLAYTIME, StatisticManager::STAT_TYPE_TIME); | ||||
| 		$this->maniaControl->statisticManager->defineStatMetaData(self::STAT_MAP_WINS); | ||||
| 		$this->maniaControl->statisticManager->defineStatMetaData(self::STAT_ON_SHOOT); | ||||
| 		$this->maniaControl->statisticManager->defineStatMetaData(self::STAT_ON_NEARMISS); | ||||
| 		$this->maniaControl->statisticManager->defineStatMetaData(self::STAT_ON_CAPTURE); | ||||
| @@ -99,6 +102,25 @@ class StatisticCollector implements CallbackListener { | ||||
| 		$this->maniaControl->statisticManager->defineStatMetaData(self::STAT_ARROW_SHOT); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Handle EndMap | ||||
| 	 * | ||||
| 	 * @param array $callback | ||||
| 	 */ | ||||
| 	public function onEndMap(array $callback) { | ||||
| 		//Check for Minimum PlayerCount | ||||
| 		if (count($this->maniaControl->playerManager->getPlayers()) < $this->maniaControl->settingManager->getSetting($this, self::SETTING_COLLECT_STATS_MINPLAYERS)) { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		$leaders = $this->maniaControl->server->rankingManager->getLeaders(); | ||||
|  | ||||
| 		foreach($leaders as $leaderLogin) { | ||||
| 			$leader = $this->maniaControl->playerManager->getPlayer($leaderLogin); | ||||
| 			$this->maniaControl->statisticManager->incrementStat(self::STAT_MAP_WINS, $leader); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Handle Player Shoots | ||||
| 	 * | ||||
| @@ -142,7 +164,6 @@ class StatisticCollector implements CallbackListener { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the Weapon stat | ||||
| 	 * | ||||
| @@ -179,7 +200,6 @@ class StatisticCollector implements CallbackListener { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/** | ||||
| 	 * Insert OnShoot Statistic when a player leaves | ||||
| 	 * | ||||
| @@ -213,7 +233,7 @@ class StatisticCollector implements CallbackListener { | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		//Check for Minplayer | ||||
| 		//Check for Minimum PlayerCount | ||||
| 		if (count($this->maniaControl->playerManager->getPlayers()) < $this->maniaControl->settingManager->getSetting($this, self::SETTING_COLLECT_STATS_MINPLAYERS)) { | ||||
| 			return; | ||||
| 		} | ||||
|   | ||||
| @@ -65,6 +65,52 @@ class StatisticManager { | ||||
| 	 * @return int | ||||
| 	 */ | ||||
| 	public function getStatisticData($statName, $playerId, $serverIndex = -1) { | ||||
| 		//Handle Special Stats | ||||
| 		switch($statName) { | ||||
| 			case self::SPECIAL_STAT_KD_RATIO: | ||||
| 				$kills  = $this->getStatisticData(StatisticCollector::STAT_ON_KILL, $playerId, $serverIndex); | ||||
| 				$deaths = $this->getStatisticData(StatisticCollector::STAT_ON_DEATH, $playerId, $serverIndex); | ||||
| 				if ($deaths == 0) { | ||||
| 					return -1; | ||||
| 				} | ||||
| 				return intval($kills) / intval($deaths); | ||||
| 			case self::SPECIAL_STAT_HITS_PH: | ||||
| 				$hits = $this->getStatisticData(StatisticCollector::STAT_ON_HIT, $playerId, $serverIndex); | ||||
| 				$time = $this->getStatisticData(StatisticCollector::STAT_PLAYTIME, $playerId, $serverIndex); | ||||
| 				if ($time == 0) { | ||||
| 					return -1; | ||||
| 				} | ||||
| 				return intval($hits) / (intval($time) / 3600); | ||||
| 			case self::SPECIAL_STAT_ARROW_ACC: | ||||
| 				$hits  = $this->getStatisticData(StatisticCollector::STAT_ARROW_HIT, $playerId, $serverIndex); | ||||
| 				$shots = $this->getStatisticData(StatisticCollector::STAT_ARROW_SHOT, $playerId, $serverIndex); | ||||
| 				if ($shots == 0) { | ||||
| 					return -1; | ||||
| 				} | ||||
| 				return intval($hits) / intval($shots); | ||||
| 			case self::SPECIAL_STAT_LASER_ACC: | ||||
| 				$hits  = $this->getStatisticData(StatisticCollector::STAT_LASER_HIT, $playerId, $serverIndex); | ||||
| 				$shots = $this->getStatisticData(StatisticCollector::STAT_LASER_SHOT, $playerId, $serverIndex); | ||||
| 				if ($shots == 0) { | ||||
| 					return -1; | ||||
| 				} | ||||
| 				return intval($hits) / intval($shots); | ||||
| 			case self::SPECIAL_STAT_NUCLEUS_ACC: | ||||
| 				$hits  = $this->getStatisticData(StatisticCollector::STAT_NUCLEUS_HIT, $playerId, $serverIndex); | ||||
| 				$shots = $this->getStatisticData(StatisticCollector::STAT_NUCLEUS_SHOT, $playerId, $serverIndex); | ||||
| 				if ($shots == 0) { | ||||
| 					return -1; | ||||
| 				} | ||||
| 				return intval($hits) / intval($shots); | ||||
| 			case self::SPECIAL_STAT_ROCKET_ACC: | ||||
| 				$hits  = $this->getStatisticData(StatisticCollector::STAT_ROCKET_HIT, $playerId, $serverIndex); | ||||
| 				$shots = $this->getStatisticData(StatisticCollector::STAT_ROCKET_SHOT, $playerId, $serverIndex); | ||||
| 				if ($shots == 0) { | ||||
| 					return -1; | ||||
| 				} | ||||
| 				return intval($hits) / intval($shots); | ||||
| 		} | ||||
|  | ||||
| 		$mysqli = $this->maniaControl->database->mysqli; | ||||
| 		$statId = $this->getStatId($statName); | ||||
|  | ||||
| @@ -81,7 +127,7 @@ class StatisticManager { | ||||
| 		$result = $mysqli->query($query); | ||||
| 		if (!$result) { | ||||
| 			trigger_error($mysqli->error); | ||||
| 			return null; | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		$row = $result->fetch_object(); | ||||
| @@ -108,7 +154,7 @@ class StatisticManager { | ||||
| 		$statId = $this->getStatId($statName); | ||||
|  | ||||
| 		if ($minValue == -1) { | ||||
| 			$query = "SELECT playerId, serverIndex, value FROM `" . self::TABLE_STATISTICS . "` WHERE statId = " . $statId . " ORDER BY value DESC LIMIT 100;"; | ||||
| 			$query = "SELECT playerId, serverIndex, value FROM `" . self::TABLE_STATISTICS . "` WHERE statId = " . $statId . " ORDER BY value DESC;"; | ||||
| 		} else { | ||||
| 			$query = "SELECT playerId, serverIndex, value FROM `" . self::TABLE_STATISTICS . "` WHERE statId = " . $statId . " AND value >= " . $minValue . " ORDER BY value DESC;"; | ||||
| 		} | ||||
|   | ||||
| @@ -66,9 +66,10 @@ class ServerRankingPlugin implements Plugin, CallbackListener, CommandListener { | ||||
|  | ||||
| 		$titleId     = $this->maniaControl->server->titleId; | ||||
| 		$titlePrefix = strtolower(substr($titleId, 0, 2)); | ||||
|  | ||||
| 		if ($titlePrefix == 'tm') { //TODO also add obstacle here as default | ||||
| 			$maniaControl->settingManager->initSetting($this, self::SETTING_MIN_RANKING_TYPE, self::RANKING_TYPE_RECORDS); | ||||
| 		} else if ($this->maniaControl->client->getScriptName() == "InstaDM.Script.txt") { | ||||
| 		} else if ($this->maniaControl->client->getScriptName()["CurrentValue"] == "InstaDM.Script.txt") { | ||||
| 			$maniaControl->settingManager->initSetting($this, self::SETTING_MIN_RANKING_TYPE, self::RANKING_TYPE_RATIOS); | ||||
| 		} else { | ||||
| 			$maniaControl->settingManager->initSetting($this, self::SETTING_MIN_RANKING_TYPE, self::RANKING_TYPE_HITS); | ||||
| @@ -88,6 +89,8 @@ class ServerRankingPlugin implements Plugin, CallbackListener, CommandListener { | ||||
| 		//Register CommandListener | ||||
| 		$this->maniaControl->commandManager->registerCommandListener('rank', $this, 'command_showRank', false); | ||||
| 		$this->maniaControl->commandManager->registerCommandListener('nextrank', $this, 'command_nextRank', false); | ||||
|  | ||||
| 		$this->resetRanks(); //TODO only update records count | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -184,11 +187,13 @@ class ServerRankingPlugin implements Plugin, CallbackListener, CommandListener { | ||||
| 					if (!isset($killDeathRatios[$player]) || !isset($accuracies[$player])) { | ||||
| 						continue; | ||||
| 					} | ||||
| 					$ranks[$player] = $killDeathRatios[$player] * $accuracies[$player]; | ||||
| 					$ranks[$player] = $killDeathRatios[$player] * $accuracies[$player] * 1000; | ||||
|  | ||||
| 				} | ||||
|  | ||||
| 				arsort($ranks); | ||||
|  | ||||
|  | ||||
| 				break; | ||||
| 			case self::RANKING_TYPE_HITS: | ||||
| 				$minHits = $this->maniaControl->settingManager->getSetting($this, self::SETTING_MIN_HITS_HITS_RANKING); | ||||
| @@ -273,8 +278,7 @@ class ServerRankingPlugin implements Plugin, CallbackListener, CommandListener { | ||||
| 	 * @param array $callback | ||||
| 	 */ | ||||
| 	public function handlePlayerConnect(array $callback) { | ||||
| 		$login  = $callback[1][0]; | ||||
| 		$player = $this->maniaControl->playerManager->getPlayer($login); | ||||
| 		$player = $callback[1]; | ||||
| 		if (!$player) { | ||||
| 			return; | ||||
| 		} | ||||
| @@ -314,7 +318,9 @@ class ServerRankingPlugin implements Plugin, CallbackListener, CommandListener { | ||||
| 		if ($rankObj != null) { | ||||
| 			switch($type) { | ||||
| 				case self::RANKING_TYPE_RATIOS: | ||||
| 					$message = '$0f3Your Server rank is $<$ff3' . $rankObj->rank . '$> / $<$fff' . $this->recordCount . '$> Ratio: $fff' . round($rankObj->avg, 2); | ||||
| 					$kd      = $this->maniaControl->statisticManager->getStatisticData(StatisticManager::SPECIAL_STAT_KD_RATIO, $player->index); | ||||
| 					$acc     = $this->maniaControl->statisticManager->getStatisticData(StatisticManager::SPECIAL_STAT_LASER_ACC, $player->index); | ||||
| 					$message = '$0f3Your Server rank is $<$ff3' . $rankObj->rank . '$> / $<$fff' . $this->recordCount . '$> (K/D: $<$fff' . round($kd, 2) . '$> Acc: $<$fff' . round($acc * 100) . '%$>)'; | ||||
| 					break; | ||||
| 				case self::RANKING_TYPE_HITS: | ||||
| 					$message = '$0f3Your Server rank is $<$ff3' . $rankObj->rank . '$> / $<$fff' . $this->recordCount . '$> Hits: $fff' . $rankObj->avg; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user