575 lines
57 KiB
PHP
575 lines
57 KiB
PHP
<?php
|
|
|
|
namespace MCTeam\Dedimania;
|
|
|
|
|
|
use ManiaControl\Callbacks\TimerListener;
|
|
use ManiaControl\Files\AsyncHttpRequest;
|
|
use ManiaControl\Logger;
|
|
use ManiaControl\ManiaControl;
|
|
use ManiaControl\Players\Player;
|
|
|
|
/**
|
|
* ManiaControl Dedimania Webhandler Class for Dedimania Plugin
|
|
*
|
|
* @author ManiaControl Team <mail@maniacontrol.com>
|
|
* @copyright 2014-2017 ManiaControl Team
|
|
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
|
*/
|
|
class DedimaniaWebHandler implements TimerListener {
|
|
const XMLRPC_MULTICALL = 'system.multicall';
|
|
const DEDIMANIA_URL = 'http://dedimania.net:8082/Dedimania';
|
|
const DEDIMANIA_OPEN_SESSION = 'dedimania.OpenSession';
|
|
const DEDIMANIA_CHECK_SESSION = 'dedimania.CheckSession';
|
|
const DEDIMANIA_GET_RECORDS = 'dedimania.GetChallengeRecords';
|
|
const DEDIMANIA_PLAYERCONNECT = 'dedimania.PlayerConnect';
|
|
const DEDIMANIA_PLAYERDISCONNECT = 'dedimania.PlayerDisconnect';
|
|
const DEDIMANIA_UPDATE_SERVER_PLAYERS = 'dedimania.UpdateServerPlayers';
|
|
const DEDIMANIA_SET_CHALLENGE_TIMES = 'dedimania.SetChallengeTimes';
|
|
const DEDIMANIA_WARNINGSANDTTR2 = 'dedimania.WarningsAndTTR2';
|
|
|
|
/** @var ManiaControl $maniaControl */
|
|
private $maniaControl;
|
|
/** @var \MCTeam\Dedimania\DedimaniaData $dedimaniaData */
|
|
private $dedimaniaData;
|
|
|
|
private $requests = array();
|
|
private $requestIndex = 0;
|
|
private $maniaLinkNeedsUpdate = false;
|
|
|
|
public function __construct($maniaControl) {
|
|
$this->maniaControl = $maniaControl;
|
|
}
|
|
|
|
/**
|
|
* Opens the Dedimania Session
|
|
*
|
|
* @param bool $updateRecords
|
|
*/
|
|
public function openDedimaniaSession($updateRecords = false) {
|
|
//TODO updateRecords
|
|
$content = $this->encodeRequest(self::DEDIMANIA_OPEN_SESSION, array($this->dedimaniaData->toArray()));
|
|
|
|
Logger::logInfo("Try to connect on Dedimania");
|
|
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, self::DEDIMANIA_URL);
|
|
$asyncHttpRequest->setCallable(function ($data, $error) use ($updateRecords) {
|
|
if (!$data || $error) {
|
|
Logger::logError("Dedimania Error while opening session: '{$error}' Line 42");
|
|
}
|
|
|
|
|
|
$data = $this->decode($data);
|
|
if (!is_array($data) || empty($data)) {
|
|
return;
|
|
}
|
|
|
|
$methodResponse = $data[0];
|
|
if (xmlrpc_is_fault($methodResponse)) {
|
|
$this->handleXmlRpcFault($methodResponse, self::DEDIMANIA_OPEN_SESSION);
|
|
return;
|
|
}
|
|
|
|
$responseData = $methodResponse[0];
|
|
$this->dedimaniaData->sessionId = $responseData['SessionId'];
|
|
if ($this->dedimaniaData->sessionId) {
|
|
Logger::logInfo("Dedimania connection successfully established.");
|
|
|
|
if ($updateRecords) {
|
|
$this->fetchDedimaniaRecords();
|
|
}
|
|
|
|
} else {
|
|
Logger::logError("Error while opening Dedimania Connection");
|
|
}
|
|
});
|
|
|
|
$asyncHttpRequest->setContent($content);
|
|
$asyncHttpRequest->setCompression(true);
|
|
$asyncHttpRequest->setTimeout(500);
|
|
$asyncHttpRequest->postData();
|
|
}
|
|
|
|
|
|
/**
|
|
* Fetch Dedimania Records
|
|
*
|
|
* @param bool $reset
|
|
* @return bool
|
|
*/
|
|
public function fetchDedimaniaRecords($reset = true) {
|
|
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
|
return false;
|
|
}
|
|
|
|
// Reset records
|
|
if ($reset) {
|
|
$this->dedimaniaData->unsetRecords();
|
|
}
|
|
|
|
$serverInfo = $this->getServerInfo();
|
|
$playerInfo = $this->getPlayerList();
|
|
$mapInfo = $this->getMapInfo();
|
|
$gameMode = $this->getGameModeString();
|
|
|
|
if (!$serverInfo || !$playerInfo || !$mapInfo || !$gameMode) {
|
|
$data = array($this->dedimaniaData->sessionId, $mapInfo, $gameMode, $serverInfo, $playerInfo);
|
|
if ($serverInfo) { // No Players
|
|
Logger::logError("Dedimania Records could not be fetched, debuginfo:" . json_encode($data));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
$data = array($this->dedimaniaData->sessionId, $mapInfo, $gameMode, $serverInfo, $playerInfo);
|
|
|
|
Logger::logInfo("Try to fetch Dedimania Records");
|
|
$this->addRequest(self::DEDIMANIA_GET_RECORDS, $data);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Checks If a Dedimania Session exists, if not create a new oen
|
|
*/
|
|
public function checkDedimaniaSession() { //TODO complete check and refactor
|
|
if (!$this->dedimaniaData->sessionIdSet()) {
|
|
return;
|
|
}
|
|
|
|
$this->addRequest(self::DEDIMANIA_CHECK_SESSION, array($this->dedimaniaData->sessionId));
|
|
}
|
|
|
|
/**
|
|
* Handle EndMap Callback
|
|
*/
|
|
public function submitChallengeTimes() {
|
|
if (!$this->dedimaniaData->sessionIdSet()) {
|
|
return;
|
|
}
|
|
|
|
if (!$this->getDedimaniaData()->recordsExisting()) {
|
|
return;
|
|
}
|
|
|
|
//Finish Counts as CP somehow
|
|
if ($this->maniaControl->getMapManager()->getCurrentMap()->nbCheckpoints < 2) {
|
|
return;
|
|
}
|
|
|
|
// Send dedimania records
|
|
$gameMode = $this->getGameModeString();
|
|
$times = array();
|
|
$replays = array();
|
|
foreach ($this->dedimaniaData->records as $record) {
|
|
if ($record->rank > $this->dedimaniaData->serverMaxRank) {
|
|
break;
|
|
}
|
|
if (!$record->newRecord) {
|
|
continue;
|
|
}
|
|
|
|
if ($record->vReplay == '' || !$record->vReplay) {
|
|
Logger::logInfo("Dedimania Ignore time for " . $record->login . " no validation replay found");
|
|
continue;
|
|
}
|
|
|
|
//TODO check number of checkpoints
|
|
|
|
array_push($times, array('Login' => $record->login, 'Best' => $record->best, 'Checks' => $record->checkpoints));
|
|
if (!isset($replays['VReplay'])) {
|
|
$replays['VReplay'] = $record->vReplay;
|
|
}
|
|
|
|
if (!isset($replays['VReplayChecks'])) {
|
|
$replays['VReplayChecks'] = '';
|
|
// TODO: VReplayChecks
|
|
}
|
|
if (!isset($replays['Top1GReplay'])) {
|
|
$replays['Top1GReplay'] = $record->top1GReplay;
|
|
}
|
|
}
|
|
|
|
xmlrpc_set_type($replays['VReplay'], 'base64');
|
|
xmlrpc_set_type($replays['Top1GReplay'], 'base64');
|
|
|
|
$data = array($this->dedimaniaData->sessionId, $this->getMapInfo(), $gameMode, $times, $replays);
|
|
|
|
Logger::logInfo("Dedimania Submitting Map Times at End-Map Start");
|
|
$this->addRequest(self::DEDIMANIA_SET_CHALLENGE_TIMES, $data);
|
|
}
|
|
|
|
/**
|
|
* Handle PlayerConnect callback
|
|
*
|
|
* @param Player $player
|
|
*/
|
|
public function handlePlayerConnect(Player $player) {
|
|
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
|
return;
|
|
}
|
|
|
|
// Send Dedimania request
|
|
$data = array($this->dedimaniaData->sessionId, $player->login, $player->rawNickname, $player->path, $player->isSpectator);
|
|
$this->addRequest(self::DEDIMANIA_PLAYERCONNECT, $data);
|
|
}
|
|
|
|
/**
|
|
* Handle Player Disconnect Callback
|
|
*
|
|
* @param Player $player
|
|
*/
|
|
public function handlePlayerDisconnect(Player $player) { //TODO move into webhandler
|
|
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
|
return;
|
|
}
|
|
|
|
$this->dedimaniaData->removePlayer($player->login);
|
|
|
|
// Send Dedimania request
|
|
$data = array($this->dedimaniaData->sessionId, $player->login, '');
|
|
$this->addRequest(self::DEDIMANIA_PLAYERDISCONNECT, $data);
|
|
}
|
|
|
|
|
|
/**
|
|
* Update the PlayerList every 3 Minutes
|
|
*/
|
|
public function updatePlayerList() {
|
|
$serverInfo = $this->getServerInfo();
|
|
$playerList = $this->getPlayerList();
|
|
$votesInfo = $this->getVotesInfo();
|
|
if (!$serverInfo || !$votesInfo || !$playerList || !isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
|
return;
|
|
}
|
|
|
|
// Send Dedimania request
|
|
$data = array($this->dedimaniaData->sessionId, $serverInfo, $votesInfo, $playerList);
|
|
$this->addRequest(self::DEDIMANIA_UPDATE_SERVER_PLAYERS, $data);
|
|
|
|
}
|
|
|
|
/** Adds a Request to the Dedimania Queue */
|
|
private function addRequest($method, $params) {
|
|
$this->requests[$this->requestIndex] = array('methodName' => $method, 'params' => $params);
|
|
$this->requestIndex++;
|
|
}
|
|
|
|
/**
|
|
* Process Dedimania Calls
|
|
*/
|
|
public function callDedimania() {
|
|
if (empty($this->requests)) {
|
|
return;
|
|
}
|
|
|
|
//var_dump($this->dedimaniaData->sessionId);
|
|
|
|
$this->addRequest(self::DEDIMANIA_WARNINGSANDTTR2, array());
|
|
|
|
$content = xmlrpc_encode_request(self::XMLRPC_MULTICALL, array($this->requests), array('encoding' => 'UTF-8', 'escaping' => 'cdata, non-ascii, non-print, markup', 'verbosity' => 'no_white_space'));
|
|
|
|
|
|
/* $content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodCall><methodName>system.multicall</methodName>
|
|
<params>
|
|
<param><value><array><data><value><struct><member><name>methodName</name><value>
|
|
<string>dedimania.SetChallengeTimes</string></value></member>
|
|
<member><name>params</name><value><array><data><value><string>".$this->dedimaniaData->sessionId."</string></value>
|
|
<value><struct><member><name>UId</name><value><string>ymBMv4ra0y81UM58_E4qfUpfSOd</string></value></member>
|
|
<member><name>Name</name><value><string>Sparkster's Canyon B12</string></value></member><member>
|
|
<name>Environment</name><value><string>Canyon</string></value></member><member><name>Author</name>
|
|
<value><string>sparkster</string></value></member><member><name>NbCheckpoints</name><value><int>3</int></value></member>
|
|
<member><name>NbLaps</name><value><int>0</int></value></member></struct></value><value><string>TA</string></value><value><array>
|
|
<data><value><struct><member><name>Login</name><value><string>kremsy</string></value></member><member><name>Best</name><value>
|
|
<int>271954</int></value></member><member><name>Checks</name><value><string>9092,17778,271954</string></value></member></struct></value></data></array></value><value><struct><member><name>VReplay</name><value><base64>R0JYBgBCVUNSADAJAwcDAAADAAAAADAJA5IAAAABMAkD2QEAgAIwCQOAAAAACAAAAAMAAAAA AABAGwAAAHltQk12NHJhMHk4MVVNNThfRTRxZlVwZlNPZAwAAAAAAABACQAAAHNwYXJrc3R lclImBAAvAAAA77u/JHokcyRpJDA5Zs+BJDAwMMK7JGFhYW9tYm8gJGZmZkx1ayQwOWbDqS DupaQGAAAAa3JlbXN5AQAAAEAIAAAAVE1DYW55b27VAQAAPGhlYWRlciB0eXBlPSJyZXBsY XkiIGV4ZXZlcj0iMy4zLjAiIGV4ZWJ1aWxkPSIyMDE3LTA1LTE2XzE5XzAwIiB0aXRsZT0i VE1DYW55b24iPjxtYXAgdWlkPSJ5bUJNdjRyYTB5ODFVTTU4X0U0cWZVcGZTT2QiIG5hbWU 9IlNwYXJrc3RlciZhcG9zO3MgQ2FueW9uIEIxMiIgYXV0aG9yPSJzcGFya3N0ZXIiIGF1dG hvcnpvbmU9IldvcmxkfEV1cm9wZXxHZXJtYW55fFJoZWlubGFuZC1QZmFsenxLYWlzZXJzb GF1dGVybiIvPjxkZXNjIGVudmlyPSJDYW55b24iIG1vb2Q9IiIgbWFwdHlwZT0iVHJhY2tt YW5pYVxSYWNlIiBtYXBzdHlsZT0iIiBkaXNwbGF5Y29zdD0iMCIgbW9kPSIiIC8+PHBsYXl lcm1vZGVsIGlkPSJDYW55b25DYXIiLz48dGltZXMgYmVzdD0iMjcxOTU0IiByZXNwYXducz 0iOSIgc3R1bnRzY29yZT0iNTIiIHZhbGlkYWJsZT0iMSIvPjxjaGVja3BvaW50cyBjdXI9I jMiIG9uZWxhcD0iMyIvPjwvaGVhZGVyPgEAAAAAAAAADQAAAHBhcmFnb25jYW55b24wAAAA JHckQURGUCQ5Q0ZhJDdCRnIkN0JGYSQ1QUZnJDJBRm8kMDlGbiRmZmYgQ2FueW9uKwAAAO+ 7v1dvcmxkfEV1cm9wZXxGcmFuY2V8w45sZS1kZS1GcmFuY2V8UGFyaXMAAAAAAgAAAAAAAA BpdQAAqmoAAAAIAjAJA/NZAABHQlgGAEJVQ1IAMAQDAAAAABxwAA0AAAAhawEA0lkAAAYNM AQDZAMH/ykAAAkRMAQDAWQEAOOwAQOMAAUAAAAB3sr6AowCAwUDAbAFA2gBKgwADwSwBQOd 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 yJpWQEx7C54CGQnIyQ1A0JyaWRnZWgmCE5vUGlsbGFyAgYbLwmAMH2sBzBcAHQ/AQENFxou XAp8AgEDDhcZLmQD3AIvbE/dAhd41XgT7FcjyGMokwMRFxwupQExe0MSFxwu7AZ9AgEx2NR 0C+woAkJ1c2hlKA0FASOgdCz9JDJiHw0XL4ybfAIBAw8XFC44AmDGAQEMDxYumAjdAhouoA 7dAhQumAhjLgEGGy/siZ0CBzBcAHgacCYipEAi6Foj9F50OgUxAQ0YDQCAACKKrUAHIshZA ZAFAwJsAACDAAAAITQDyuqqln8LVKW6P6ZjSLEPa24yplLYM3kKwWNPcRv93Hk/AAAAU2tp bnNcQW55XEFkdmVydGlzZW1lbnRcQnJpbGxpYW5jZSAnbicgTWV0YWxzXEVtZXJhbGRfVGl 0bGUuanBnOQAAAGh0dHA6Ly9kbC5kcm9wYm94LmNvbS9zL3lhZXl6dDRjZnI1MWFpby8v8A AjXL54Fj4MABJAUzcWBDIBEiEGkLQgIuF2AGQgbAC0IAAQ9RH4GNU3Kz6517kqaUP2mWmc+ VkyMdjBhenMx0tdW8BFACAXFAQCTWlzY18kaG1sIXgpNiwEDTVlem96N3cwbXM4dDV1cS/s IS0IASAQRAQi1EQvXQgyJFljASIgf9wiImCMIMtcBCLoZYygJjRJClNjcmVlbjJ4MQMZBhH sZiIouvQibFAAEAOsmvq7MnKz3zvH/9+l+QIH6AV7H3/AE+sRHcFQp+/szzMSuVprNcQMCn VkZGllYWRcQnVkZHkXyFtkQwE6AAAANmQIDWFzZnE5MHVneDV3M3Ziby8w9AAgDFEINSJaT B0EJ4gDIkCV6BwirHcAEiE0A066RCY4+uvmQMCFVJtwIuiCk8bJfHXYg8ujm+hSlgYNRjqQ AztYEAVTZXJpZXNfR2gtfR5AOdwDDDNpdHRrMXp2amV4YXp1aidEDC4MASAM9APwhCe0ByY 4xgJBAwkJEvg+EvRgLUwEAA5FcJWwWZpSC7araSAf1DnJjhAttQu1qk0uIoVb58NCYCAZkB AIV2Fybl9EYW5nZXJoIjqQEAxvdGh4NDMwc3Z1bHFjeW0nSAQtCAEgDEUEN39BCQkQ7R8Nf Fxwo2wAoKQguO0DNmwfAwYPEgCAAojkIkSELdwHABBKKvAex853mjshr/bVrH4kfTuvHxc+ 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 YAFmAqaNxQLiYAFmAlahxQLEYAFmAvyqxgKIq9oZHK7NDZRgAW4EJLDsBGABZgKCsc0E5mA BZgKgts4EmsHeCMLBzgTQws4WHsXOBCLGzgQwx84EUsjOBELJxgJ8y8YCYszGAjjOxgLizt 4IXtreCGjazgRC3dJETN3SBeXdx2Um3gMT154ADt/aNBzq3QiyYAF2GMDrxgIu7MYLDu7FA nJgAW4EcPDFAqxgAWYC7PHGAkby1gbk9MYCevXGAmD2xQLEYAF2BiL4xQLCYAFmAjr51Rju YAFmAsD6xgLi+9oZVP3FAvRgAW8EGgUEtaiSYAFnArIIBK+mxggExokJBLeWzgoEr68eCwS tlG5gAWquoAvWBu4SzARgAZZgjhPLDPYUBKK1+hXCCtYW3ggMGNkHtmABexAsGwSmm5ob2Q f0ZAJqAxIc3AhgASMCI6of0gV+I84W0iTKDJAlygzMJcMTsCYEtZ/5YAFiCqwn2gdaM9kQ0 mABagNiNcUC5GABZgLyNsYCYDfCCqo4xgIsOcUC4GABeiJYOsYCLjzVGJxgAX4Iqj3WBiI+ zQT+YAF2Bp4/xgJcQNYGHkLKHuZC1gaGQ84EikTGAoRFxgLURdYGPEfVBqBgAWYLOknGAl5 N1QbCYAF+EdpOxgJIT94IClHFAtJgAW4EhlLGArJTzgQMVM0NmGABbgQ4VcowsFXSBbpV7T Fc1gaaXNIyDF7aB1BgwhOgYM4xAmPeCH5kzgSIZMoDDmbKAyJm1gYgaMoDcGjSDuxpzg0Ua tIFcmveCIZr0gWUbMoDxmzeCNduz0MZbwS+fSJw0gW2fMYLOH3GC4J+xQL6YAFuH6R/xgIS gM4EjoHFAvxgAW4EDIbFAt5gAWYCQofGAkaI1QbSYAF+NVSJxgKQidIXiorKFQyLxgJWjMY CUI3eCA6O1Qb0YAF+CKiPxgJIkNUGymABdg+elNYGDJXOBBqWzQSIYAFuBEqYwiVymMkD4G ABagNSmtI7fpvOOr6cxgLwnMYLNp3FC8JgAX4RMJ7GAjqe1gYMn9IFNJ/aB4yhzgTcoc4ED qLOBCKizQTgYAF6EAij0gWEpM4EJKXGAkylxjiSpdIXUKbaGXimyiekp8IKqKjODUyq0QXY YAFqDPaq3gi6vsoMRr/KDDTCxgLmxMYC4MXaByrHyQyEYAFuHwrJxQKWYAFmAoDLxgIMzN0 I1GABcg7Yzd4Ils7OFqDO0gVvz81VrmABcgWK0MYUPN3dCLRgAWoD9N7GAnbfxhQM4MUCrG ABbgRC4cUCsGABZgKA6cYCKurWBqLq3hFq69oQ1u3OBDDuxhT879IFqPDFFONgAWIKoPHGF Ej+1QbyYAFqA37/xQL2YAFnAswBBafRRAIFvs7AA8YCTATHAlQLBb3X9GABdgYWDccCTA4F us1qDtcGkg4Fp9pkDwWyy5YP3QjIYAFuMe4RxgL4Ed4I1BLWBowUwgqgFMIKgBbeCGga1ga aGtYG0CDSBRYh0gVsJd4IgCXSBbIl8gUlBabsSCbSBXom2AdgAZnotmgDYRz8aANqFVYn1w bMKQW68f4p2gcIKtoHOirGFDwt1g9QLdYPgi3WD6ot3ggAN9YGBDjeCHY50gUmPsoMlD7CC mBA2QfOYAFiEwRC1QauYAFmAlRHxQLCYAFmApJKxgIeS8YLok7GAvJOxhS6T94RyFDSDopS 0gWYU9IFQlTaELpUygPIVcoDQFbGAipYxRS2YAF2DzZbxQKuYAFmAipd1QaEYAFmAsJgxgI cYd4IrmXWBiZm3iN4bs0EqmABdgYccMUCYmABZgLyccYCGnLeCMp2xgJgd8YCLHnFAqRgAX YG4H7GAkR/zgTIh9YPGIjWDxaKxQJwYAF2BnSL1Qa6YAFmAkCNzQSQYAFmAvaQzgRgmsYLJ J/GApChxgLgocow+KLaB46jzjF0pM4xTqfELwLyrAUAAHxQAAoRAAAATWFuaWFQbGFuZXQu My4zLjAmvdB+DwAAhHAFLAAAADxpZD4QATDHCzwvaWQ+PGxhcHM+MTwvnAAIPGN0PjEzPC9 jdD54FWwAASYgCQMSscsQcAEtDQAnKWwAI+xKKXwAEmjN+AEHFTAJA/////8YMK0JjKIDQA gSnMwETUNhbnlvbmgCCQ0AAABwYXJhZ29uY5ACAAMwAAAAJHckQURGUCQ5Q0ZhJDdCRnJwA AADYSQ1QUZnJDJBRm8kMDlGbiRmZmYgoAkAEisAAADvu79Xb3JsZHxFdXJvcGV8RnJhbmNl fMOObGUtZGUtRrgBAlBhcmlzfQ4a3RIUcAEpDABsFnkBG9wDfBV8AW0AHM0CEnABElDQbBk HaW1lQXR0YWNrHdQDKsUAHswCZCmUicQHeQAfzAN8BSKUQmUPIM0CDBKg0nAEzQAh3AJsBc oCACIxTQAjzAJ8B3wEbAp/ACQwCRMY1HwBbQAlKpwADAAAAAAAgL8AAAAAAd7K+hEAAA== </base64></value></member><member><name>VReplayChecks</name><value><string/></value></member><member>
|
|
<name>Top1GReplay</name><value><base64></base64></value></member>
|
|
</struct></value></data></array></value></member></struct></value><value><struct><member><name>methodName</name><value><string>dedimania.WarningsAndTTR2</string></value></member><member><name>params</name><value><array><data/></array></value></member></struct></value></data></array></value></param></params></methodCall>";
|
|
*/ //TODO remove debug code later
|
|
|
|
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, self::DEDIMANIA_URL);
|
|
$asyncHttpRequest->setCallable(function ($answerData, $error) {
|
|
if ($error) {
|
|
Logger::logError("Dedimania Error while Request: " . $error);
|
|
$this->checkDedimaniaSession();
|
|
return;
|
|
}
|
|
|
|
//var_dump($error);
|
|
//var_dump($answerData);
|
|
|
|
$data = $this->decode($answerData);
|
|
if(!$data){
|
|
//TODO just Temporary
|
|
var_dump("Dedimania Debug:");
|
|
var_dump($answerData);
|
|
}
|
|
|
|
if (!is_array($data) || empty($data) || !isset($data[0]) || !isset($data[0][0])) {
|
|
return;
|
|
}
|
|
|
|
//Get the Errors and Warnings to get the Method Order
|
|
$errorsAndWarnings = $data[count($data) - 1][0];
|
|
$methods = $errorsAndWarnings['methods'];
|
|
|
|
foreach ($data as $key => $methodResponse) {
|
|
$methodName = $methods[$key]['methodName'];
|
|
|
|
if (xmlrpc_is_fault($methodResponse)) {
|
|
$this->handleXmlRpcFault($methodResponse, $methodName);
|
|
}
|
|
|
|
$responseParameters = $methodResponse[0];
|
|
|
|
switch ($methodName) {
|
|
case self::DEDIMANIA_UPDATE_SERVER_PLAYERS:
|
|
Logger::logInfo("Dedimania Playerlist Updated");
|
|
break;
|
|
case self::DEDIMANIA_GET_RECORDS:
|
|
if (!isset($responseParameters['Players']) || !isset($responseParameters['Records'])) {
|
|
$this->maniaControl->getErrorHandler()->triggerDebugNotice('Invalid Dedimania response! ' . json_encode($responseParameters));
|
|
return;
|
|
}
|
|
|
|
$this->dedimaniaData->serverMaxRank = $responseParameters['ServerMaxRank'];
|
|
|
|
foreach ($responseParameters['Players'] as $player) {
|
|
$dediPlayer = new DedimaniaPlayer($player);
|
|
$this->dedimaniaData->addPlayer($dediPlayer);
|
|
}
|
|
foreach ($responseParameters['Records'] as $recordKey => $record) {
|
|
$this->dedimaniaData->records[$recordKey] = new RecordData($record);
|
|
}
|
|
|
|
Logger::logInfo(count($this->dedimaniaData->records) . " Dedimania Records Fetched succesfully!");
|
|
|
|
$this->maniaLinkNeedsUpdate = true;
|
|
$this->maniaControl->getCallbackManager()->triggerCallback(DedimaniaPlugin::CB_DEDIMANIA_UPDATED, $this->dedimaniaData->records); //TODO
|
|
|
|
//3 Minutes
|
|
$this->maniaControl->getTimerManager()->registerOneTimeListening($this, function () {
|
|
$this->updatePlayerList();
|
|
}, 1000 * 60 * 3);
|
|
|
|
break;
|
|
case self::DEDIMANIA_CHECK_SESSION:
|
|
//TODO Check and reopen if needed
|
|
break;
|
|
case self::DEDIMANIA_SET_CHALLENGE_TIMES:
|
|
//TODO Proper Checks
|
|
Logger::logInfo("Dedimania Times succesfully submitted");
|
|
break;
|
|
case self::DEDIMANIA_PLAYERCONNECT:
|
|
$dediPlayer = new DedimaniaPlayer($responseParameters);
|
|
$this->dedimaniaData->addPlayer($dediPlayer);
|
|
|
|
// Fetch records if he is the first who joined the server
|
|
if ($this->maniaControl->getPlayerManager()->getPlayerCount(false) === 1) {
|
|
$this->fetchDedimaniaRecords(true);
|
|
}
|
|
|
|
Logger::logInfo("Dedimania Player added " . $dediPlayer->login);
|
|
|
|
$this->maniaLinkNeedsUpdate = true; //TODO handle update for only one player instead of everyone as soon splitted
|
|
break;
|
|
case self::DEDIMANIA_PLAYERDISCONNECT:
|
|
Logger::logInfo("Debug: Dedimania Player removed");
|
|
break;
|
|
case self::DEDIMANIA_WARNINGSANDTTR2:
|
|
foreach ($responseParameters['methods'] as $method) {
|
|
if ($method['errors']) {
|
|
Logger::log('Dedimania Warning or Error: ' . $method['methodName'] . ': ' . json_encode($method['errors']));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//exit();
|
|
});
|
|
|
|
$asyncHttpRequest->setContent($content);
|
|
//$asyncHttpRequest->setCompression(true);
|
|
//FIXME setChallengeTime Compressed gives Dedimania Error 400
|
|
$asyncHttpRequest->setTimeout(500);
|
|
$asyncHttpRequest->postData();
|
|
|
|
$this->requests = array();
|
|
}
|
|
|
|
/**
|
|
* Encode the given xml rpc method and params
|
|
*
|
|
* @param string $method
|
|
* @param array $params
|
|
* @return string
|
|
*/
|
|
private function encodeRequest($method, $params) {
|
|
$paramArray = array(array('methodName' => $method, 'params' => $params), array('methodName' => self::DEDIMANIA_WARNINGSANDTTR2, 'params' => array()));
|
|
return xmlrpc_encode_request(self::XMLRPC_MULTICALL, array($paramArray), array('encoding' => 'UTF-8', 'escaping' => 'markup'));
|
|
}
|
|
|
|
/**
|
|
* Decodes xml rpc response
|
|
*
|
|
* @param string $response
|
|
* @return mixed
|
|
*/
|
|
private function decode($response) {
|
|
return xmlrpc_decode($response, 'utf-8');
|
|
}
|
|
|
|
/**
|
|
* Build Votes Info Array for Callbacks
|
|
*/
|
|
private function getVotesInfo() {
|
|
$map = $this->maniaControl->getMapManager()->getCurrentMap();
|
|
if (!$map) {
|
|
return null;
|
|
}
|
|
$gameMode = $this->getGameModeString();
|
|
if (!$gameMode) {
|
|
return null;
|
|
}
|
|
return array('UId' => $map->uid, 'GameMode' => $gameMode);
|
|
}
|
|
|
|
/**
|
|
* Build server info Structure for callbacks
|
|
*/
|
|
private function getServerInfo() {
|
|
$server = $this->maniaControl->getClient()->getServerOptions();
|
|
if (!$server) {
|
|
return null;
|
|
}
|
|
|
|
if ($this->maniaControl->getPlayerManager()->getPlayerCount(false) <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$playerCount = $this->maniaControl->getPlayerManager()->getPlayerCount();
|
|
$spectatorCount = $this->maniaControl->getPlayerManager()->getSpectatorCount();
|
|
|
|
return array('SrvName' => $server->name, 'Comment' => $server->comment, 'Private' => (strlen($server->password) > 0), 'NumPlayers' => $playerCount, 'MaxPlayers' => $server->currentMaxPlayers,
|
|
'NumSpecs' => $spectatorCount, 'MaxSpecs' => $server->currentMaxSpectators);
|
|
}
|
|
|
|
/**
|
|
* Build simple player list for callbacks
|
|
*/
|
|
private function getPlayerList() {
|
|
$players = $this->maniaControl->getPlayerManager()->getPlayers();
|
|
|
|
if (empty($players)) {
|
|
return null;
|
|
}
|
|
$playerInfo = array();
|
|
foreach ($players as $player) {
|
|
array_push($playerInfo, array('Login' => $player->login, 'IsSpec' => $player->isSpectator));
|
|
}
|
|
return $playerInfo;
|
|
}
|
|
|
|
/**
|
|
* Build Map Info Array for Dedimania Requests
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getMapInfo() {
|
|
$map = $this->maniaControl->getMapManager()->getCurrentMap();
|
|
if (!$map) {
|
|
return null;
|
|
}
|
|
$mapInfo = array();
|
|
$mapInfo['UId'] = $map->uid;
|
|
$mapInfo['Name'] = $map->rawName;
|
|
$mapInfo['Environment'] = $map->environment;
|
|
$mapInfo['Author'] = $map->authorLogin;
|
|
$mapInfo['NbCheckpoints'] = $map->nbCheckpoints;
|
|
$mapInfo['NbLaps'] = $map->nbLaps;
|
|
return $mapInfo;
|
|
}
|
|
|
|
/**
|
|
* Get Dedimania String Representation of the current Game Mode
|
|
*
|
|
* @return String
|
|
*/
|
|
private function getGameModeString() {
|
|
$gameMode = $this->maniaControl->getServer()->getGameMode();
|
|
if ($gameMode === null) {
|
|
Logger::logError("Couldn't retrieve game mode.");
|
|
return null;
|
|
}
|
|
switch ($gameMode) {
|
|
case 0: {
|
|
$scriptNameResponse = $this->maniaControl->getClient()->getScriptName();
|
|
$scriptName = str_replace('.Script.txt', '', $scriptNameResponse['CurrentValue']);
|
|
switch ($scriptName) {
|
|
case 'Rounds':
|
|
case 'Cup':
|
|
case 'Team':
|
|
return 'Rounds';
|
|
case 'TimeAttack':
|
|
case 'Laps':
|
|
case 'TeamAttack':
|
|
case 'TimeAttackPlus':
|
|
return 'TA';
|
|
}
|
|
break;
|
|
}
|
|
case 1:
|
|
case 3:
|
|
case 5: {
|
|
return 'Rounds';
|
|
}
|
|
case 2:
|
|
case 4: {
|
|
return 'TA';
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Handle xml rpc fault
|
|
*
|
|
* @param array $fault
|
|
* @param string $method
|
|
*/
|
|
private function handleXmlRpcFault(array $fault, $method) {
|
|
trigger_error("XmlRpc Fault on '{$method}': '{$fault['faultString']} ({$fault['faultCode']})!");
|
|
}
|
|
|
|
/**
|
|
* @return \MCTeam\Dedimania\DedimaniaData
|
|
*/
|
|
public function getDedimaniaData() {
|
|
return $this->dedimaniaData;
|
|
}
|
|
|
|
/**
|
|
* @param \MCTeam\Dedimania\DedimaniaData $dedimaniaData
|
|
*/
|
|
public function setDedimaniaData($dedimaniaData) {
|
|
$this->dedimaniaData = $dedimaniaData;
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function doesManiaLinkNeedUpdate() {
|
|
return $this->maniaLinkNeedsUpdate;
|
|
}
|
|
|
|
/**
|
|
* Call if ManiaLink got Updated
|
|
*/
|
|
public function maniaLinkUpdated() {
|
|
$this->maniaLinkNeedsUpdate = false;
|
|
}
|
|
|
|
/**
|
|
* Call if You want a ManiaLink Update
|
|
*/
|
|
public function maniaLinkUpdateNeeded() {
|
|
$this->maniaLinkNeedsUpdate = true;
|
|
}
|
|
} |