From 1a97d14a1b8d1503bd7288e63a0bed6880605c24 Mon Sep 17 00:00:00 2001 From: fanyx Date: Sun, 26 Jun 2022 16:01:19 +0200 Subject: [PATCH] Add Freezone(1.4) --- freezone/README.txt | 18 + freezone/freezone.xml | 36 + freezone/plugins/freezone/fz-rest-client.php | 214 ++++++ freezone/plugins/plugin.freezone.php | 744 +++++++++++++++++++ 4 files changed, 1012 insertions(+) create mode 100644 freezone/README.txt create mode 100644 freezone/freezone.xml create mode 100644 freezone/plugins/freezone/fz-rest-client.php create mode 100644 freezone/plugins/plugin.freezone.php diff --git a/freezone/README.txt b/freezone/README.txt new file mode 100644 index 0000000..ba809ff --- /dev/null +++ b/freezone/README.txt @@ -0,0 +1,18 @@ +#################################################################### +### Freezone Port for XAseco ### +#################################################################### +### !!! I am not responsible if your server gets disabled !!! ### +#################################################################### + +##Installation## + +1. UnZIP the Archive into the XAseco folder. +2. Open the file "freezone.xml" and set to your webservices-password. +3. Insert the following line into "plugins.xml": + + plugin.freezone.php + +4. Restart XAseco + +##Copyright## +The full copyright remains to the Author of the Freezone plugin for ManiaLive. diff --git a/freezone/freezone.xml b/freezone/freezone.xml new file mode 100644 index 0000000..3d669ad --- /dev/null +++ b/freezone/freezone.xml @@ -0,0 +1,36 @@ + + + + + + + false + true + + + false + + + + + + true + + + 1 + + {#server}>> {#highlite}{1}$z{#grey} got muted for this round because of freezone limitations. + {#server}>> {#highlite}{1}$z{#grey} got unmuted again. + + + + diff --git a/freezone/plugins/freezone/fz-rest-client.php b/freezone/plugins/freezone/fz-rest-client.php new file mode 100644 index 0000000..ca782ec --- /dev/null +++ b/freezone/plugins/freezone/fz-rest-client.php @@ -0,0 +1,214 @@ +username = $username; + $this->password = $password; + $this->contentType = 'application/json'; + $this->acceptType = 'application/json'; + $this->serializeCallback = 'json_encode'; + $this->unserializeCallback = 'json_decode'; + $this->timeout = 3; + $this->debug = $debug; + } + + function setAuth($username, $password) + { + $this->username = $username; + $this->password = $password; + } + + function setAPIURL($URL) + { + $this->APIURL = $URL; + } + + function setContentType($contentType) + { + $this->contentType = $contentType; + } + + function setAcceptType($acceptType) + { + $this->acceptType = $acceptType; + } + + function setSerializeCallback($callback) + { + $this->serializeCallback = $callback; + } + + function setUnserializeCallback($callback) + { + $this->unserializeCallback = $callback; + } + + function setTimeout($timeout) + { + $this->timeout = $timeout; + } + + function execute($verb, $ressource, array $params = array()) + { + $url = $this->APIURL.$ressource; + if($verb == 'POST' || $verb == 'PUT') + { + $data = array_pop($params); + $data = call_user_func($this->serializeCallback, $data); + } + else + { + $data = null; + } + if($params) + { + $params = array_map('urlencode', $params); + array_unshift($params, $url); + $url = call_user_func_array('sprintf', $params); + } + + $header[] = 'Accept: '.$this->acceptType; + $header[] = 'Content-type: '.$this->contentType; + + $options = array(); + + switch($verb) + { + case 'HEAD': + case 'GET': + // Nothing to do + break; + + case 'POST': + $options[CURLOPT_POST] = true; + $options[CURLOPT_POSTFIELDS] = $data; + break; + + case 'PUT': + $fh = fopen('php://temp', 'rw'); + fwrite($fh, $data); + rewind($fh); + + $options[CURLOPT_PUT] = true; + $options[CURLOPT_INFILE] = $fh; + $options[CURLOPT_INFILESIZE] = strlen($data); + break; + + case 'DELETE': + $options[CURLOPT_POST] = true; + $options[CURLOPT_POSTFIELDS] = ''; + $header[] = 'Method: DELETE'; + break; + + default: + throw new FreezoneException('Unsupported HTTP method: '.$verb); + } + + $options[CURLOPT_URL] = $url; + $options[CURLOPT_HTTPHEADER] = $header; + $options[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC; + $options[CURLOPT_USERPWD] = $this->username.':'.$this->password; + $options[CURLOPT_TIMEOUT] = $this->timeout; + $options[CURLOPT_RETURNTRANSFER] = true; + $options[CURLOPT_USERAGENT] = 'ManiaLib Rest Client'; + + // This normally should not be done + // But the certificates of our api are self-signed for now + $options[CURLOPT_SSL_VERIFYHOST] = 0; + $options[CURLOPT_SSL_VERIFYPEER] = 0; + + try + { + $ch = curl_init(); + curl_setopt_array($ch, $options); + $response = curl_exec($ch); + $info = curl_getinfo($ch); + curl_close($ch); + } + catch(Exception $e) + { + if($ch) + { + curl_close($ch); + } + throw $e; + } + + $this->lastRequestInfo = $info; + + if($response && $this->unserializeCallback) + { + $response = call_user_func($this->unserializeCallback, $response); + } + if($this->debug) { + $this->writedebug("[".date('r')."] ".$info['http_code']." ('".$verb."', '".$ressource."', '".(is_array($data) ? print_r($data,1) : $data)."')"); + } + + if($info['http_code'] == 200) + { + return $response; + } + else + { + if(is_object($response) && property_exists($response, 'message')) + { + $message = $response->message; + } + else + { + $message = 'API error. Check the HTTP error code.'; + } + throw new FreezoneException($message, $info['http_code']); + } + } + + static function writedebug($msg) { + $fp = fopen("freezone.log","a+"); + fwrite($fp, $msg."\r\n"); + fclose($fp); + } +} +class FreezoneException extends Exception { + + public function __construct($message, $code = 0) { + parent::__construct($message, $code); + } + + public function __toString() { + return __CLASS__ . ": [{$this->code}]: {$this->message}\n"; + } +} +?> diff --git a/freezone/plugins/plugin.freezone.php b/freezone/plugins/plugin.freezone.php new file mode 100644 index 0000000..f2230f2 --- /dev/null +++ b/freezone/plugins/plugin.freezone.php @@ -0,0 +1,744 @@ + '; + protected static $maxPlayerGame = 5; + protected static $maxSpectatorGame = 1; + + + function __construct($aseco, $config) { + $this->Aseco = $aseco; + $this->xml = simplexml_load_file($config); + $this->loadSettings(); + $this->translation = file_get_contents('http://files.manialive.com/freezonerules.xml'); + if(!$this->testmode) { + $this->wsInstance = new Client($this->wsUser, $this->wsPassword, $this->debuginfo); + if($this->debugmode) { + $this->wsInstance->setAPIURL('http://ws.localhost/'); + } + try { + $response = $this->wsInstance->execute('GET', '/manialive/version/check/239/index.json'); + } catch(FreezoneException $ex) { + if($ex->getCode() == 401) { + trigger_error('[plugin.freezone.php] API Password wrong or server not registered for freezone! Check the freezone:servers manialink.', E_USER_ERROR); + } + } + $this->MLVersion = $response->version->revision; + } + $this->interval['ban_slang'] = 0; // every 6 hours + $this->interval['stats'] = 0; // every hour + $this->interval['rules'] = 0; // every 13 minutes + $this->interval['free'] = 0; // every 13 minutes + $this->interval['rules'] = 0; // every minute + + $this->players = array(); + $this->spectators = array(); + $this->retired = array(); + $this->banned = array(); + $this->store['forcedspectators'] = array(); + + $this->slangWords = $this->getSlangList(); + $this->gamestate = 0; + } + + function loadSettings() { + global $re_config; + $this->wsUser = strval(($this->xml->webservices->user!="" ? $this->xml->webservices->user : $this->Aseco->server->serverlogin)); + $this->wsPassword = strval($this->xml->webservices->password); + $this->testmode = (strtoupper($this->xml->webservices->testmode) == 'TRUE' ? true : false); + $this->debuginfo = (strtoupper($this->xml->webservices->debuginfo) == 'TRUE' ? true : false); + $this->debugmode = (strtoupper($this->xml->webservices->debugmode) == 'TRUE' ? true : false); + if($this->wsPassword == "") { + trigger_error('[plugin.freezone.php] Please set freezone.webservices.password in freezone.xml!', E_USER_ERROR); + } + $this->button['background_style'] = strval($this->xml->button->background_style); + $this->button['background_substyle'] = strval($this->xml->button->background_substyle); + $this->button['pos_x'] = strval($this->xml->button->pos_x); + $this->button['pos_y'] = strval($this->xml->button->pos_y); + $this->button['score_pos_x'] = strval($this->xml->button->score->pos_x); + $this->button['score_pos_y'] = strval($this->xml->button->score->pos_y); + + $this->searchupdates = (strtoupper($this->xml->searchupdates) == 'TRUE' ? true : false); + + // Messages + $frText = 'Pour profiter d\'un accès illimité à tous les serveurs en ligne, vous devez convertir votre compte à TrackMania United Forever. Clicker ici $hfreezone$h pour plus d\'informations'; + $deText = 'Für einen unbegrenzten Zugang zu allen Onlinepartien musst Du auf einen Trackmania United Forever Account upgraden. Klicke hier $hfreezone$h für mehr Informationen.'; + $enText = 'To enjoy unlimited access to all online games, you must upgrade to a TrackMania United Forever account. Click here $hfreezone$h for more information'; + $this->messages['freeaccount'][] = array('Lang'=>'fr','Text'=>$frText); + $this->messages['freeaccount'][] = array('Lang'=>'de','Text'=>$deText); + $this->messages['freeaccount'][] = array('Lang'=>'en','Text'=>$enText); + + $frText = 'Nous expérimentons de nouvelles règles sur la FreeZone: les joueurs possédant un compte gratuit peuvent jouer sur 5 circuits d\'affilé avant d\'effectuer une partie en spectateur'; + $deText = 'Wir experimentieren mit neuen Regeln für die FreeZone: Spieler mit einem kostenlosen Account können 5 Strecken am Stück spielen bevor sie eine Runde als Zuschauer verbringen.'; + $enText = 'We are experimenting new rules on the FreeZone: players with a free account can play up to 5 tracks in a row before doing 1 match as spectator.'; + $this->messages['rules'][] = array('Lang'=>'fr','Text'=>$frText); + $this->messages['rules'][] = array('Lang'=>'de','Text'=>$deText); + $this->messages['rules'][] = array('Lang'=>'en','Text'=>$enText); + + $this->messages['notify'] = array('mute' => strval($this->xml->notify->messages->mute), 'unmute' => strval($this->xml->notify->messages->unmute)); + $this->notify = intval($this->xml->notify->enable); + } + + function showFreezoneButton($player = false) { + $xml = ' + + + '.$this->translation.' + + + + + + + + + + +'; + + if(!$player) { + $players = array(); + foreach ($this->Aseco->server->players->player_list as $player) { + if($player->rights) { + continue; + } + $players[] = $player->login; + } + if(!empty($players)) { + $this->Aseco->client->query('SendDisplayManialinkPageToLogin', implode(',', $players), $xml, 0, false); + } + } else { + if(!$this->Aseco->server->players->player_list[$player]->rights) { + $this->Aseco->client->query('SendDisplayManialinkPageToLogin', $player, $xml, 0, false); + } + } + } + + function showSpectator($player) { + if (!isset($this->Aseco->server->players->player_list[$player])) { + return; + } + + $xml = ' + + + + + + + + + '.$this->getCustomUi(true).' + + + + + + + + + '.$this->translation.' + + + + + + + + + '.$this->translation.' + + +'; + + $this->Aseco->client->query('SendDisplayManialinkPageToLogin', $player, $xml, 0, false); + $message = formatText($this->messages['notify']['mute'], $this->Aseco->server->players->player_list[$player]->nickname); + if($this->notify==2 && function_exists('send_window_message')) { + send_window_message($this->Aseco, $message, false); + } else if($this->notify==1){ + $this->Aseco->client->query('ChatSendServerMessage', $this->Aseco->formatColors($message)); + } + } + + function showPlayer($player) { + if (!isset($this->Aseco->server->players->player_list[$player])) { + return; + } + + $xml = ' + + + + '.$this->getCustomUi(false).' + + + + + + +'; + + $this->Aseco->client->query('SendDisplayManialinkPageToLogin', $player, $xml, 0, false); + + $message = formatText($this->messages['notify']['unmute'], $this->Aseco->server->players->player_list[$player]->nickname); + if($this->notify==2 && function_exists('send_window_message')) { + send_window_message($this->Aseco, $message, false); + } else if($this->notify==1){ + $this->Aseco->client->query('ChatSendServerMessage', $this->Aseco->formatColors($message)); + } + } + + protected function getFreePlayers() { + $players = array(); + foreach ($this->Aseco->server->players->player_list as $player) { + if(!$player->rights) { + $players[] = $player->login; + } + } + return $players; + } + + protected function getSlangList() { + if(!$this->testmode) { + try { + return $this->wsInstance->execute('GET', '/freezone/slang/'); + } catch(FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + } + } + return array(); + } + + protected function checkLanguage($playerUid, $login, $text, $isRegistredCmd) { + $pattern = '/.*(?:^|\\s)('.implode('|', $this->slangWords).')(?:$|\\s).*/i'; + $matches = array(); + + if(preg_match($pattern, $text, $matches)) { + $slangWord = $matches[1]; + if(array_key_exists($login, $this->slangUsers)) { + $slangs = $this->slangUsers[$login]->matches; + $totalMatch = 0; + $find = false; + $this->slangUsers[$login]->lastMatchTime = time(); + + foreach ($slangs as $key => $matchCount) { + if($matchCount[0] == $slangWord) { + $this->slangUsers[$login]->matches[$key][1]++; + $find = true; + } + $totalMatch += $matchCount[1]; + } + + if(!$find) { + $this->slangUsers[$login]->matches[] = array($slangWord, 1); + $totalMatch += 1; + } + + $slangDuration = $this->slangUsers[$login]->lastMatchTime - $this->slangUsers[$login]->firstMatchTime; + if($totalMatch >= 10 && $slangDuration <= 3600) { + $this->usersWatched[$login] = $this->slangUsers[$login]; + } + } else { + $player = $this->Aseco->server->players->player_list[$login]; + $slangUser = new SlangUser(); + $slangUser->language = $player->language; + $slangUser->matches[] = array($slangWord, 1); + $this->slangUsers[$login] = $slangUser; + } + } + } + + protected function cleanSlangUsersList() { + foreach($this->slangUsers as $key => $slangUser) { + if(time() - $slangUser->firstMatchTime >= 3600) { + unset($this->slangUsers[$key]); + } + } + } + + protected function sendUsersWatched() { + if(count($this->usersWatched)) { + $datas = array(); + foreach ($this->usersWatched as $slangUser) { + $user = array(); + $user['language'] = $slangUser->language; + $user['matches'] = $slangUser->matches; + $datas[] = (object)$user; + } + $this->usersWatched = array(); + + try { + $this->wsInstance->execute('PUT', '/freezone/abuses/reports/%s/',array($this->wsUser, $datas)); + } catch (FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + } + } + } + + function badPasswordMessage() { + foreach ($this->Aseco->server->players->player_list as $player) { + if($this->Aseco->isMasterAdmin($player)) { + $this->sendChat('Bad API Password, please check your configuration file and the manialink $hfreezone:servers$h', $player->login); + } + } + } + + function sendChat($message, $player = false) { + if(!$player) { + $this->Aseco->client->query('ChatSendServerMessage', self::$chatPrefix.$message); + } else { + $this->Aseco->client->query('ChatSendServerMessageToLogin', self::$chatPrefix.$message, $player); + } + } + + function getCustomUi($dis = false) { + // From manialinks.inc.php + global $ml_custom_ui; + return '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + '' . + ''; + } + + /***** Events *****/ + function onPlayerConnect($player) { + $this->Aseco->client->query('GetPlayerInfo', $player->login, 2); + $info = $this->Aseco->client->getResponse(); + + if(in_array($login, $this->banned)) { + $this->Aseco->client->query('Kick', $player->login); + } else { + if(!$this->testmode) { + try { + $result = $this->wsInstance->execute('GET', '/freezone/ban/status/'.$player->login.'/index.json'); + } catch(FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + $result = 0; + } + } else { + $result = 0; + } + + if($result == 2) { + $this->Aseco->client->query('Kick', $player->login); + $this->banned[] = $login; + } else { + if(!$player->rights) { + if(key_exists($player->login, $this->retired)) { + if(key_exists($player->login, $this->players)) { + if($this->Aseco->isSpectator($player)) { + $this->spectators[$player->login] = $this->players[$player->login]; + } else { + $this->Aseco->client->query('ForceSpectator', $player->login, 2); + $this->store['forcedspectators'][$player->login] = 2; + } + } else if(key_exists($player->login, $this->spectators)) { + if(isset($this->retired[$player->login])) { + $this->showSpectator($player->login); + $this->spectators[$player->login] = self::$maxPlayerGame; + $this->Aseco->client->query('ForceSpectator', $player->login, 1); + $this->store['forcedspectators'][$player->login] = 1; + } else { + if(!$this->Aseco->isSpectator($player)) { + if($this->spectators[$login] > self::$maxPlayerGame) { + $this->showSpectator($player->login); + $this->Aseco->client->query('ForceSpectator', $player->login, 1); + $this->store['forcedspectators'][$player->login] = 1; + } else { + $this->players[$login] = $this->spectators[$player->login]; + } + } + } + } + return; + } + if(!$this->testmode) { + try { + $count = $this->wsInstance->execute('GET', '/freezone/rules/'.$player->login.'/index.json'); + } catch(FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + } + + } else { + $count = 0; + } + + if($count >= self::$maxPlayerGame) { + $this->showSpectator($player->login); + $this->spectators[$player->login] = $count; + $this->Aseco->client->query('ForceSpectator', $player->login, 1); + $this->store['forcedspectators'][$player->login] = 1; + return; + } + + if(!$this->Aseco->isSpectator($player)) { + $this->players[$player->login] = $count; + $this->Aseco->client->query('ForceSpectator', $player->login, 2); + $this->store['forcedspectators'][$player->login] = 2; + } else { + $this->spectators[$player->login] = $count; + } + $this->showFreezoneButton($player->login); + } + } + } + } + + function onPlayerChangeSide($login) { + $player = $this->Aseco->server->players->player_list[$login]; + + if (!$this->Aseco->isSpectator($player)) { + $this->Aseco->client->query('GetPlayerInfo', $player->login, 2); + $this->store['forcedspectators'][$player->login] = 2; + $info = $this->Aseco->client->getResponse(); + if (!$player->rights && ($info['Flags'] % 10 == 0)) { + $this->Aseco->client->query('ForceSpectator', $login, 2); + $this->store['forcedspectators'][$player->login] = 2; + } + + if (isset($this->spectators[$login])) { + $this->players[$login] = $this->spectators[$login]; + unset($this->spectators[$login]); + } + + $player->isSpectator = false; + $this->showFreezoneButton($player->login); + } elseif ($this->Aseco->isSpectator($player)) { + if (isset($this->players[$login])) { + $this->spectators[$login] = $this->players[$login]; + unset($this->players[$login]); + } + + $player->isSpectator = true; + $this->showFreezoneButton($player->login); + } + } + + function actionHandler($answer) { + if ($answer[2] == 0) { + return; + } + + if ($answer[2] == 1610612737) { + // Close SpectatorWindow + $xml = ' + + + + '; + $this->Aseco->client->query('SendDisplayManialinkPageToLogin', $answer[1], $xml, 0, false); + } + } + + function onBeginRace($challenge) { + + foreach($this->spectators as $login => $value) { + if(!array_key_exists($login, $this->Aseco->server->players->player_list)) { + Client::writedebug("$login is in plugin-intern spectatorlist but is offline!"); + unset($this->spectators[$login]); + } + $player = $this->Aseco->server->players->player_list[$login]; + $this->Aseco->client->query('GetPlayerInfo', $player->login, 2); + $info = $this->Aseco->client->getResponse(); + if($player && (($info['Flags'] % 10) == 1)) { + if (!$this->Aseco->startup_phase) { + $this->spectators[$login]++; + } + if($value >= self::$maxPlayerGame + self::$maxSpectatorGame) { + $this->Aseco->client->query('ForceSpectator', $login, 2); + $this->store['forcedspectators'][$login] = 2; + $this->showPlayer($player->login); + $this->spectators[$login] = 0; + if($this->debuginfo) { + Client::writedebug("Forcing $login into player!"); + } + } + } + } + + foreach($this->players as $login => $value) { + $this->players[$login]++; + if($value >= self::$maxPlayerGame) { + $player = $this->Aseco->server->players->player_list[$login]; + $this->showSpectator($login); + $this->Aseco->client->query('ForceSpectator', $login, 1); + $this->store['forcedspectators'][$login] = 1; + if($this->debuginfo) { + Client::writedebug("Forcing $login into spectator!"); + } + } + } + $this->gamestate = 0; + $this->showFreezoneButton(); + } + + function onEndChallenge($rankings, $challenge, $wasWarmUp, $matchContinuesOnNextChallenge, $restartChallenge) { + if(!$wasWarmUp) { + foreach ($this->retired as $login => $value) { + if ($value) { + $count = self::$maxPlayerGame; + if(array_key_exists($login, $this->players)) { + $count = $this->players[$login]; + } elseif(array_key_exists($login, $this->spectators)) { + $count = $this->spectators[$login]; + } + $count++; + if(!$this->testmode) { + try { + $this->wsInstance->execute('PUT', '/freezone/rules/'.$login.'/index.json', array($count)); + } catch (FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + } + } + unset($this->players[$login]); + unset($this->spectators[$login]); + } + } + $this->retired = array(); + $this->gamestate = 1; + $this->showFreezoneButton(); + } + $this->printDebug(); + } + + function onRestartChallenge() { + $this->gamestate = 0; + } + + function onPlayerDisconnect($player) { + $count = self::$maxPlayerGame; + if(array_key_exists($player->login, $this->players)) { + $count = $this->players[$player->login]; + } elseif(array_key_exists($player->login, $this->spectators)) { + $count = $this->spectators[$player->login]; + } + + if(!$this->testmode){ + try { + $this->wsInstance->execute('PUT', '/freezone/rules/'.$player->login.'/index.json', array($count)); + } catch (FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + } + } + + if(isset($this->store['forcedspectators'][$player->login])) { + if($this->store['forcedspectators'][$player->login] != 0) { + $this->retired[$player->login] = true; + } + unset($this->store['forcedspectators'][$player->login]); + } + } + + function onPlayerChat($playerUid, $login, $text, $isRegistredCmd) { + $this->checkLanguage($playerUid, $login, $text, $isRegistredCmd); + } + + function onTick() { + $time = time(); + + // every 6 hours - refresh ban- and clean slanglist + if($this->interval['ban_slang']+21600 <= $time) { + $this->slangWords = $this->getSlangList(); + $this->banned = array(); + $this->interval['ban_slang'] = $time; + + } + + // every hour - send statistics to ManiaStudio + if($this->interval['stats']+3600 <= $time) { + if(!$this->testmode) { + $this->Aseco->client->query('GetHideServer'); + $hidestatus = $this->Aseco->client->getResponse(); + $data = array(); + $data['serverLogin'] = $this->wsUser; + $data['serverName'] = $this->Aseco->server->name; + $data['serverVersion'] = $this->Aseco->server->game.','.$this->Aseco->server->version.','.$this->Aseco->server->build; + $data['manialiveVersion'] = $this->MLVersion; + $data['maxPlayers'] = $this->Aseco->server->maxplay; + $data['visibility'] = $hidestatus; + $data['classHash'] = self::$MLHash; + try { + $this->wsInstance->execute('POST', '/freezone/live/', array($data)); + } catch (FreezoneException $ex) { + if($ex->getCode() == 401) { + $this->badPasswordMessage(); + } + } + + $this->sendUsersWatched(); + } + $this->cleanSlangUsersList(); + $this->interval['stats'] = $time; + } + + // every minute - testmode message + if($this->interval['rules']+60 <= $time) { + if($this->testmode) { + foreach ($this->Aseco->server->players->player_list as $player) { + if($this->Aseco->isMasterAdmin($player)) { + $this->sendChat('This server is in test Mode. This mode should be disable to respect the FreeZone Rules', $player->login); + } + } + } + $this->interval['rules'] = $time; + } + + // every 13 minutes - send rule message + if($this->interval['rules']+780 <= $time) { + $players = $this->getFreePlayers(); + if(count($players)) { + $this->Aseco->client->query('ChatSendServerMessageToLanguage', $this->messages['rules'], $players); + } + $this->interval['rules'] = $time; + } + + // every 13 minutes - send free-account message + if($this->interval['free']+780 <= $time) { + $players = $this->getFreePlayers(); + if(count($players)) { + $this->Aseco->client->query('ChatSendServerMessageToLanguage', $this->messages['freeaccount'], $players); + } + $this->interval['free'] = $time; + } + } + + function printDebug() { + echo '$this->players:'."\n"; + print_r($this->players); + echo '$this->spectators:'."\n"; + print_r($this->spectators); + } + +} + +function freezone_sync($aseco) { + global $freezone; + $freezone = new Freezone($aseco, 'freezone.xml'); + // Register this to the global version pool (for up-to-date checks) + $aseco->plugin_versions[] = array( + 'plugin' => 'plugin.freezone.php', + 'author' => 'ManiacTwister', + 'version' => FREEZONE_VERSION + ); +} +function freezone_chat($aseco, $chat) { + global $freezone; + if ($chat[0] == $aseco->server->id) return; + $freezone->onPlayerChat($chat[0], $chat[1], $chat[2], $chat[3]); +} +function freezone_playerConnect($aseco, $player) { + global $freezone; + $freezone->onPlayerConnect($player); + if($aseco->isMasterAdmin($player) && $message=search_update()) { + $aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $player->login); + } +} +function freezone_playerDisconnect($aseco, $player) { + global $freezone; + $freezone->onPlayerDisconnect($player); +} +function freezone_playerInfoChanged($aseco, $changes) { + global $freezone; + $freezone->onPlayerChangeSide($changes['Login']); +} +function freezone_actionHandler($aseco, $answer) { + global $freezone; + $freezone->actionHandler($answer); +} +function freezone_tick($aseco) { + global $freezone; + $freezone->onTick(); +} +function freezone_newChallenge($aseco, $challenge) { + global $freezone; + $freezone->onBeginRace($challenge); +} +function freezone_endRace($aseco, $race) { + global $freezone; + $freezone->onEndChallenge($race[0], $race[1], $race[2], $race[3], $race[4]); +} +function freezone_restartChallenge($aseco) { + global $freezone; + $freezone->onRestartChallenge(); +} +function search_update() { + global $freezone; + $current = trim(http_get_file('http://xaseco.maniactwister.de/freezone/version')); + if (!empty($current) && $freezone->searchupdates && $current != -1 && $current > FREEZONE_VERSION) { + return formatText('{#server}>> {#message}New Freezone plugin version {#highlite}{1}{#message} available from {#highlite}{2}', $current, '$L[http://www.tm-forum.com/viewtopic.php?f=127&t=29748]TM-Forum'); + } + return false; +} + +$freezone = ''; + +class SlangUser { + public $language; + public $firstMatchTime; + public $lastMatchTime; + public $matches = array(); + + function __construct() { + $this->firstMatchTime = time(); + $this->lastMatchTime = time(); + } +} +?>