2017-05-19 23:53:21 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace MCTeam\Dedimania;
|
|
|
|
|
|
|
|
|
2017-05-22 15:52:59 +02:00
|
|
|
use ManiaControl\Callbacks\TimerListener;
|
2017-05-19 23:53:21 +02:00
|
|
|
use ManiaControl\Files\AsyncHttpRequest;
|
|
|
|
use ManiaControl\Logger;
|
|
|
|
use ManiaControl\ManiaControl;
|
|
|
|
use ManiaControl\Players\Player;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ManiaControl Dedimania Webhandler Class for Dedimania Plugin
|
2017-05-19 23:55:45 +02:00
|
|
|
*
|
2017-05-19 23:53:21 +02:00
|
|
|
* @author ManiaControl Team <mail@maniacontrol.com>
|
|
|
|
* @copyright 2014-2017 ManiaControl Team
|
|
|
|
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
|
|
|
*/
|
2017-05-22 15:52:59 +02:00
|
|
|
class DedimaniaWebHandler implements TimerListener {
|
2017-05-19 23:53:21 +02:00
|
|
|
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;
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
private $requests = array();
|
|
|
|
private $requestIndex = 0;
|
2017-05-19 23:53:21 +02:00
|
|
|
private $maniaLinkNeedsUpdate = false;
|
|
|
|
|
|
|
|
public function __construct($maniaControl) {
|
|
|
|
$this->maniaControl = $maniaControl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Opens the Dedimania Session
|
|
|
|
*
|
|
|
|
* @param bool $updateRecords
|
|
|
|
*/
|
2017-05-20 12:37:34 +02:00
|
|
|
public function openDedimaniaSession($updateRecords = false) {
|
2017-06-22 15:07:00 +02:00
|
|
|
//TODO updateRecords
|
2017-05-19 23:53:21 +02:00
|
|
|
$content = $this->encodeRequest(self::DEDIMANIA_OPEN_SESSION, array($this->dedimaniaData->toArray()));
|
|
|
|
|
2017-05-22 15:52:59 +02:00
|
|
|
Logger::logInfo("Try to connect on Dedimania");
|
2017-05-19 23:53:21 +02:00
|
|
|
$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");
|
|
|
|
}
|
2017-06-22 15:07:00 +02:00
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
|
|
|
|
$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) {
|
2017-05-20 11:29:15 +02:00
|
|
|
Logger::logInfo("Dedimania connection successfully established.");
|
2017-05-19 23:53:21 +02:00
|
|
|
|
|
|
|
if ($updateRecords) {
|
|
|
|
$this->fetchDedimaniaRecords();
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
Logger::logError("Error while opening Dedimania Connection");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$asyncHttpRequest->setContent($content);
|
|
|
|
$asyncHttpRequest->setCompression(true);
|
|
|
|
$asyncHttpRequest->setTimeout(500);
|
|
|
|
$asyncHttpRequest->postData();
|
|
|
|
}
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
/**
|
|
|
|
* Fetch Dedimania Records
|
|
|
|
*
|
|
|
|
* @param bool $reset
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function fetchDedimaniaRecords($reset = true) {
|
2017-05-22 16:31:09 +02:00
|
|
|
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
2017-05-19 23:53:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset records
|
|
|
|
if ($reset) {
|
2017-05-22 15:52:59 +02:00
|
|
|
$this->dedimaniaData->unsetRecords();
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$serverInfo = $this->getServerInfo();
|
|
|
|
$playerInfo = $this->getPlayerList();
|
|
|
|
$mapInfo = $this->getMapInfo();
|
|
|
|
$gameMode = $this->getGameModeString();
|
|
|
|
|
|
|
|
if (!$serverInfo || !$playerInfo || !$mapInfo || !$gameMode) {
|
2017-05-22 18:23:44 +02:00
|
|
|
$data = array($this->dedimaniaData->sessionId, $mapInfo, $gameMode, $serverInfo, $playerInfo);
|
2017-06-22 15:07:00 +02:00
|
|
|
if ($serverInfo) { // No Players
|
2017-05-24 10:25:42 +02:00
|
|
|
Logger::logError("Dedimania Records could not be fetched, debuginfo:" . json_encode($data));
|
|
|
|
}
|
2017-07-02 18:23:33 +02:00
|
|
|
|
|
|
|
if (!$gameMode) {
|
|
|
|
$this->maniaControl->getChat()->sendError("Dedimania Error: Gamemode not found, try to restart map!");
|
|
|
|
}
|
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
$data = array($this->dedimaniaData->sessionId, $mapInfo, $gameMode, $serverInfo, $playerInfo);
|
2017-05-19 23:53:21 +02:00
|
|
|
|
2017-05-22 17:53:31 +02:00
|
|
|
Logger::logInfo("Try to fetch Dedimania Records");
|
2017-06-22 15:07:00 +02:00
|
|
|
$this->addRequest(self::DEDIMANIA_GET_RECORDS, $data);
|
2017-05-19 23:53:21 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks If a Dedimania Session exists, if not create a new oen
|
|
|
|
*/
|
|
|
|
public function checkDedimaniaSession() { //TODO complete check and refactor
|
2017-05-22 16:31:09 +02:00
|
|
|
if (!$this->dedimaniaData->sessionIdSet()) {
|
2017-05-19 23:53:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
$this->addRequest(self::DEDIMANIA_CHECK_SESSION, array($this->dedimaniaData->sessionId));
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle EndMap Callback
|
|
|
|
*/
|
|
|
|
public function submitChallengeTimes() {
|
2017-05-22 16:31:09 +02:00
|
|
|
if (!$this->dedimaniaData->sessionIdSet()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
if (!$this->getDedimaniaData()->recordsExisting()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Finish Counts as CP somehow
|
|
|
|
if ($this->maniaControl->getMapManager()->getCurrentMap()->nbCheckpoints < 2) {
|
|
|
|
return;
|
|
|
|
}
|
2017-05-22 17:39:22 +02:00
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2017-05-21 21:28:20 +02:00
|
|
|
if ($record->vReplay == '' || !$record->vReplay) {
|
2017-06-30 18:33:54 +02:00
|
|
|
Logger::logInfo("Dedimania Ignore time for " . $record->login . " no validation replay found");
|
2017-05-19 23:53:21 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-05-21 21:31:21 +02:00
|
|
|
//TODO check number of checkpoints
|
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
array_push($times, array('Login' => $record->login, 'Best' => $record->best, 'Checks' => $record->checkpoints));
|
|
|
|
if (!isset($replays['VReplay'])) {
|
|
|
|
$replays['VReplay'] = $record->vReplay;
|
|
|
|
}
|
2017-06-30 18:33:54 +02:00
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
if (!isset($replays['VReplayChecks'])) {
|
|
|
|
$replays['VReplayChecks'] = '';
|
|
|
|
// TODO: VReplayChecks
|
|
|
|
}
|
2017-06-30 18:33:54 +02:00
|
|
|
if (!isset($replays['Top1GReplay'])) {
|
|
|
|
$replays['Top1GReplay'] = $record->top1GReplay;
|
|
|
|
}
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
xmlrpc_set_type($replays['VReplay'], 'base64');
|
|
|
|
xmlrpc_set_type($replays['Top1GReplay'], 'base64');
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
$data = array($this->dedimaniaData->sessionId, $this->getMapInfo(), $gameMode, $times, $replays);
|
2017-05-19 23:53:21 +02:00
|
|
|
|
2017-05-20 11:29:15 +02:00
|
|
|
Logger::logInfo("Dedimania Submitting Map Times at End-Map Start");
|
2017-06-22 15:07:00 +02:00
|
|
|
$this->addRequest(self::DEDIMANIA_SET_CHALLENGE_TIMES, $data);
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle PlayerConnect callback
|
|
|
|
*
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handlePlayerConnect(Player $player) {
|
2017-05-22 16:31:09 +02:00
|
|
|
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
2017-05-19 23:53:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send Dedimania request
|
2017-06-22 15:07:00 +02:00
|
|
|
$data = array($this->dedimaniaData->sessionId, $player->login, $player->rawNickname, $player->path, $player->isSpectator);
|
|
|
|
$this->addRequest(self::DEDIMANIA_PLAYERCONNECT, $data);
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle Player Disconnect Callback
|
|
|
|
*
|
|
|
|
* @param Player $player
|
|
|
|
*/
|
|
|
|
public function handlePlayerDisconnect(Player $player) { //TODO move into webhandler
|
2017-05-22 16:31:09 +02:00
|
|
|
if (!isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
2017-05-19 23:53:21 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-05-22 16:31:09 +02:00
|
|
|
|
2017-05-19 23:53:21 +02:00
|
|
|
$this->dedimaniaData->removePlayer($player->login);
|
|
|
|
|
|
|
|
// Send Dedimania request
|
2017-06-22 15:07:00 +02:00
|
|
|
$data = array($this->dedimaniaData->sessionId, $player->login, '');
|
|
|
|
$this->addRequest(self::DEDIMANIA_PLAYERDISCONNECT, $data);
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the PlayerList every 3 Minutes
|
|
|
|
*/
|
|
|
|
public function updatePlayerList() {
|
|
|
|
$serverInfo = $this->getServerInfo();
|
|
|
|
$playerList = $this->getPlayerList();
|
|
|
|
$votesInfo = $this->getVotesInfo();
|
2017-05-22 16:31:09 +02:00
|
|
|
if (!$serverInfo || !$votesInfo || !$playerList || !isset($this->dedimaniaData) || !$this->dedimaniaData->sessionIdSet()) {
|
2017-05-19 23:53:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send Dedimania request
|
2017-06-22 15:07:00 +02:00
|
|
|
$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;
|
|
|
|
}
|
|
|
|
|
2017-06-30 18:33:54 +02:00
|
|
|
//var_dump($this->dedimaniaData->sessionId);
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
$this->addRequest(self::DEDIMANIA_WARNINGSANDTTR2, array());
|
|
|
|
|
2017-07-02 18:23:33 +02:00
|
|
|
$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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
|
|
|
|
<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
|
2017-05-19 23:53:21 +02:00
|
|
|
|
|
|
|
$asyncHttpRequest = new AsyncHttpRequest($this->maniaControl, self::DEDIMANIA_URL);
|
2017-06-28 14:27:56 +02:00
|
|
|
$asyncHttpRequest->setCallable(function ($answerData, $error) {
|
2017-05-19 23:53:21 +02:00
|
|
|
if ($error) {
|
2017-06-28 14:27:56 +02:00
|
|
|
Logger::logError("Dedimania Error while Request: " . $error);
|
2017-05-22 15:52:59 +02:00
|
|
|
$this->checkDedimaniaSession();
|
|
|
|
return;
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
2017-06-30 18:33:54 +02:00
|
|
|
//var_dump($error);
|
|
|
|
//var_dump($answerData);
|
|
|
|
|
2017-06-28 14:27:56 +02:00
|
|
|
$data = $this->decode($answerData);
|
2017-07-02 18:23:33 +02:00
|
|
|
if (!$data) {
|
2017-06-28 14:27:56 +02:00
|
|
|
//TODO just Temporary
|
|
|
|
var_dump("Dedimania Debug:");
|
|
|
|
var_dump($answerData);
|
|
|
|
}
|
|
|
|
|
2017-06-30 18:33:54 +02:00
|
|
|
if (!is_array($data) || empty($data) || !isset($data[0]) || !isset($data[0][0])) {
|
2017-05-19 23:53:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
//Get the Errors and Warnings to get the Method Order
|
|
|
|
$errorsAndWarnings = $data[count($data) - 1][0];
|
|
|
|
$methods = $errorsAndWarnings['methods'];
|
2017-05-22 15:52:59 +02:00
|
|
|
|
2017-06-22 15:07:00 +02:00
|
|
|
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']));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-30 18:33:54 +02:00
|
|
|
|
|
|
|
//exit();
|
2017-05-19 23:53:21 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
$asyncHttpRequest->setContent($content);
|
2017-06-28 14:27:56 +02:00
|
|
|
//$asyncHttpRequest->setCompression(true);
|
|
|
|
//FIXME setChallengeTime Compressed gives Dedimania Error 400
|
2017-05-19 23:53:21 +02:00
|
|
|
$asyncHttpRequest->setTimeout(500);
|
|
|
|
$asyncHttpRequest->postData();
|
2017-06-22 15:07:00 +02:00
|
|
|
|
|
|
|
$this->requests = array();
|
2017-05-19 23:53:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
2017-06-30 18:33:54 +02:00
|
|
|
$mapInfo['Author'] = $map->authorLogin;
|
2017-05-19 23:53:21 +02:00
|
|
|
$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;
|
|
|
|
}
|
|
|
|
}
|