Add match recovery functionality

This commit is contained in:
Beu 2021-04-06 21:28:00 +02:00
parent 6ac99c334f
commit 1c1d8d2469

View File

@ -311,6 +311,8 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
private $nbspectators = 0;
private $currentgmbase = "";
private $currentmap = null;
private $matchrecover = false;
private $pointstorecover = array();
// Settings to keep in memory
private $settings_nbroundsbymap = 5;
@ -419,6 +421,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
//Register Admin Commands
$this->maniaControl->getCommandManager()->registerCommandListener('matchstart', $this, 'onCommandMatchStart', true, 'Start a match');
$this->maniaControl->getCommandManager()->registerCommandListener('matchstop', $this, 'onCommandMatchStop', true, 'Stop a match');
$this->maniaControl->getCommandManager()->registerCommandListener('matchrecover', $this, 'onCommandMatchRecover', true, 'Recover a match');
$this->maniaControl->getCommandManager()->registerCommandListener('matchendround', $this, 'onCommandMatchEndRound', true, 'Force end a round during a match');
$this->maniaControl->getCommandManager()->registerCommandListener('matchendwu', $this, 'onCommandMatchEndWU', true, 'Force end a WU during a match');
$this->maniaControl->getCommandManager()->registerCommandListener('matchsetpoints', $this, 'onCommandSetPoints', true, 'Sets points to a player.');
@ -438,6 +441,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
$this->maniaControl->getCallbackManager()->registerCallbackListener(PlayerManager::CB_PLAYERINFOCHANGED, $this, 'handlePlayerInfoChanged');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::TM_SCORES, $this, 'handleEndRoundCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::MP_STARTROUNDSTART, $this, 'handleBeginRoundCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::TM_WARMUPSTARTROUND, $this, 'handleStartWarmUpCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_BEGINMATCH, $this, 'handleBeginMatchCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(Callbacks::TM_ONFINISHLINE, $this, 'handleFinishCallback');
$this->maniaControl->getCallbackManager()->registerCallbackListener(CallbackManager::CB_MP_MAPLISTMODIFIED, $this, 'handleMapListModified');
@ -626,7 +630,6 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
$this->maniaControl->getChat()->sendErrorToAdmins($this->chatprefix . 'Parameters not updated');
}
$this->updateGMvariables();
} else {
$this->maniaControl->getChat()->sendErrorToAdmins($this->chatprefix . 'Settings are loaded by Matchsettings file only.');
}
@ -679,6 +682,24 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
}
}
/**
* Function called to list matches
*/
public function getMatchesList($limit = 10) {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = "SELECT `gamemodebase`,`started`,`ended` FROM `" . self::DB_MATCHESINDEX . "`
ORDER BY `started` DESC LIMIT " . $limit;
$result = $mysqli->query($query);
if ($mysqli->error) {
trigger_error($mysqli->error);
return false;
}
while($row = $result->fetch_array()) {
$array[] = $row;
}
return $array;
}
/**
* Function called to start the match
*/
@ -701,7 +722,6 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
Logger::log("Match start with script " . $scriptName . '!');
if ($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCH_LOAD_MAPLIST_FILE)) {
Logger::log("Loading maplist + matchsettings");
if (empty($this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCH_MAPLIST))) {
$server = $this->maniaControl->getServer()->login;
@ -801,10 +821,12 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
Logger::log("Loading script: $scriptName");
Logger::log("Match finished");
$this->matchStarted = false;
$this->matchrecover = false;
$this->pointstorecover = array();
$this->currentscore = [];
$this->settingsloaded = false;
$this->mapsshuffled = false;
$this->postmatch = true;
$this->currentscore = [];
$this->matchid = "";
// KO Specifics variables
@ -841,6 +863,9 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
$this->maniaControl->getClient()->setScriptName($scriptName);
Logger::log("Loading script: $scriptName");
$this->matchStarted = false;
$this->matchrecover = false;
$this->pointstorecover = array();
$this->currentscore = [];
$this->settingsloaded = false;
$this->mapsshuffled = false;
$this->postmatch = true;
@ -858,6 +883,109 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
$this->maniaControl->getClient()->restartMap();
}
/**
* Function called to recover a match
* @param integer $index
*/
public function MatchRecover(Int $index) {
Logger::log("Match Recover");
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = "SELECT `matchid`,`gamemodebase` FROM `" . self::DB_MATCHESINDEX . "`
ORDER BY `started` DESC LIMIT " . $index . ",1";
$result = $mysqli->query($query);
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$gamemodebase = $array['gamemodebase'];
$matchid = $array['matchid'];
unset($array);
$this->matchrecover = true;
$query = "SELECT `timestamp`,`settings`,`nbmaps`,`nbrounds` FROM `" . self::DB_ROUNDSINDEX . "`
WHERE `matchid` = '" . $matchid . "'
ORDER BY `timestamp` DESC LIMIT 1";
$result = $mysqli->query($query);
$array = mysqli_fetch_array($result);
if (isset($array[0])) {
$nbmaps=$array['nbmaps'];
$nbrounds=$array['nbrounds'];
$settings=$array['settings'];
$timestamp=$array['timestamp'];
unset($array);
if ($gamemodebase == "Teams") {
$query = "SELECT `id` AS login,`points` AS matchpoints FROM `" . self::DB_TEAMSDATA . "`
WHERE `timestamp` = (SELECT `timestamp` FROM `" . self::DB_TEAMSDATA . "`
WHERE `matchid` = '" . $matchid . "' ORDER BY `timestamp` DESC LIMIT 1)" ;
} else {
$query = "SELECT `login`,`matchpoints` FROM `" . self::DB_ROUNDSDATA . "`
WHERE `timestamp` = '" . $timestamp . "'";
}
$result = $mysqli->query($query);
if ($mysqli->error) {
trigger_error($mysqli->error);
return false;
}
while($row = $result->fetch_array()) {
$array[] = $row;
}
if (isset($array[0])) {
$this->matchrecover = true;
foreach ($array as $index => $value) {
if (isset($value['login'])) {
$this->pointstorecover[$value['login']] = $value['matchpoints'];
}
}
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Recovering the match: ' . $matchid );
Logger::log('Recovering the match: ' . $matchid);
$this->MatchStart();
} else {
$this->maniaControl->getChat()->sendErrorToAdmins($this->chatprefix . 'No data found from the last round');
}
} else {
$this->maniaControl->getChat()->sendErrorToAdmins($this->chatprefix . 'No Rounds found for this match');
}
} else {
$this->maniaControl->getChat()->sendErrorToAdmins($this->chatprefix . 'Match not found');
}
}
/**
* Function called to recover points
*/
private function recoverPoints() {
if (!empty($this->pointstorecover)) {
if ($this->currentgmbase == "Teams") {
// Blue Team
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("0", "", $this->pointstorecover[0], $this->pointstorecover[0]);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . '$<$ff0' . $this->pointstorecover[0] . '$> points recovered for the $<$00fBlue$> Team');
// Red Team
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("1", "", $this->pointstorecover[1], $this->pointstorecover[1]);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . '$<$ff0' . $this->pointstorecover[1] . '$> points recovered for the $<$f00Red$> Team');
Logger::log("Point recovered: Blue " . $this->pointstorecover[0] . " - Red " . $this->pointstorecover[1]);
$this->pointstorecover = [];
} else {
foreach ($this->pointstorecover as $index => $value) {
$player = $this->maniaControl->getPlayerManager()->getPlayer($index, true);
if ($player) {
if (!empty($this->currentscore)) {
$key = array_search($index, array_column($this->currentscore, '1'));
if (!($key === false)) {
$points = $value + $this->currentscore[$key][2];
} else {
$points = $value;
}
} else {
$points = $value;
}
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaPlayerPoints($player, "", "", $points);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Your $<$ff0' . $value . '$> points have been recovered', $player);
unset($this->pointstorecover[$index]);
Logger::log("Point recovered: " . $index . " " . $points . "(+" . $value . ")");
}
}
}
}
}
/**
* Set pause
*
@ -1181,6 +1309,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
if ($current) {
$current = false;
} elseif (($this->nbmaps + $i) <= ($this->settings_nbmapsbymatch)) {
Logger::log("i: " . $i);
if ($i > 0) {
if ($i == 1) {
$message = $this->chatprefix . '$<$o$iNext Maps:$>';
@ -1199,6 +1328,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
$this->maniaControl->getChat()->sendInformation($message);
}
}
// Trigger Callback
$currentstatus = [
'nbmaps' => $this->nbmaps,
@ -1227,6 +1357,19 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
// Depending of the load of the server and the match gamemode, the script could be not loaded, this is a workaround to reload thhe script
$this->maniaControl->getClient()->restartMap();
}
}
}
/**
* Handle callback "WarmUp.StartRound"
*/
public function handleStartWarmUpCallback() {
Logger::log("handleStartWarmUpCallback");
// Match Recover
if ($this->matchrecover) {
$this->recoverPoints();
}
}
@ -1264,6 +1407,11 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
Logger::log("Map: " . $this->nbmaps);
}
}
// Match Recover
if ($this->matchrecover) {
$this->recoverPoints();
}
}
}
@ -1454,7 +1602,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
}
/**
* Command /matchstart for admins
* Command //matchstart for admins
*
* @param array $chatCallback
* @param \ManiaControl\Players\Player $player
@ -1469,7 +1617,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
}
/**
* Command /matchstop for admins
* Command //matchstop for admins
*
* @param array $chatCallback
* @param \ManiaControl\Players\Player $player
@ -1487,6 +1635,47 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
}
}
/**
* Command //matchrecover for admins
*
* @param array $chatCallback
* @param \ManiaControl\Players\Player $player
*/
public function onCommandMatchRecover(array $chatCallback, Player $player) {
$authLevel = $this->maniaControl->getSettingManager()->getSettingValue($this, self::SETTING_MATCH_AUTHLEVEL);
if (!$this->maniaControl->getAuthenticationManager()->checkRight($player, AuthenticationManager::getAuthLevel($authLevel))) {
$this->maniaControl->getAuthenticationManager()->sendNotAllowed($player);
return;
}
$text = $chatCallback[1][2];
$text = explode(" ", $text);
if (is_numeric($text[1])) {
$this->MatchRecover($text[1]);
} elseif ($text[1] == "latest") {
$this->MatchRecover(0);
} else {
$lastmatches = $this->getMatchesList(3);
$message = $this->chatprefix . '$<run this command with an index or "latest"$>' . "\n";
foreach ($lastmatches as $index => $value) {
if ($index >= 3) {
break;
}
$message .= '$<' . $index . ' - ' . $value['gamemodebase'] . ' started at ' . date("H:i:s", $value['started']);
if ($value['ended'] == "0") {
$message .= " (Not finished)$>\n";
} else {
$message .= " (Finished at " . date("H:i:s", $value['ended'] ). ")$>\n";
}
}
$this->maniaControl->getChat()->sendSuccess($message, $player);
$this->maniaControl->getChat()->sendError($this->chatprefix . 'For the moment, only point recovery is supported, you have to manage maps and rounds manually');
}
}
/**
* Command //matchendround for admin
*
@ -1541,7 +1730,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
$text = explode(" ", $text);
if (isset($text[1]) && $text[1] != "") {
if (is_numeric($text[1]) && $text[1] > 0) {
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Admin force a break for ' . $text[1] . ' seconds!');
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Admin force a break for $<$ff0' . $text[1] . '$> seconds!');
$this->setNadeoPause(true, $text[1]);
} elseif (is_numeric($text[1]) && $text[1] == 0) {
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Admin force an unlimited break');
@ -1560,7 +1749,7 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
}
/**
* Command /matchendpause for admins
* Command //matchendpause for admins
*
* @param array $chatCallback
* @param \ManiaControl\Players\Player $player
@ -1598,10 +1787,10 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
if (isset($text[1]) && isset($text[2]) && is_numeric($text[2]) && $text[2] >= 0 ) {
if (strcasecmp($text[1], "Blue") == 0 || $text[1] == "0") { //TODO: add support of Custom teams
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("0", "", $text[2], $text[2]);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . '$<$00fBlue$> Team now has ' . $text[2] . ' points!');
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . '$<$00fBlue$> Team now has $<$ff0' . $text[2] . '$> points!');
} elseif (strcasecmp($text[1], "Red") == 0 || $text[1] == "1") {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaTeamPoints("1", "", $text[2] , $text[2]);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . '$<$f00Red$> Team now has ' . $text[2] . ' points!');
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . '$<$f00Red$> Team now has $<$ff0' . $text[2] . '$> points!');
} else {
$mysqli = $this->maniaControl->getDatabase()->getMysqli();
$query = 'SELECT login FROM `' . PlayerManager::TABLE_PLAYERS . '` WHERE nickname LIKE "' . $text[1] . '"';
@ -1610,20 +1799,19 @@ class MatchManagerCore implements ManialinkPageAnswerListener, CallbackListener,
if (isset($array[0])) {
$login = $array[0];
} elseif (strlen($text[1]) == 22) {
$login = $text[1] ;
} elseif (strlen($peopletoadd) == 22) {
$login = $peopletoadd ;
}
if ($mysqli->error) {
trigger_error($mysqli->error, E_USER_ERROR);
}
if (isset($login)) {
$player = $this->maniaControl->getPlayerManager()->getPlayer($login);
$player = $this->maniaControl->getPlayerManager()->getPlayer($login,true);
if ($player) {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaPlayerPoints($player, "", "", $text[2]);
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Player $<$ff0' . $player->nickname . '$> now has ' . $text[2] . ' points!');
$this->maniaControl->getChat()->sendSuccess($this->chatprefix . 'Player $<$ff0' . $player->nickname . '$> now has $<$ff0' . $text[2] . '$> points!');
} else {
$this->maniaControl->getModeScriptEventManager()->setTrackmaniaPlayerPoints($player, "", "", $text[2]);
$this->maniaControl->getChat()->sendError($this->chatprefix . 'Player ' . $text[1] . " isn't connected", $adminplayer);
}
} else {