diff --git a/application/core/Admin/AdminMenu.php b/application/core/Admin/AdminMenu.php index 044c45ce..c036c84d 100644 --- a/application/core/Admin/AdminMenu.php +++ b/application/core/Admin/AdminMenu.php @@ -4,7 +4,6 @@ namespace ManiaControl\Admin; use ManiaControl\ManiaControl; use ManiaControl\Callbacks\CallbackListener; -use ManiaControl\Callbacks\CallbackManager; use FML\ManiaLink; use FML\Controls\Control; use FML\Controls\Frame; @@ -136,7 +135,7 @@ class AdminMenu implements CallbackListener { // Add items $x = 0.5 * $itemSize * $itemMarginFactorX; - foreach ($this->menuItems as $itemOrder => $menuItems) { + foreach ($this->menuItems as $menuItems) { foreach ($menuItems as $menuItem) { $menuItem->setSize($itemSize, $itemSize); $itemsFrame->add($menuItem); diff --git a/application/core/Admin/AuthCommands.php b/application/core/Admin/AuthCommands.php index 5bf4a73d..ea03d9d7 100644 --- a/application/core/Admin/AuthCommands.php +++ b/application/core/Admin/AuthCommands.php @@ -6,6 +6,11 @@ use ManiaControl\ManiaControl; use ManiaControl\Commands\CommandListener; use ManiaControl\Players\Player; +/** + * Class offering commands to grant authorizations to players + * + * @author steeffeen & kremsy + */ class AuthCommands implements CommandListener { /** * Private properties @@ -50,7 +55,7 @@ class AuthCommands implements CommandListener { } $success = $this->maniaControl->authenticationManager->grantAuthLevel($player, AuthenticationManager::AUTH_LEVEL_SUPERADMIN); if (!$success) { - $this->maniaControl->chat->sendError('Error occured.', $player->login); + $this->maniaControl->chat->sendError('Error occurred.', $player->login); return; } $message = '$<' . $player->nickname . '$> added $<' . $target->nickname . '$> as SuperAdmin!'; @@ -81,7 +86,7 @@ class AuthCommands implements CommandListener { } $success = $this->maniaControl->authenticationManager->grantAuthLevel($player, AuthenticationManager::AUTH_LEVEL_ADMIN); if (!$success) { - $this->maniaControl->chat->sendError('Error occured.', $player->login); + $this->maniaControl->chat->sendError('Error occurred.', $player->login); return; } $message = '$<' . $player->nickname . '$> added $<' . $target->nickname . '$> as Admin!'; @@ -112,7 +117,7 @@ class AuthCommands implements CommandListener { } $success = $this->maniaControl->authenticationManager->grantAuthLevel($player, AuthenticationManager::AUTH_LEVEL_OPERATOR); if (!$success) { - $this->maniaControl->chat->sendError('Error occured.', $player->login); + $this->maniaControl->chat->sendError('Error occurred.', $player->login); return; } $message = '$<' . $player->nickname . '$> added $<' . $target->nickname . '$> as Operator!'; @@ -127,7 +132,7 @@ class AuthCommands implements CommandListener { */ private function sendAddSuperAdminUsageInfo(Player $player) { $message = "Usage Example: '//addsuperadmin login'"; - return $this->maniaControl->chat->sendUsageInfo($message); + return $this->maniaControl->chat->sendUsageInfo($message, $player->login); } /** @@ -138,7 +143,7 @@ class AuthCommands implements CommandListener { */ private function sendAddAdminUsageInfo(Player $player) { $message = "Usage Example: '//addadmin login'"; - return $this->maniaControl->chat->sendUsageInfo($message); + return $this->maniaControl->chat->sendUsageInfo($message, $player->login); } /** @@ -149,7 +154,7 @@ class AuthCommands implements CommandListener { */ private function sendAddOperatorUsageInfo(Player $player) { $message = "Usage Example: '//addop login'"; - return $this->maniaControl->chat->sendUsageInfo($message); + return $this->maniaControl->chat->sendUsageInfo($message, $player->login); } } diff --git a/application/core/Admin/AuthenticationManager.php b/application/core/Admin/AuthenticationManager.php index 3dac54a9..d59f5171 100644 --- a/application/core/Admin/AuthenticationManager.php +++ b/application/core/Admin/AuthenticationManager.php @@ -133,9 +133,9 @@ class AuthenticationManager { } /** - * Sends an error message to the login + * Sends an error message to the player * - * @param string $login + * @param Player $player * @return bool */ public function sendNotAllowed(Player $player) { @@ -148,7 +148,7 @@ class AuthenticationManager { /** * Check if the player has enough rights * - * @param \ManiaControl\Players\Player $login + * @param Player $player * @param int $neededAuthLevel * @return bool */ diff --git a/application/core/Callbacks/CallbackManager.php b/application/core/Callbacks/CallbackManager.php index 1f6f8b41..e03e5f0f 100644 --- a/application/core/Callbacks/CallbackManager.php +++ b/application/core/Callbacks/CallbackManager.php @@ -115,7 +115,7 @@ class CallbackManager { * Trigger a specific callback * * @param string $callbackName - * @param array $data + * @param array $callback */ public function triggerCallback($callbackName, array $callback) { if (!array_key_exists($callbackName, $this->callbackListeners)) { @@ -159,7 +159,7 @@ class CallbackManager { } // Handle callbacks - foreach ($callbacks as $index => $callback) { + foreach ($callbacks as $callback) { $callbackName = $callback[0]; switch ($callbackName) { case 'ManiaPlanet.BeginMap': diff --git a/application/core/ColorUtil.php b/application/core/ColorUtil.php index 1ca6f6f0..7ea9b685 100644 --- a/application/core/ColorUtil.php +++ b/application/core/ColorUtil.php @@ -3,7 +3,7 @@ namespace ManiaControl; /** - * Utitlity class offering methods to convert and use ManiaPlanet colors + * Utility class offering methods to convert and use ManiaPlanet colors * * @author steeffeen */ @@ -45,7 +45,7 @@ abstract class ColorUtil { $value = 1.; } $value *= 15.; - $value = round($value); + $value = (int) round($value); if ($value < 10) { return (string) $value; } diff --git a/application/core/Commands/CommandManager.php b/application/core/Commands/CommandManager.php index 63b4fcf2..dcc6e9d7 100644 --- a/application/core/Commands/CommandManager.php +++ b/application/core/Commands/CommandManager.php @@ -3,10 +3,8 @@ namespace ManiaControl\Commands; use ManiaControl\ManiaControl; -use ManiaControl\Admin\AuthenticationManager; use ManiaControl\Callbacks\CallbackListener; use ManiaControl\Callbacks\CallbackManager; -use ManiaControl\Players\Player; /** * Class for handling chat commands diff --git a/application/core/Configurators/Configurator.php b/application/core/Configurators/Configurator.php index 21a15b53..f039a138 100644 --- a/application/core/Configurators/Configurator.php +++ b/application/core/Configurators/Configurator.php @@ -8,7 +8,6 @@ use ManiaControl\Callbacks\CallbackManager; use ManiaControl\Manialinks\ManialinkPageAnswerListener; use ManiaControl\Players\Player; use FML\ManiaLink; -use FML\Controls\Control; use FML\Controls\Frame; use FML\Controls\Label; use FML\Controls\Labels\Label_Text; diff --git a/application/core/Configurators/ScriptSettings.php b/application/core/Configurators/ScriptSettings.php index cf2fb612..3f62f2fa 100644 --- a/application/core/Configurators/ScriptSettings.php +++ b/application/core/Configurators/ScriptSettings.php @@ -8,7 +8,6 @@ use FML\Controls\Label; use FML\Script\Pages; use FML\Script\Tooltips; use FML\Controls\Control; -use FML\Controls\Quad; use FML\Controls\Quads\Quad_Icons64x64_1; use FML\Controls\Labels\Label_Text; use FML\Controls\Entry; @@ -99,6 +98,7 @@ class ScriptSettings implements ConfiguratorMenu { // Setting pages $pageFrames = array(); + $y = 0.; foreach ($scriptParams as $index => $scriptParam) { $settingName = $scriptParam['Name']; if (!isset($scriptSettings[$settingName])) continue; @@ -135,16 +135,16 @@ class ScriptSettings implements ConfiguratorMenu { } $entry->setDefault($settingValue); - $decriptionLabel = new Label(); - $pageFrame->add($decriptionLabel); - $decriptionLabel->setHAlign(Control::LEFT); - $decriptionLabel->setPosition($width * -0.45, $height * -0.44); - $decriptionLabel->setSize($width * 0.7, $settingHeight); - $decriptionLabel->setStyle($labelStyleDescription); - $decriptionLabel->setTranslate(true); - $decriptionLabel->setTextPrefix('Desc: '); - $decriptionLabel->setText($scriptParam['Desc']); - $tooltips->add($nameLabel, $decriptionLabel); + $descriptionLabel = new Label(); + $pageFrame->add($descriptionLabel); + $descriptionLabel->setHAlign(Control::LEFT); + $descriptionLabel->setPosition($width * -0.45, $height * -0.44); + $descriptionLabel->setSize($width * 0.7, $settingHeight); + $descriptionLabel->setStyle($labelStyleDescription); + $descriptionLabel->setTranslate(true); + $descriptionLabel->setTextPrefix('Desc: '); + $descriptionLabel->setText($scriptParam['Desc']); + $tooltips->add($nameLabel, $descriptionLabel); $y -= $settingHeight; if ($index % $pageMaxCount == $pageMaxCount - 1) { diff --git a/application/core/Database.php b/application/core/Database.php index 804afec7..08e0bff5 100644 --- a/application/core/Database.php +++ b/application/core/Database.php @@ -76,15 +76,15 @@ class Database { * @return bool */ private function initDatabase() { - $dbname = $this->config->xpath('database'); - if (!$dbname) { + $dbName = $this->config->xpath('database'); + if (!$dbName) { trigger_error("Invalid database configuration (database).", E_USER_ERROR); return false; } - $dbname = (string) $dbname[0]; + $dbName = (string) $dbName[0]; // Try to connect - $result = $this->mysqli->select_db($dbname); + $result = $this->mysqli->select_db($dbName); if ($result) { return true; } @@ -96,7 +96,7 @@ class Database { trigger_error($this->mysqli->error, E_USER_ERROR); return false; } - $databaseStatement->bind_param('s', $dbname); + $databaseStatement->bind_param('s', $dbName); $databaseStatement->execute(); if ($databaseStatement->error) { trigger_error($databaseStatement->error, E_USER_ERROR); @@ -105,9 +105,9 @@ class Database { $databaseStatement->close(); // Connect to new database - $this->mysqli->select_db($dbname); + $this->mysqli->select_db($dbName); if ($this->mysqli->error) { - trigger_error("Couldn't select database '{$dbname}'. " . $this->mysqli->error, E_USER_ERROR); + trigger_error("Couldn't select database '{$dbName}'. " . $this->mysqli->error, E_USER_ERROR); return false; } return true; diff --git a/application/core/GbxDataFetcher/gbxdatafetcher.inc.php b/application/core/GbxDataFetcher/gbxdatafetcher.inc.php index c43bb74f..43fcfe72 100644 --- a/application/core/GbxDataFetcher/gbxdatafetcher.inc.php +++ b/application/core/GbxDataFetcher/gbxdatafetcher.inc.php @@ -260,7 +260,7 @@ class GBXBaseFetcher // XML parser functions private function startTag($parser, $name, $attribs) { - foreach ($attribs as $key => &$val) + foreach ($attribs as &$val) $val = utf8_decode($val); //echo 'startTag: ' . $name . "\n"; print_r($attribs); array_push($this->_parsestack, $name); diff --git a/application/core/ManiaControl.php b/application/core/ManiaControl.php index 46285078..2a35ceec 100644 --- a/application/core/ManiaControl.php +++ b/application/core/ManiaControl.php @@ -119,7 +119,8 @@ class ManiaControl implements CommandListener { /** * Send ManiaControl version * - * @param array $chat + * @param array $chat + * @param Player $player * @return bool */ public function command_Version(array $chat, Player $player) { @@ -129,10 +130,10 @@ class ManiaControl implements CommandListener { /** * Quit ManiaControl and log the given message - *test + * * @param string $message */ - public function quit($message = false) { + public function quit($message = '') { if ($this->client) { // Announce quit $this->chat->sendInformation('ManiaControl shutting down.'); @@ -248,7 +249,7 @@ class ManiaControl implements CommandListener { } // Connect finished - error_log("Server connection succesfully established!"); + error_log("Server connection successfully established!"); // Enable script callbacks if needed if ($this->server->getGameMode() === 0) { diff --git a/application/core/Maps/Map.php b/application/core/Maps/Map.php index dcf05393..7948436c 100644 --- a/application/core/Maps/Map.php +++ b/application/core/Maps/Map.php @@ -52,7 +52,7 @@ class Map { if (!$rpc_infos) { return; } - $this->name = $rpc_infos['Name']; // in aseco stripped new lines on name + $this->name = $rpc_infos['Name']; $this->uid = $rpc_infos['UId']; $this->fileName = $rpc_infos['FileName']; $this->authorLogin = $rpc_infos['Author']; @@ -69,7 +69,7 @@ class Map { try { $this->mapFetcher->processFile($mapsDirectory . $this->fileName); } - catch (Exception $e) { + catch (\Exception $e) { trigger_error($e->getMessage(), E_USER_WARNING); } $this->authorNick = $this->mapFetcher->authorNick; diff --git a/application/core/Maps/MapCommands.php b/application/core/Maps/MapCommands.php index 11607de1..c3860979 100644 --- a/application/core/Maps/MapCommands.php +++ b/application/core/Maps/MapCommands.php @@ -73,7 +73,7 @@ class MapCommands implements CommandListener { $this->maniaControl->authenticationManager->sendNotAllowed($player); return false; } - // TODO: mx fetcher nutzen? + // TODO: user mx fetcher $params = explode(' ', $chatCallback[1][2], 2); if (count($params) < 2) { $this->maniaControl->chat->sendUsageInfo('Usage example: //addmap 1234', $player->login); @@ -138,7 +138,7 @@ class MapCommands implements CommandListener { } $response = $this->maniaControl->client->getResponse(); if (!$response) { - // Inalid map type + // Invalid map type $this->maniaControl->chat->sendError("Invalid map type.", $player->login); return false; } diff --git a/application/core/PhpRemote/GbxRemote.bem.php b/application/core/PhpRemote/GbxRemote.bem.php index a8c03bd2..0fda65fd 100644 --- a/application/core/PhpRemote/GbxRemote.bem.php +++ b/application/core/PhpRemote/GbxRemote.bem.php @@ -1,891 +1,891 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Errors: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php - - Modified to support protocol 'GbxRemote 2' ('GbxRemote 1') - This version is for BigEndian machines. For LittleEndian (e.g. Intel PC) - machines use the original GbxRemote.inc.php instead. - - Release 2007-09-22 - Slig: - Modified to support >256KB received data (and now >2MB data produce a specific error message) - Modified readCB() to wait the initial timeout only before first read packet - Modified readCB() to return true if there is data to get with getCBResponses() - Modified to support amd64 (for $recvhandle) - Modified IXR_ClientMulticall_Gbx::addCall() to fit Aseco 0.6.1 - Added IXR_Client_Gbx::bytes_sent & bytes_received counters - Fix for a changed feature since php5.1.1 about reference parameter assignment (was used in stream_select) - Workaround for stream_select return value bug with amd64 - - Release 2008-01-20 - Slig / Xymph / Assembler Maniac: - Workaround for fread delay bug in some cases - Added IXR_Client_Gbx::resetError() method (by Xymph) - Some comments and strings code cleanup (by Xymph) - Fix stream_set_timeout($this->socket,...) (thx to CavalierDeVache) - Added a default timeout value to IXR_Client_Gbx::readCB($timeout) - Changed calls with timeout on a stream to use microseconds instead of seconds (by AM) - Removed IXR_Client_Gbx::bytes_sent & bytes_received counters - not used (by AM) - - Release 2008-02-05 - Slig: - Changed some socket read/write timeouts back to seconds to avoid 'transport error' - Changed max data received from 2MB to 4MB - - Release 2008-05-20 - Xymph: - Prevented unpack() warnings in IXR_Client_Gbx::query() when the connection dies - Changed IXR_Client_Gbx::resetError() to assign 'false' for correct isError() - Tweaked some 'transport error' messages - - Release 2009-04-08 - Gou1: - Added method IXR_Client_Gbx::queryIgnoreResult() - Added methods IXR_Client_Gbx::sendRequest() & IXR_Client_Gbx::getResult() - IXR_Client_Gbx::queryIgnoreResult checks if the request is larger than 512KB to avoid errors - If larger than 512KB and method is system.multicall, try to divide the request into - two separate requests with two separate IXR_Client_Gbx::queryIgnoreResult() calls - - Release 2009-06-03 - Xymph: - Suppress possible repetitive CRT warning at stream_select - - Release 2011-04-09 - Xymph / La beuze: - Added optional timeout mechanism to IXR_Client_Gbx::InitWithIp() - - Release 2011-05-22 - Xymph: - Added non-error (true) return status to IXR_Client_Gbx::queryIgnoreResult() - Updated status codes and messages for transport/endian errors - Prevented possible PHP warning in IXR_Client_Gbx::getErrorCode() and getErrorMessage() -*/ - -if (!defined('LF')) { - define('LF', "\n"); -} - -class IXR_Value { - public $data; - public $type; - - function IXR_Value ($data, $type = false) { - $this->data = $data; - if (!$type) { - $type = $this->calculateType(); - } - $this->type = $type; - if ($type == 'struct') { - // Turn all the values in the array into new IXR_Value objects - foreach ($this->data as $key => $value) { - $this->data[$key] = new IXR_Value($value); - } - } - if ($type == 'array') { - for ($i = 0, $j = count($this->data); $i < $j; $i++) { - $this->data[$i] = new IXR_Value($this->data[$i]); - } - } - } - - function calculateType() { - if ($this->data === true || $this->data === false) { - return 'boolean'; - } - if (is_integer($this->data)) { - return 'int'; - } - if (is_double($this->data)) { - return 'double'; - } - // Deal with IXR object types base64 and date - if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { - return 'date'; - } - if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { - return 'base64'; - } - // If it is a normal PHP object convert it into a struct - if (is_object($this->data)) { - $this->data = get_object_vars($this->data); - return 'struct'; - } - if (!is_array($this->data)) { - return 'string'; - } - // We have an array - is it an array or a struct? - if ($this->isStruct($this->data)) { - return 'struct'; - } else { - return 'array'; - } - } - - function getXml() { - // Return XML for this value - switch ($this->type) { - case 'boolean': - return '' . ($this->data ? '1' : '0') . ''; - break; - case 'int': - return '' . $this->data . ''; - break; - case 'double': - return '' . $this->data . ''; - break; - case 'string': - return '' . htmlspecialchars($this->data) . ''; - break; - case 'array': - $return = '' . LF; - foreach ($this->data as $item) { - $return .= ' ' . $item->getXml() . '' . LF; - } - $return .= ''; - return $return; - break; - case 'struct': - $return = '' . LF; - foreach ($this->data as $name => $value) { - $return .= ' ' . $name . ''; - $return .= $value->getXml() . '' . LF; - } - $return .= ''; - return $return; - break; - case 'date': - case 'base64': - return $this->data->getXml(); - break; - } - return false; - } - - function isStruct($array) { - // Nasty function to check if an array is a struct or not - $expected = 0; - foreach ($array as $key => $value) { - if ((string)$key != (string)$expected) { - return true; - } - $expected++; - } - return false; - } -} - - -class IXR_Message { - public $message; - public $messageType; // methodCall / methodResponse / fault - public $faultCode; - public $faultString; - public $methodName; - public $params; - // Current variable stacks - protected $_arraystructs = array(); // Stack to keep track of the current array/struct - protected $_arraystructstypes = array(); // Stack to keep track of whether things are structs or array - protected $_currentStructName = array(); // A stack as well - protected $_param; - protected $_value; - protected $_currentTag; - protected $_currentTagContents; - // The XML parser - protected $_parser; - - function IXR_Message ($message) { - $this->message = $message; - } - - function parse() { - // first remove the XML declaration - $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); - if (trim($this->message) == '') { - return false; - } - $this->_parser = xml_parser_create(); - // Set XML parser to take the case of tags into account - xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); - // Set XML parser callback functions - xml_set_object($this->_parser, $this); - xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); - xml_set_character_data_handler($this->_parser, 'cdata'); - if (!xml_parse($this->_parser, $this->message)) { - /* die(sprintf('GbxRemote XML error: %s at line %d', - xml_error_string(xml_get_error_code($this->_parser)), - xml_get_current_line_number($this->_parser))); */ - return false; - } - xml_parser_free($this->_parser); - // Grab the error messages, if any - if ($this->messageType == 'fault') { - $this->faultCode = $this->params[0]['faultCode']; - $this->faultString = $this->params[0]['faultString']; - } - return true; - } - - function tag_open($parser, $tag, $attr) { - $this->currentTag = $tag; - switch ($tag) { - case 'methodCall': - case 'methodResponse': - case 'fault': - $this->messageType = $tag; - break; - // Deal with stacks of arrays and structs - case 'data': // data is to all intents and purposes more interesting than array - $this->_arraystructstypes[] = 'array'; - $this->_arraystructs[] = array(); - break; - case 'struct': - $this->_arraystructstypes[] = 'struct'; - $this->_arraystructs[] = array(); - break; - } - } - - function cdata($parser, $cdata) { - $this->_currentTagContents .= $cdata; - } - - function tag_close($parser, $tag) { - $valueFlag = false; - switch ($tag) { - case 'int': - case 'i4': - $value = (int)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'double': - $value = (double)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'string': - $value = (string)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'dateTime.iso8601': - $value = new IXR_Date(trim($this->_currentTagContents)); - // $value = $iso->getTimestamp(); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'value': - // If no type is indicated, the type is string - if (trim($this->_currentTagContents) != '') { - $value = (string)$this->_currentTagContents; - $this->_currentTagContents = ''; - $valueFlag = true; - } - break; - case 'boolean': - $value = (boolean)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'base64': - $value = base64_decode($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - // Deal with stacks of arrays and structs - case 'data': - case 'struct': - $value = array_pop($this->_arraystructs); - array_pop($this->_arraystructstypes); - $valueFlag = true; - break; - case 'member': - array_pop($this->_currentStructName); - break; - case 'name': - $this->_currentStructName[] = trim($this->_currentTagContents); - $this->_currentTagContents = ''; - break; - case 'methodName': - $this->methodName = trim($this->_currentTagContents); - $this->_currentTagContents = ''; - break; - } - - if ($valueFlag) { - /* - if (!is_array($value) && !is_object($value)) { - $value = trim($value); - } - */ - if (count($this->_arraystructs) > 0) { - // Add value to struct or array - if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { - // Add to struct - $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; - } else { - // Add to array - $this->_arraystructs[count($this->_arraystructs)-1][] = $value; - } - } else { - // Just add as a paramater - $this->params[] = $value; - } - } - } -} - - -class IXR_Request { - public $method; - public $args; - public $xml; - - function IXR_Request($method, $args) { - $this->method = $method; - $this->args = $args; - $this->xml = '' . $this->method . ''; - foreach ($this->args as $arg) { - $this->xml .= ''; - $v = new IXR_Value($arg); - $this->xml .= $v->getXml(); - $this->xml .= '' . LF; - } - $this->xml .= ''; - } - - function getLength() { - return strlen($this->xml); - } - - function getXml() { - return $this->xml; - } -} - - -class IXR_Error { - public $code; - public $message; - - function IXR_Error($code, $message) { - $this->code = $code; - $this->message = $message; - } - - function getXml() { - $xml = << - - - - - faultCode - {$this->code} - - - faultString - {$this->message} - - - - - -EOD; - return $xml; - } -} - - -class IXR_Date { - public $year; - public $month; - public $day; - public $hour; - public $minute; - public $second; - - function IXR_Date($time) { - // $time can be a PHP timestamp or an ISO one - if (is_numeric($time)) { - $this->parseTimestamp($time); - } else { - $this->parseIso($time); - } - } - - function parseTimestamp($timestamp) { - $this->year = date('Y', $timestamp); - $this->month = date('Y', $timestamp); - $this->day = date('Y', $timestamp); - $this->hour = date('H', $timestamp); - $this->minute = date('i', $timestamp); - $this->second = date('s', $timestamp); - } - - function parseIso($iso) { - $this->year = substr($iso, 0, 4); - $this->month = substr($iso, 4, 2); - $this->day = substr($iso, 6, 2); - $this->hour = substr($iso, 9, 2); - $this->minute = substr($iso, 12, 2); - $this->second = substr($iso, 15, 2); - } - - function getIso() { - return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; - } - - function getXml() { - return ''.$this->getIso().''; - } - - function getTimestamp() { - return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); - } -} - - -class IXR_Base64 { - public $data; - - function IXR_Base64($data) { - $this->data = $data; - } - - function getXml() { - return ''.base64_encode($this->data).''; - } -} - - -////////////////////////////////////////////////////////// -// Nadeo modifications // -// (many thanks to slig for adding callback support) // -////////////////////////////////////////////////////////// -class IXR_Client_Gbx { - public $socket; - public $message = false; - public $cb_message = array(); - public $reqhandle; - public $protocol = 0; - // Storage place for an error message - public $error = false; - - function bigEndianTest() { - list($endiantest) = array_values(unpack('L1L', pack('V', 1))); - if ($endiantest == 1) { - echo "Machine reports itself as LittleEndian, float handling will work correctly with unpack\r\n"; - echo "Use original GbxRemote.inc.php instead of GbxRemote.bem.php\r\n"; - die('App Terminated'); - return false; - } - return true; - } // bigEndianTest - - function IXR_Client_Gbx() { - $this->socket = false; - $this->reqhandle = 0x80000000; - } - - function InitWithIp($ip, $port, $timeout = null) { - - if (!$this->bigEndianTest()) { - $this->error = new IXR_Error(-31999, 'endian error - script doesn\'t match machine type'); - return false; - } - - // open connection, with timeout if specified - if (!isset($timeout)) { - $this->socket = @fsockopen($ip, $port, $errno, $errstr); - } else { - $init_time = microtime(true); - $init_timeout = 5; // retry every 5s - while (true) { - $this->socket = @fsockopen($ip, $port, $errno, $errstr, $init_timeout); - if ($this->socket || (microtime(true) - $init_time >= $timeout)) - break; - } - } - if (!$this->socket) { - $this->error = new IXR_Error(-32300, "transport error - could not open socket (error: $errno, $errstr)"); - return false; - } - // handshake - $array_result = big_endian_unpack('Vsize', fread($this->socket, 4)); - $size = $array_result['size']; - if ($size > 64) { - $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol header'); - return false; - } - $handshake = fread($this->socket, $size); - if ($handshake == 'GBXRemote 1') { - $this->protocol = 1; - } else if ($handshake == 'GBXRemote 2') { - $this->protocol = 2; - } else { - $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol version'); - return false; - } - return true; - } - - function Init($port) { - return $this->InitWithIp('localhost', $port); - } - - function Terminate() { - if ($this->socket) { - fclose($this->socket); - $this->socket = false; - } - } - - protected function sendRequest(IXR_Request $request) { - $xml = $request->getXml(); - - @stream_set_timeout($this->socket, 20); // timeout 20s (to write the request) - // send request - $this->reqhandle++; - if ($this->protocol == 1) { - $bytes = pack('Va*', strlen($xml), $xml); - } else { - $bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml); - } - - $bytes_to_write = strlen($bytes); - while ($bytes_to_write > 0) { - $r = @fwrite($this->socket, $bytes); - if ($r === false || $r == 0) { - // connection interrupted - return false; // or die? - } - - $bytes_to_write -= $r; - if ($bytes_to_write == 0) - break; - - $bytes = substr($bytes, $r); - } - - return true; - } - - protected function getResult() { - $contents = ''; - $contents_length = 0; - do { - $size = 0; - $recvhandle = 0; - @stream_set_timeout($this->socket, 20); // timeout 20s (to read the reply header) - // Get result - if ($this->protocol == 1) { - $contents = fread($this->socket, 4); - if (strlen($contents) == 0) { - $this->error = new IXR_Error(-32300, 'transport error - cannot read size'); - return false; - } - $array_result = big_endian_unpack('Vsize', $contents); - $size = $array_result['size']; - $recvhandle = $this->reqhandle; - } else { - $contents = fread($this->socket, 8); - if (strlen($contents) == 0) { - $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); - return false; - } - $array_result = big_endian_unpack('Vsize/Vhandle', $contents); - $size = $array_result['size']; - $recvhandle = $array_result['handle']; - // -- amd64 support -- - $bits = sprintf('%b', $recvhandle); - if (strlen($bits) == 64) { - $recvhandle = bindec(substr($bits, 32)); - } - } - - if ($recvhandle == 0 || $size == 0) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - if ($size > 4096*1024) { - $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); - return false; - } - - $contents = ''; - $contents_length = 0; - @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (for successive reads until end) - while ($contents_length < $size) { - $contents .= fread($this->socket, $size-$contents_length); - $contents_length = strlen($contents); - } - - if (($recvhandle & 0x80000000) == 0) { - // this is a callback, not our answer! handle= $recvhandle, xml-rpc= $contents - // just add it to the message list for the user to read - $new_cb_message = new IXR_Message($contents); - if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { - array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); - } - } - } while ((int)$recvhandle != (int)$this->reqhandle); - - $this->message = new IXR_Message($contents); - if (!$this->message->parse()) { - // XML error - $this->error = new IXR_Error(-32700, 'parse error. not well formed'); - return false; - } - // Is the message a fault? - if ($this->message->messageType == 'fault') { - $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); - return false; - } - // Message must be OK - return true; - } - - - function query() { - $args = func_get_args(); - $method = array_shift($args); - - if (!$this->socket || $this->protocol == 0) { - $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); - return false; - } - - $request = new IXR_Request($method, $args); - - // Check if request is larger than 512 Kbytes - if (($size = $request->getLength()) > 512*1024-8) { - $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); - return false; - } - - // Send request - $ok = $this->sendRequest($request); - if (!$ok) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - - // Get result - return $this->getResult(); - } - - // Non-blocking query method: doesn't read the response - function queryIgnoreResult() { - $args = func_get_args(); - $method = array_shift($args); - - if (!$this->socket || $this->protocol == 0) { - $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); - return false; - } - - $request = new IXR_Request($method, $args); - - // Check if the request is greater than 512 Kbytes to avoid errors - // If the method is system.multicall, make two calls (possibly recursively) - if (($size = $request->getLength()) > 512*1024-8) { - if ($method = 'system.multicall' && isset($args[0])) { - $count = count($args[0]); - // If count is 1, query cannot be reduced - if ($count < 2) { - $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); - return false; - } - $length = floor($count/2); - $args1 = array_slice($args[0], 0, $length); - $args2 = array_slice($args[0], $length, ($count-$length)); - - $res1 = $this->queryIgnoreResult('system.multicall', $args1); - $res2 = $this->queryIgnoreResult('system.multicall', $args2); - return ($res1 && $res2); - } - // If the method is not a multicall, just stop - else { - $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); - return false; - } - } - - // Send request - $ok = $this->sendRequest($request); - if (!$ok) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - return true; - } - - function readCB($timeout = 2000) { // timeout 2 ms - if (!$this->socket || $this->protocol == 0) { - $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); - return false; - } - if ($this->protocol == 1) - return false; - - $something_received = count($this->cb_message)>0; - $contents = ''; - $contents_length = 0; - - @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (to read available data) - // (assignment in arguments is forbidden since php 5.1.1) - $read = array($this->socket); - $write = NULL; - $except = NULL; - $nb = @stream_select($read, $write, $except, 0, $timeout); - // workaround for stream_select bug with amd64 - if ($nb !== false) - $nb = count($read); - - while ($nb !== false && $nb > 0) { - $timeout = 0; // we don't want to wait for the full time again, just flush the available data - - $size = 0; - $recvhandle = 0; - // Get result - $contents = fread($this->socket, 8); - if (strlen($contents) == 0) { - $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); - return false; - } - $array_result = big_endian_unpack('Vsize/Vhandle', $contents); - $size = $array_result['size']; - $recvhandle = $array_result['handle']; - - if ($recvhandle == 0 || $size == 0) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - if ($size > 4096*1024) { - $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); - return false; - } - - $contents = ''; - $contents_length = 0; - while ($contents_length < $size) { - $contents .= fread($this->socket, $size-$contents_length); - $contents_length = strlen($contents); - } - - if (($recvhandle & 0x80000000) == 0) { - // this is a callback. handle= $recvhandle, xml-rpc= $contents - //echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF; - $new_cb_message = new IXR_Message($contents); - if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { - array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); - } - $something_received = true; - } - - // (assignment in arguments is forbidden since php 5.1.1) - $read = array($this->socket); - $write = NULL; - $except = NULL; - $nb = @stream_select($read, $write, $except, 0, $timeout); - // workaround for stream_select bug with amd64 - if ($nb !== false) - $nb = count($read); - } - return $something_received; - } - - function getResponse() { - // methodResponses can only have one param - return that - return $this->message->params[0]; - } - - function getCBResponses() { - // (look at the end of basic.php for an example) - $messages = $this->cb_message; - $this->cb_message = array(); - return $messages; - } - - function isError() { - return is_object($this->error); - } - - function resetError() { - $this->error = false; - } - - function getErrorCode() { - if ($this->isError()) - return $this->error->code; - else - return 0; - } - - function getErrorMessage() { - if ($this->isError()) - return $this->error->message; - else - return ''; - } -} - - -class IXR_ClientMulticall_Gbx extends IXR_Client_Gbx { - public $calls = array(); - - function addCall($methodName, $args) { - $struct = array('methodName' => $methodName, 'params' => $args); - $this->calls[] = $struct; - - return (count($this->calls) - 1); - } - - function multiquery($ignoreResult = false) { - // Prepare multicall, then call the parent::query() (or queryIgnoreResult) method - if ($ignoreResult) { - $result = parent::queryIgnoreResult('system.multicall', $this->calls); - } else { - $result = parent::query('system.multicall', $this->calls); - } - $this->calls = array(); // reset for next calls - return $result; - } -} - -/** - * The following code is a workaround for php's unpack function which - * does not have the capability of unpacking double precision floats - * that were packed in the opposite byte order of the current machine. - */ -function big_endian_unpack($format, $data) { - $ar = unpack($format, $data); - $vals = array_values($ar); - $f = explode('/', $format); - $i = 0; - foreach ($f as $f_k => $f_v) { - $repeater = intval(substr($f_v, 1)); - if ($repeater == 0) - $repeater = 1; - if ($f_v{1} == '*') { - $repeater = count($ar) - $i; - } - if ($f_v{0} != 'd') { - $i += $repeater; - continue; - } - $j = $i + $repeater; - for ($a = $i; $a < $j; ++$a) { - $p = pack('d', $vals[$i]); - $p = strrev($p); - list($vals[$i]) = array_values(unpack('d1d', $p)); - ++$i; - } - } - $a = 0; - foreach ($ar as $ar_k => $ar_v) { - $ar[$ar_k] = $vals[$a]; - ++$a; - } - return $ar; -} + htmlspecialchars) + Site: http://scripts.incutio.com/xmlrpc/ + Manual: http://scripts.incutio.com/xmlrpc/manual.php + Errors: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php + Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php + + Modified to support protocol 'GbxRemote 2' ('GbxRemote 1') + This version is for BigEndian machines. For LittleEndian (e.g. Intel PC) + machines use the original GbxRemote.inc.php instead. + + Release 2007-09-22 - Slig: + Modified to support >256KB received data (and now >2MB data produce a specific error message) + Modified readCB() to wait the initial timeout only before first read packet + Modified readCB() to return true if there is data to get with getCBResponses() + Modified to support amd64 (for $recvhandle) + Modified IXR_ClientMulticall_Gbx::addCall() to fit Aseco 0.6.1 + Added IXR_Client_Gbx::bytes_sent & bytes_received counters + Fix for a changed feature since php5.1.1 about reference parameter assignment (was used in stream_select) + Workaround for stream_select return value bug with amd64 + + Release 2008-01-20 - Slig / Xymph / Assembler Maniac: + Workaround for fread delay bug in some cases + Added IXR_Client_Gbx::resetError() method (by Xymph) + Some comments and strings code cleanup (by Xymph) + Fix stream_set_timeout($this->socket,...) (thx to CavalierDeVache) + Added a default timeout value to IXR_Client_Gbx::readCB($timeout) + Changed calls with timeout on a stream to use microseconds instead of seconds (by AM) + Removed IXR_Client_Gbx::bytes_sent & bytes_received counters - not used (by AM) + + Release 2008-02-05 - Slig: + Changed some socket read/write timeouts back to seconds to avoid 'transport error' + Changed max data received from 2MB to 4MB + + Release 2008-05-20 - Xymph: + Prevented unpack() warnings in IXR_Client_Gbx::query() when the connection dies + Changed IXR_Client_Gbx::resetError() to assign 'false' for correct isError() + Tweaked some 'transport error' messages + + Release 2009-04-08 - Gou1: + Added method IXR_Client_Gbx::queryIgnoreResult() + Added methods IXR_Client_Gbx::sendRequest() & IXR_Client_Gbx::getResult() + IXR_Client_Gbx::queryIgnoreResult checks if the request is larger than 512KB to avoid errors + If larger than 512KB and method is system.multicall, try to divide the request into + two separate requests with two separate IXR_Client_Gbx::queryIgnoreResult() calls + + Release 2009-06-03 - Xymph: + Suppress possible repetitive CRT warning at stream_select + + Release 2011-04-09 - Xymph / La beuze: + Added optional timeout mechanism to IXR_Client_Gbx::InitWithIp() + + Release 2011-05-22 - Xymph: + Added non-error (true) return status to IXR_Client_Gbx::queryIgnoreResult() + Updated status codes and messages for transport/endian errors + Prevented possible PHP warning in IXR_Client_Gbx::getErrorCode() and getErrorMessage() +*/ + +if (!defined('LF')) { + define('LF', "\n"); +} + +class IXR_Value { + public $data; + public $type; + + function IXR_Value ($data, $type = false) { + $this->data = $data; + if (!$type) { + $type = $this->calculateType(); + } + $this->type = $type; + if ($type == 'struct') { + // Turn all the values in the array into new IXR_Value objects + foreach ($this->data as $key => $value) { + $this->data[$key] = new IXR_Value($value); + } + } + if ($type == 'array') { + for ($i = 0, $j = count($this->data); $i < $j; $i++) { + $this->data[$i] = new IXR_Value($this->data[$i]); + } + } + } + + function calculateType() { + if ($this->data === true || $this->data === false) { + return 'boolean'; + } + if (is_integer($this->data)) { + return 'int'; + } + if (is_double($this->data)) { + return 'double'; + } + // Deal with IXR object types base64 and date + if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { + return 'date'; + } + if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { + return 'base64'; + } + // If it is a normal PHP object convert it into a struct + if (is_object($this->data)) { + $this->data = get_object_vars($this->data); + return 'struct'; + } + if (!is_array($this->data)) { + return 'string'; + } + // We have an array - is it an array or a struct? + if ($this->isStruct($this->data)) { + return 'struct'; + } else { + return 'array'; + } + } + + function getXml() { + // Return XML for this value + switch ($this->type) { + case 'boolean': + return '' . ($this->data ? '1' : '0') . ''; + break; + case 'int': + return '' . $this->data . ''; + break; + case 'double': + return '' . $this->data . ''; + break; + case 'string': + return '' . htmlspecialchars($this->data) . ''; + break; + case 'array': + $return = '' . LF; + foreach ($this->data as $item) { + $return .= ' ' . $item->getXml() . '' . LF; + } + $return .= ''; + return $return; + break; + case 'struct': + $return = '' . LF; + foreach ($this->data as $name => $value) { + $return .= ' ' . $name . ''; + $return .= $value->getXml() . '' . LF; + } + $return .= ''; + return $return; + break; + case 'date': + case 'base64': + return $this->data->getXml(); + break; + } + return false; + } + + function isStruct($array) { + // Nasty function to check if an array is a struct or not + $expected = 0; + foreach ($array as $key => $value) { + if ((string)$key != (string)$expected) { + return true; + } + $expected++; + } + return false; + } +} + + +class IXR_Message { + public $message; + public $messageType; // methodCall / methodResponse / fault + public $faultCode; + public $faultString; + public $methodName; + public $params; + // Current variable stacks + protected $_arraystructs = array(); // Stack to keep track of the current array/struct + protected $_arraystructstypes = array(); // Stack to keep track of whether things are structs or array + protected $_currentStructName = array(); // A stack as well + protected $_param; + protected $_value; + protected $_currentTag; + protected $_currentTagContents; + // The XML parser + protected $_parser; + + function IXR_Message ($message) { + $this->message = $message; + } + + function parse() { + // first remove the XML declaration + $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); + if (trim($this->message) == '') { + return false; + } + $this->_parser = xml_parser_create(); + // Set XML parser to take the case of tags into account + xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); + // Set XML parser callback functions + xml_set_object($this->_parser, $this); + xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->_parser, 'cdata'); + if (!xml_parse($this->_parser, $this->message)) { + /* die(sprintf('GbxRemote XML error: %s at line %d', + xml_error_string(xml_get_error_code($this->_parser)), + xml_get_current_line_number($this->_parser))); */ + return false; + } + xml_parser_free($this->_parser); + // Grab the error messages, if any + if ($this->messageType == 'fault') { + $this->faultCode = $this->params[0]['faultCode']; + $this->faultString = $this->params[0]['faultString']; + } + return true; + } + + function tag_open($parser, $tag, $attr) { + $this->currentTag = $tag; + switch ($tag) { + case 'methodCall': + case 'methodResponse': + case 'fault': + $this->messageType = $tag; + break; + // Deal with stacks of arrays and structs + case 'data': // data is to all intents and purposes more interesting than array + $this->_arraystructstypes[] = 'array'; + $this->_arraystructs[] = array(); + break; + case 'struct': + $this->_arraystructstypes[] = 'struct'; + $this->_arraystructs[] = array(); + break; + } + } + + function cdata($parser, $cdata) { + $this->_currentTagContents .= $cdata; + } + + function tag_close($parser, $tag) { + $valueFlag = false; + switch ($tag) { + case 'int': + case 'i4': + $value = (int)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'double': + $value = (double)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'string': + $value = (string)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'dateTime.iso8601': + $value = new IXR_Date(trim($this->_currentTagContents)); + // $value = $iso->getTimestamp(); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'value': + // If no type is indicated, the type is string + if (trim($this->_currentTagContents) != '') { + $value = (string)$this->_currentTagContents; + $this->_currentTagContents = ''; + $valueFlag = true; + } + break; + case 'boolean': + $value = (boolean)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'base64': + $value = base64_decode($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + // Deal with stacks of arrays and structs + case 'data': + case 'struct': + $value = array_pop($this->_arraystructs); + array_pop($this->_arraystructstypes); + $valueFlag = true; + break; + case 'member': + array_pop($this->_currentStructName); + break; + case 'name': + $this->_currentStructName[] = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + case 'methodName': + $this->methodName = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + } + + if ($valueFlag) { + /* + if (!is_array($value) && !is_object($value)) { + $value = trim($value); + } + */ + if (count($this->_arraystructs) > 0) { + // Add value to struct or array + if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { + // Add to struct + $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; + } else { + // Add to array + $this->_arraystructs[count($this->_arraystructs)-1][] = $value; + } + } else { + // Just add as a paramater + $this->params[] = $value; + } + } + } +} + + +class IXR_Request { + public $method; + public $args; + public $xml; + + function IXR_Request($method, $args) { + $this->method = $method; + $this->args = $args; + $this->xml = '' . $this->method . ''; + foreach ($this->args as $arg) { + $this->xml .= ''; + $v = new IXR_Value($arg); + $this->xml .= $v->getXml(); + $this->xml .= '' . LF; + } + $this->xml .= ''; + } + + function getLength() { + return strlen($this->xml); + } + + function getXml() { + return $this->xml; + } +} + + +class IXR_Error { + public $code; + public $message; + + function IXR_Error($code, $message) { + $this->code = $code; + $this->message = $message; + } + + function getXml() { + $xml = << + + + + + faultCode + {$this->code} + + + faultString + {$this->message} + + + + + +EOD; + return $xml; + } +} + + +class IXR_Date { + public $year; + public $month; + public $day; + public $hour; + public $minute; + public $second; + + function IXR_Date($time) { + // $time can be a PHP timestamp or an ISO one + if (is_numeric($time)) { + $this->parseTimestamp($time); + } else { + $this->parseIso($time); + } + } + + function parseTimestamp($timestamp) { + $this->year = date('Y', $timestamp); + $this->month = date('Y', $timestamp); + $this->day = date('Y', $timestamp); + $this->hour = date('H', $timestamp); + $this->minute = date('i', $timestamp); + $this->second = date('s', $timestamp); + } + + function parseIso($iso) { + $this->year = substr($iso, 0, 4); + $this->month = substr($iso, 4, 2); + $this->day = substr($iso, 6, 2); + $this->hour = substr($iso, 9, 2); + $this->minute = substr($iso, 12, 2); + $this->second = substr($iso, 15, 2); + } + + function getIso() { + return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; + } + + function getXml() { + return ''.$this->getIso().''; + } + + function getTimestamp() { + return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); + } +} + + +class IXR_Base64 { + public $data; + + function IXR_Base64($data) { + $this->data = $data; + } + + function getXml() { + return ''.base64_encode($this->data).''; + } +} + + +////////////////////////////////////////////////////////// +// Nadeo modifications // +// (many thanks to slig for adding callback support) // +////////////////////////////////////////////////////////// +class IXR_Client_Gbx { + public $socket; + public $message = false; + public $cb_message = array(); + public $reqhandle; + public $protocol = 0; + // Storage place for an error message + public $error = false; + + function bigEndianTest() { + list($endiantest) = array_values(unpack('L1L', pack('V', 1))); + if ($endiantest == 1) { + echo "Machine reports itself as LittleEndian, float handling will work correctly with unpack\r\n"; + echo "Use original GbxRemote.inc.php instead of GbxRemote.bem.php\r\n"; + die('App Terminated'); + return false; + } + return true; + } // bigEndianTest + + function IXR_Client_Gbx() { + $this->socket = false; + $this->reqhandle = 0x80000000; + } + + function InitWithIp($ip, $port, $timeout = null) { + + if (!$this->bigEndianTest()) { + $this->error = new IXR_Error(-31999, 'endian error - script doesn\'t match machine type'); + return false; + } + + // open connection, with timeout if specified + if (!isset($timeout)) { + $this->socket = @fsockopen($ip, $port, $errno, $errstr); + } else { + $init_time = microtime(true); + $init_timeout = 5; // retry every 5s + while (true) { + $this->socket = @fsockopen($ip, $port, $errno, $errstr, $init_timeout); + if ($this->socket || (microtime(true) - $init_time >= $timeout)) + break; + } + } + if (!$this->socket) { + $this->error = new IXR_Error(-32300, "transport error - could not open socket (error: $errno, $errstr)"); + return false; + } + // handshake + $array_result = big_endian_unpack('Vsize', fread($this->socket, 4)); + $size = $array_result['size']; + if ($size > 64) { + $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol header'); + return false; + } + $handshake = fread($this->socket, $size); + if ($handshake == 'GBXRemote 1') { + $this->protocol = 1; + } else if ($handshake == 'GBXRemote 2') { + $this->protocol = 2; + } else { + $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol version'); + return false; + } + return true; + } + + function Init($port) { + return $this->InitWithIp('localhost', $port); + } + + function Terminate() { + if ($this->socket) { + fclose($this->socket); + $this->socket = false; + } + } + + protected function sendRequest(IXR_Request $request) { + $xml = $request->getXml(); + + @stream_set_timeout($this->socket, 20); // timeout 20s (to write the request) + // send request + $this->reqhandle++; + if ($this->protocol == 1) { + $bytes = pack('Va*', strlen($xml), $xml); + } else { + $bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml); + } + + $bytes_to_write = strlen($bytes); + while ($bytes_to_write > 0) { + $r = @fwrite($this->socket, $bytes); + if ($r === false || $r == 0) { + // connection interrupted + return false; // or die? + } + + $bytes_to_write -= $r; + if ($bytes_to_write == 0) + break; + + $bytes = substr($bytes, $r); + } + + return true; + } + + protected function getResult() { + $contents = ''; + $contents_length = 0; + do { + $size = 0; + $recvhandle = 0; + @stream_set_timeout($this->socket, 20); // timeout 20s (to read the reply header) + // Get result + if ($this->protocol == 1) { + $contents = fread($this->socket, 4); + if (strlen($contents) == 0) { + $this->error = new IXR_Error(-32300, 'transport error - cannot read size'); + return false; + } + $array_result = big_endian_unpack('Vsize', $contents); + $size = $array_result['size']; + $recvhandle = $this->reqhandle; + } else { + $contents = fread($this->socket, 8); + if (strlen($contents) == 0) { + $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); + return false; + } + $array_result = big_endian_unpack('Vsize/Vhandle', $contents); + $size = $array_result['size']; + $recvhandle = $array_result['handle']; + // -- amd64 support -- + $bits = sprintf('%b', $recvhandle); + if (strlen($bits) == 64) { + $recvhandle = bindec(substr($bits, 32)); + } + } + + if ($recvhandle == 0 || $size == 0) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + if ($size > 4096*1024) { + $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); + return false; + } + + $contents = ''; + $contents_length = 0; + @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (for successive reads until end) + while ($contents_length < $size) { + $contents .= fread($this->socket, $size-$contents_length); + $contents_length = strlen($contents); + } + + if (($recvhandle & 0x80000000) == 0) { + // this is a callback, not our answer! handle= $recvhandle, xml-rpc= $contents + // just add it to the message list for the user to read + $new_cb_message = new IXR_Message($contents); + if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { + array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); + } + } + } while ((int)$recvhandle != (int)$this->reqhandle); + + $this->message = new IXR_Message($contents); + if (!$this->message->parse()) { + // XML error + $this->error = new IXR_Error(-32700, 'parse error. not well formed'); + return false; + } + // Is the message a fault? + if ($this->message->messageType == 'fault') { + $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); + return false; + } + // Message must be OK + return true; + } + + + function query() { + $args = func_get_args(); + $method = array_shift($args); + + if (!$this->socket || $this->protocol == 0) { + $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); + return false; + } + + $request = new IXR_Request($method, $args); + + // Check if request is larger than 512 Kbytes + if (($size = $request->getLength()) > 512*1024-8) { + $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); + return false; + } + + // Send request + $ok = $this->sendRequest($request); + if (!$ok) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + + // Get result + return $this->getResult(); + } + + // Non-blocking query method: doesn't read the response + function queryIgnoreResult() { + $args = func_get_args(); + $method = array_shift($args); + + if (!$this->socket || $this->protocol == 0) { + $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); + return false; + } + + $request = new IXR_Request($method, $args); + + // Check if the request is greater than 512 Kbytes to avoid errors + // If the method is system.multicall, make two calls (possibly recursively) + if (($size = $request->getLength()) > 512*1024-8) { + if ($method = 'system.multicall' && isset($args[0])) { + $count = count($args[0]); + // If count is 1, query cannot be reduced + if ($count < 2) { + $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); + return false; + } + $length = floor($count/2); + $args1 = array_slice($args[0], 0, $length); + $args2 = array_slice($args[0], $length, ($count-$length)); + + $res1 = $this->queryIgnoreResult('system.multicall', $args1); + $res2 = $this->queryIgnoreResult('system.multicall', $args2); + return ($res1 && $res2); + } + // If the method is not a multicall, just stop + else { + $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); + return false; + } + } + + // Send request + $ok = $this->sendRequest($request); + if (!$ok) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + return true; + } + + function readCB($timeout = 2000) { // timeout 2 ms + if (!$this->socket || $this->protocol == 0) { + $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); + return false; + } + if ($this->protocol == 1) + return false; + + $something_received = count($this->cb_message)>0; + $contents = ''; + $contents_length = 0; + + @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (to read available data) + // (assignment in arguments is forbidden since php 5.1.1) + $read = array($this->socket); + $write = NULL; + $except = NULL; + $nb = @stream_select($read, $write, $except, 0, $timeout); + // workaround for stream_select bug with amd64 + if ($nb !== false) + $nb = count($read); + + while ($nb !== false && $nb > 0) { + $timeout = 0; // we don't want to wait for the full time again, just flush the available data + + $size = 0; + $recvhandle = 0; + // Get result + $contents = fread($this->socket, 8); + if (strlen($contents) == 0) { + $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); + return false; + } + $array_result = big_endian_unpack('Vsize/Vhandle', $contents); + $size = $array_result['size']; + $recvhandle = $array_result['handle']; + + if ($recvhandle == 0 || $size == 0) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + if ($size > 4096*1024) { + $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); + return false; + } + + $contents = ''; + $contents_length = 0; + while ($contents_length < $size) { + $contents .= fread($this->socket, $size-$contents_length); + $contents_length = strlen($contents); + } + + if (($recvhandle & 0x80000000) == 0) { + // this is a callback. handle= $recvhandle, xml-rpc= $contents + //echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF; + $new_cb_message = new IXR_Message($contents); + if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { + array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); + } + $something_received = true; + } + + // (assignment in arguments is forbidden since php 5.1.1) + $read = array($this->socket); + $write = NULL; + $except = NULL; + $nb = @stream_select($read, $write, $except, 0, $timeout); + // workaround for stream_select bug with amd64 + if ($nb !== false) + $nb = count($read); + } + return $something_received; + } + + function getResponse() { + // methodResponses can only have one param - return that + return $this->message->params[0]; + } + + function getCBResponses() { + // (look at the end of basic.php for an example) + $messages = $this->cb_message; + $this->cb_message = array(); + return $messages; + } + + function isError() { + return is_object($this->error); + } + + function resetError() { + $this->error = false; + } + + function getErrorCode() { + if ($this->isError()) + return $this->error->code; + else + return 0; + } + + function getErrorMessage() { + if ($this->isError()) + return $this->error->message; + else + return ''; + } +} + + +class IXR_ClientMulticall_Gbx extends IXR_Client_Gbx { + public $calls = array(); + + function addCall($methodName, $args) { + $struct = array('methodName' => $methodName, 'params' => $args); + $this->calls[] = $struct; + + return (count($this->calls) - 1); + } + + function multiquery($ignoreResult = false) { + // Prepare multicall, then call the parent::query() (or queryIgnoreResult) method + if ($ignoreResult) { + $result = parent::queryIgnoreResult('system.multicall', $this->calls); + } else { + $result = parent::query('system.multicall', $this->calls); + } + $this->calls = array(); // reset for next calls + return $result; + } +} + +/** + * The following code is a workaround for php's unpack function which + * does not have the capability of unpacking double precision floats + * that were packed in the opposite byte order of the current machine. + */ +function big_endian_unpack($format, $data) { + $ar = unpack($format, $data); + $vals = array_values($ar); + $f = explode('/', $format); + $i = 0; + foreach ($f as $f_k => $f_v) { + $repeater = intval(substr($f_v, 1)); + if ($repeater == 0) + $repeater = 1; + if ($f_v{1} == '*') { + $repeater = count($ar) - $i; + } + if ($f_v{0} != 'd') { + $i += $repeater; + continue; + } + $j = $i + $repeater; + for ($a = $i; $a < $j; ++$a) { + $p = pack('d', $vals[$i]); + $p = strrev($p); + list($vals[$i]) = array_values(unpack('d1d', $p)); + ++$i; + } + } + $a = 0; + foreach ($ar as $ar_k => $ar_v) { + $ar[$ar_k] = $vals[$a]; + ++$a; + } + return $ar; +} diff --git a/application/core/PhpRemote/GbxRemote.inc.php b/application/core/PhpRemote/GbxRemote.inc.php index 2228311f..b306694a 100644 --- a/application/core/PhpRemote/GbxRemote.inc.php +++ b/application/core/PhpRemote/GbxRemote.inc.php @@ -1,855 +1,855 @@ - htmlspecialchars) - Site: http://scripts.incutio.com/xmlrpc/ - Manual: http://scripts.incutio.com/xmlrpc/manual.php - Errors: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php - Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php - - Modified to support protocol 'GbxRemote 2' ('GbxRemote 1') - This version is for LittleEndian (e.g. Intel PC) machines. For BegEndian - machines use GbxRemote.bem.php as GbxRemote.inc.php instead. - - Release 2007-09-22 - Slig: - Modified to support >256KB received data (and now >2MB data produce a specific error message) - Modified readCB() to wait the initial timeout only before first read packet - Modified readCB() to return true if there is data to get with getCBResponses() - Modified to support amd64 (for $recvhandle) - Modified IXR_ClientMulticall_Gbx::addCall() to fit Aseco 0.6.1 - Added IXR_Client_Gbx::bytes_sent & bytes_received counters - Fix for a changed feature since php5.1.1 about reference parameter assignment (was used in stream_select) - Workaround for stream_select return value bug with amd64 - - Release 2008-01-20 - Slig / Xymph / Assembler Maniac: - Workaround for fread delay bug in some cases - Added IXR_Client_Gbx::resetError() method (by Xymph) - Some comments and strings code cleanup (by Xymph) - Fix stream_set_timeout($this->socket,...) (thx to CavalierDeVache) - Added a default timeout value to IXR_Client_Gbx::readCB($timeout) - Changed calls with timeout on a stream to use microseconds instead of seconds (by AM) - Removed IXR_Client_Gbx::bytes_sent & bytes_received counters - not used (by AM) - - Release 2008-02-05 - Slig: - Changed some socket read/write timeouts back to seconds to avoid 'transport error' - Changed max data received from 2MB to 4MB - - Release 2008-05-20 - Xymph: - Prevented unpack() warnings in IXR_Client_Gbx::query() when the connection dies - Changed IXR_Client_Gbx::resetError() to assign 'false' for correct isError() - Tweaked some 'transport error' messages - - Release 2009-04-08 - Gou1: - Added method IXR_Client_Gbx::queryIgnoreResult() - Added methods IXR_Client_Gbx::sendRequest() & IXR_Client_Gbx::getResult() - IXR_Client_Gbx::queryIgnoreResult checks if the request is larger than 512KB to avoid errors - If larger than 512KB and method is system.multicall, try to divide the request into - two separate requests with two separate IXR_Client_Gbx::queryIgnoreResult() calls - - Release 2009-06-03 - Xymph: - Suppress possible repetitive CRT warning at stream_select - - Release 2011-04-09 - Xymph / La beuze: - Added optional timeout mechanism to IXR_Client_Gbx::InitWithIp() - - Release 2011-05-22 - Xymph: - Added non-error (true) return status to IXR_Client_Gbx::queryIgnoreResult() - Updated status codes and messages for transport/endian errors - Prevented possible PHP warning in IXR_Client_Gbx::getErrorCode() and getErrorMessage() -*/ - -if (!defined('LF')) { - define('LF', "\n"); -} - -class IXR_Value { - public $data; - public $type; - - function IXR_Value ($data, $type = false) { - $this->data = $data; - if (!$type) { - $type = $this->calculateType(); - } - $this->type = $type; - if ($type == 'struct') { - // Turn all the values in the array into new IXR_Value objects - foreach ($this->data as $key => $value) { - $this->data[$key] = new IXR_Value($value); - } - } - if ($type == 'array') { - for ($i = 0, $j = count($this->data); $i < $j; $i++) { - $this->data[$i] = new IXR_Value($this->data[$i]); - } - } - } - - function calculateType() { - if ($this->data === true || $this->data === false) { - return 'boolean'; - } - if (is_integer($this->data)) { - return 'int'; - } - if (is_double($this->data)) { - return 'double'; - } - // Deal with IXR object types base64 and date - if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { - return 'date'; - } - if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { - return 'base64'; - } - // If it is a normal PHP object convert it into a struct - if (is_object($this->data)) { - $this->data = get_object_vars($this->data); - return 'struct'; - } - if (!is_array($this->data)) { - return 'string'; - } - // We have an array - is it an array or a struct? - if ($this->isStruct($this->data)) { - return 'struct'; - } else { - return 'array'; - } - } - - function getXml() { - // Return XML for this value - switch ($this->type) { - case 'boolean': - return '' . ($this->data ? '1' : '0') . ''; - break; - case 'int': - return '' . $this->data . ''; - break; - case 'double': - return '' . $this->data . ''; - break; - case 'string': - return '' . htmlspecialchars($this->data) . ''; - break; - case 'array': - $return = '' . LF; - foreach ($this->data as $item) { - $return .= ' ' . $item->getXml() . '' . LF; - } - $return .= ''; - return $return; - break; - case 'struct': - $return = '' . LF; - foreach ($this->data as $name => $value) { - $return .= ' ' . $name . ''; - $return .= $value->getXml() . '' . LF; - } - $return .= ''; - return $return; - break; - case 'date': - case 'base64': - return $this->data->getXml(); - break; - } - return false; - } - - function isStruct($array) { - // Nasty function to check if an array is a struct or not - $expected = 0; - foreach ($array as $key => $value) { - if ((string)$key != (string)$expected) { - return true; - } - $expected++; - } - return false; - } -} - - -class IXR_Message { - public $message; - public $messageType; // methodCall / methodResponse / fault - public $faultCode; - public $faultString; - public $methodName; - public $params; - // Current variable stacks - protected $_arraystructs = array(); // Stack to keep track of the current array/struct - protected $_arraystructstypes = array(); // Stack to keep track of whether things are structs or array - protected $_currentStructName = array(); // A stack as well - protected $_param; - protected $_value; - protected $_currentTag; - protected $_currentTagContents; - // The XML parser - protected $_parser; - - function IXR_Message ($message) { - $this->message = $message; - } - - function parse() { - // first remove the XML declaration - $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); - if (trim($this->message) == '') { - return false; - } - $this->_parser = xml_parser_create(); - // Set XML parser to take the case of tags into account - xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); - // Set XML parser callback functions - xml_set_object($this->_parser, $this); - xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); - xml_set_character_data_handler($this->_parser, 'cdata'); - if (!xml_parse($this->_parser, $this->message)) { - /* die(sprintf('GbxRemote XML error: %s at line %d', - xml_error_string(xml_get_error_code($this->_parser)), - xml_get_current_line_number($this->_parser))); */ - return false; - } - xml_parser_free($this->_parser); - // Grab the error messages, if any - if ($this->messageType == 'fault') { - $this->faultCode = $this->params[0]['faultCode']; - $this->faultString = $this->params[0]['faultString']; - } - return true; - } - - function tag_open($parser, $tag, $attr) { - $this->currentTag = $tag; - switch ($tag) { - case 'methodCall': - case 'methodResponse': - case 'fault': - $this->messageType = $tag; - break; - // Deal with stacks of arrays and structs - case 'data': // data is to all intents and purposes more interesting than array - $this->_arraystructstypes[] = 'array'; - $this->_arraystructs[] = array(); - break; - case 'struct': - $this->_arraystructstypes[] = 'struct'; - $this->_arraystructs[] = array(); - break; - } - } - - function cdata($parser, $cdata) { - $this->_currentTagContents .= $cdata; - } - - function tag_close($parser, $tag) { - $valueFlag = false; - switch ($tag) { - case 'int': - case 'i4': - $value = (int)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'double': - $value = (double)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'string': - $value = (string)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'dateTime.iso8601': - $value = new IXR_Date(trim($this->_currentTagContents)); - // $value = $iso->getTimestamp(); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'value': - // If no type is indicated, the type is string - if (trim($this->_currentTagContents) != '') { - $value = (string)$this->_currentTagContents; - $this->_currentTagContents = ''; - $valueFlag = true; - } - break; - case 'boolean': - $value = (boolean)trim($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - case 'base64': - $value = base64_decode($this->_currentTagContents); - $this->_currentTagContents = ''; - $valueFlag = true; - break; - // Deal with stacks of arrays and structs - case 'data': - case 'struct': - $value = array_pop($this->_arraystructs); - array_pop($this->_arraystructstypes); - $valueFlag = true; - break; - case 'member': - array_pop($this->_currentStructName); - break; - case 'name': - $this->_currentStructName[] = trim($this->_currentTagContents); - $this->_currentTagContents = ''; - break; - case 'methodName': - $this->methodName = trim($this->_currentTagContents); - $this->_currentTagContents = ''; - break; - } - - if ($valueFlag) { - /* - if (!is_array($value) && !is_object($value)) { - $value = trim($value); - } - */ - if (count($this->_arraystructs) > 0) { - // Add value to struct or array - if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { - // Add to struct - $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; - } else { - // Add to array - $this->_arraystructs[count($this->_arraystructs)-1][] = $value; - } - } else { - // Just add as a paramater - $this->params[] = $value; - } - } - } -} - - -class IXR_Request { - public $method; - public $args; - public $xml; - - function IXR_Request($method, $args) { - $this->method = $method; - $this->args = $args; - $this->xml = '' . $this->method . ''; - foreach ($this->args as $arg) { - $this->xml .= ''; - $v = new IXR_Value($arg); - $this->xml .= $v->getXml(); - $this->xml .= '' . LF; - } - $this->xml .= ''; - } - - function getLength() { - return strlen($this->xml); - } - - function getXml() { - return $this->xml; - } -} - - -class IXR_Error { - public $code; - public $message; - - function IXR_Error($code, $message) { - $this->code = $code; - $this->message = $message; - } - - function getXml() { - $xml = << - - - - - faultCode - {$this->code} - - - faultString - {$this->message} - - - - - -EOD; - return $xml; - } -} - - -class IXR_Date { - public $year; - public $month; - public $day; - public $hour; - public $minute; - public $second; - - function IXR_Date($time) { - // $time can be a PHP timestamp or an ISO one - if (is_numeric($time)) { - $this->parseTimestamp($time); - } else { - $this->parseIso($time); - } - } - - function parseTimestamp($timestamp) { - $this->year = date('Y', $timestamp); - $this->month = date('Y', $timestamp); - $this->day = date('Y', $timestamp); - $this->hour = date('H', $timestamp); - $this->minute = date('i', $timestamp); - $this->second = date('s', $timestamp); - } - - function parseIso($iso) { - $this->year = substr($iso, 0, 4); - $this->month = substr($iso, 4, 2); - $this->day = substr($iso, 6, 2); - $this->hour = substr($iso, 9, 2); - $this->minute = substr($iso, 12, 2); - $this->second = substr($iso, 15, 2); - } - - function getIso() { - return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; - } - - function getXml() { - return ''.$this->getIso().''; - } - - function getTimestamp() { - return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); - } -} - - -class IXR_Base64 { - public $data; - - function IXR_Base64($data) { - $this->data = $data; - } - - function getXml() { - return ''.base64_encode($this->data).''; - } -} - - -////////////////////////////////////////////////////////// -// Nadeo modifications // -// (many thanks to slig for adding callback support) // -////////////////////////////////////////////////////////// -class IXR_Client_Gbx { - public $socket; - public $message = false; - public $cb_message = array(); - public $reqhandle; - public $protocol = 0; - // Storage place for an error message - public $error = false; - - function bigEndianTest() { - list($endiantest) = array_values(unpack('L1L', pack('V', 1))); - if ($endiantest != 1) { - echo "Machine reports itself as BigEndian, float handling must be altered\r\n"; - echo "Overwrite GbxRemote.inc.php with GbxRemote.bem.php\r\n"; - die('App Terminated'); - return false; - } - return true; - } // bigEndianTest - - function IXR_Client_Gbx() { - $this->socket = false; - $this->reqhandle = 0x80000000; - } - - function InitWithIp($ip, $port, $timeout = null) { - - if (!$this->bigEndianTest()) { - $this->error = new IXR_Error(-31999, 'endian error - script doesn\'t match machine type'); - return false; - } - - // open connection, with timeout if specified - if (!isset($timeout)) { - $this->socket = @fsockopen($ip, $port, $errno, $errstr); - } else { - $init_time = microtime(true); - $init_timeout = 5; // retry every 5s - while (true) { - $this->socket = @fsockopen($ip, $port, $errno, $errstr, $init_timeout); - if ($this->socket || (microtime(true) - $init_time >= $timeout)) - break; - } - } - if (!$this->socket) { - $this->error = new IXR_Error(-32300, "transport error - could not open socket (error: $errno, $errstr)"); - return false; - } - // handshake - $array_result = unpack('Vsize', fread($this->socket, 4)); - $size = $array_result['size']; - if ($size > 64) { - $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol header'); - return false; - } - $handshake = fread($this->socket, $size); - if ($handshake == 'GBXRemote 1') { - $this->protocol = 1; - } else if ($handshake == 'GBXRemote 2') { - $this->protocol = 2; - } else { - $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol version'); - return false; - } - return true; - } - - function Init($port) { - return $this->InitWithIp('localhost', $port); - } - - function Terminate() { - if ($this->socket) { - fclose($this->socket); - $this->socket = false; - } - } - - protected function sendRequest(IXR_Request $request) { - $xml = $request->getXml(); - - @stream_set_timeout($this->socket, 20); // timeout 20s (to write the request) - // send request - $this->reqhandle++; - if ($this->protocol == 1) { - $bytes = pack('Va*', strlen($xml), $xml); - } else { - $bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml); - } - - $bytes_to_write = strlen($bytes); - while ($bytes_to_write > 0) { - $r = @fwrite($this->socket, $bytes); - if ($r === false || $r == 0) { - // connection interrupted - return false; // or die? - } - - $bytes_to_write -= $r; - if ($bytes_to_write == 0) - break; - - $bytes = substr($bytes, $r); - } - - return true; - } - - protected function getResult() { - $contents = ''; - $contents_length = 0; - do { - $size = 0; - $recvhandle = 0; - @stream_set_timeout($this->socket, 20); // timeout 20s (to read the reply header) - // Get result - if ($this->protocol == 1) { - $contents = fread($this->socket, 4); - if (strlen($contents) == 0) { - $this->error = new IXR_Error(-32300, 'transport error - cannot read size'); - return false; - } - $array_result = unpack('Vsize', $contents); - $size = $array_result['size']; - $recvhandle = $this->reqhandle; - } else { - $contents = fread($this->socket, 8); - if (strlen($contents) == 0) { - $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); - return false; - } - $array_result = unpack('Vsize/Vhandle', $contents); - $size = $array_result['size']; - $recvhandle = $array_result['handle']; - // -- amd64 support -- - $bits = sprintf('%b', $recvhandle); - if (strlen($bits) == 64) { - $recvhandle = bindec(substr($bits, 32)); - } - } - - if ($recvhandle == 0 || $size == 0) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - if ($size > 4096*1024) { - $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); - return false; - } - - $contents = ''; - $contents_length = 0; - @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (for successive reads until end) - while ($contents_length < $size) { - $contents .= fread($this->socket, $size-$contents_length); - $contents_length = strlen($contents); - } - - if (($recvhandle & 0x80000000) == 0) { - // this is a callback, not our answer! handle= $recvhandle, xml-rpc= $contents - // just add it to the message list for the user to read - $new_cb_message = new IXR_Message($contents); - if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { - array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); - } - } - } while ((int)$recvhandle != (int)$this->reqhandle); - - $this->message = new IXR_Message($contents); - if (!$this->message->parse()) { - // XML error - $this->error = new IXR_Error(-32700, 'parse error. not well formed'); - return false; - } - // Is the message a fault? - if ($this->message->messageType == 'fault') { - $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); - return false; - } - // Message must be OK - return true; - } - - - function query() { - $args = func_get_args(); - $method = array_shift($args); - - if (!$this->socket || $this->protocol == 0) { - $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); - return false; - } - - $request = new IXR_Request($method, $args); - - // Check if request is larger than 512 Kbytes - if (($size = $request->getLength()) > 512*1024-8) { - $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); - return false; - } - - // Send request - $ok = $this->sendRequest($request); - if (!$ok) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - - // Get result - return $this->getResult(); - } - - // Non-blocking query method: doesn't read the response - function queryIgnoreResult() { - $args = func_get_args(); - $method = array_shift($args); - - if (!$this->socket || $this->protocol == 0) { - $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); - return false; - } - - $request = new IXR_Request($method, $args); - - // Check if the request is greater than 512 Kbytes to avoid errors - // If the method is system.multicall, make two calls (possibly recursively) - if (($size = $request->getLength()) > 512*1024-8) { - if ($method = 'system.multicall' && isset($args[0])) { - $count = count($args[0]); - // If count is 1, query cannot be reduced - if ($count < 2) { - $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); - return false; - } - $length = floor($count/2); - $args1 = array_slice($args[0], 0, $length); - $args2 = array_slice($args[0], $length, ($count-$length)); - - $res1 = $this->queryIgnoreResult('system.multicall', $args1); - $res2 = $this->queryIgnoreResult('system.multicall', $args2); - return ($res1 && $res2); - } - // If the method is not a multicall, just stop - else { - $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); - return false; - } - } - - // Send request - $ok = $this->sendRequest($request); - if (!$ok) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - return true; - } - - function readCB($timeout = 2000) { // timeout 2 ms - if (!$this->socket || $this->protocol == 0) { - $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); - return false; - } - if ($this->protocol == 1) - return false; - - $something_received = count($this->cb_message)>0; - $contents = ''; - $contents_length = 0; - - @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (to read available data) - // (assignment in arguments is forbidden since php 5.1.1) - $read = array($this->socket); - $write = NULL; - $except = NULL; - $nb = @stream_select($read, $write, $except, 0, $timeout); - // workaround for stream_select bug with amd64 - if ($nb !== false) - $nb = count($read); - - while ($nb !== false && $nb > 0) { - $timeout = 0; // we don't want to wait for the full time again, just flush the available data - - $size = 0; - $recvhandle = 0; - // Get result - $contents = fread($this->socket, 8); - if (strlen($contents) == 0) { - $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); - return false; - } - $array_result = unpack('Vsize/Vhandle', $contents); - $size = $array_result['size']; - $recvhandle = $array_result['handle']; - - if ($recvhandle == 0 || $size == 0) { - $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); - return false; - } - if ($size > 4096*1024) { - $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); - return false; - } - - $contents = ''; - $contents_length = 0; - while ($contents_length < $size) { - $contents .= fread($this->socket, $size-$contents_length); - $contents_length = strlen($contents); - } - - if (($recvhandle & 0x80000000) == 0) { - // this is a callback. handle= $recvhandle, xml-rpc= $contents - //echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF; - $new_cb_message = new IXR_Message($contents); - if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { - array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); - } - $something_received = true; - } - - // (assignment in arguments is forbidden since php 5.1.1) - $read = array($this->socket); - $write = NULL; - $except = NULL; - $nb = @stream_select($read, $write, $except, 0, $timeout); - // workaround for stream_select bug with amd64 - if ($nb !== false) - $nb = count($read); - } - return $something_received; - } - - function getResponse() { - // methodResponses can only have one param - return that - return $this->message->params[0]; - } - - function getCBResponses() { - // (look at the end of basic.php for an example) - $messages = $this->cb_message; - $this->cb_message = array(); - return $messages; - } - - function isError() { - return is_object($this->error); - } - - function resetError() { - $this->error = false; - } - - function getErrorCode() { - if ($this->isError()) - return $this->error->code; - else - return 0; - } - - function getErrorMessage() { - if ($this->isError()) - return $this->error->message; - else - return ''; - } -} - - -class IXR_ClientMulticall_Gbx extends IXR_Client_Gbx { - public $calls = array(); - - function addCall($methodName, $args) { - $struct = array('methodName' => $methodName, 'params' => $args); - $this->calls[] = $struct; - - return (count($this->calls) - 1); - } - - function multiquery($ignoreResult = false) { - // Prepare multicall, then call the parent::query() (or queryIgnoreResult) method - if ($ignoreResult) { - $result = parent::queryIgnoreResult('system.multicall', $this->calls); - } else { - $result = parent::query('system.multicall', $this->calls); - } - $this->calls = array(); // reset for next calls - return $result; - } -} - + htmlspecialchars) + Site: http://scripts.incutio.com/xmlrpc/ + Manual: http://scripts.incutio.com/xmlrpc/manual.php + Errors: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php + Made available under the Artistic License: http://www.opensource.org/licenses/artistic-license.php + + Modified to support protocol 'GbxRemote 2' ('GbxRemote 1') + This version is for LittleEndian (e.g. Intel PC) machines. For BegEndian + machines use GbxRemote.bem.php as GbxRemote.inc.php instead. + + Release 2007-09-22 - Slig: + Modified to support >256KB received data (and now >2MB data produce a specific error message) + Modified readCB() to wait the initial timeout only before first read packet + Modified readCB() to return true if there is data to get with getCBResponses() + Modified to support amd64 (for $recvhandle) + Modified IXR_ClientMulticall_Gbx::addCall() to fit Aseco 0.6.1 + Added IXR_Client_Gbx::bytes_sent & bytes_received counters + Fix for a changed feature since php5.1.1 about reference parameter assignment (was used in stream_select) + Workaround for stream_select return value bug with amd64 + + Release 2008-01-20 - Slig / Xymph / Assembler Maniac: + Workaround for fread delay bug in some cases + Added IXR_Client_Gbx::resetError() method (by Xymph) + Some comments and strings code cleanup (by Xymph) + Fix stream_set_timeout($this->socket,...) (thx to CavalierDeVache) + Added a default timeout value to IXR_Client_Gbx::readCB($timeout) + Changed calls with timeout on a stream to use microseconds instead of seconds (by AM) + Removed IXR_Client_Gbx::bytes_sent & bytes_received counters - not used (by AM) + + Release 2008-02-05 - Slig: + Changed some socket read/write timeouts back to seconds to avoid 'transport error' + Changed max data received from 2MB to 4MB + + Release 2008-05-20 - Xymph: + Prevented unpack() warnings in IXR_Client_Gbx::query() when the connection dies + Changed IXR_Client_Gbx::resetError() to assign 'false' for correct isError() + Tweaked some 'transport error' messages + + Release 2009-04-08 - Gou1: + Added method IXR_Client_Gbx::queryIgnoreResult() + Added methods IXR_Client_Gbx::sendRequest() & IXR_Client_Gbx::getResult() + IXR_Client_Gbx::queryIgnoreResult checks if the request is larger than 512KB to avoid errors + If larger than 512KB and method is system.multicall, try to divide the request into + two separate requests with two separate IXR_Client_Gbx::queryIgnoreResult() calls + + Release 2009-06-03 - Xymph: + Suppress possible repetitive CRT warning at stream_select + + Release 2011-04-09 - Xymph / La beuze: + Added optional timeout mechanism to IXR_Client_Gbx::InitWithIp() + + Release 2011-05-22 - Xymph: + Added non-error (true) return status to IXR_Client_Gbx::queryIgnoreResult() + Updated status codes and messages for transport/endian errors + Prevented possible PHP warning in IXR_Client_Gbx::getErrorCode() and getErrorMessage() +*/ + +if (!defined('LF')) { + define('LF', "\n"); +} + +class IXR_Value { + public $data; + public $type; + + function IXR_Value ($data, $type = false) { + $this->data = $data; + if (!$type) { + $type = $this->calculateType(); + } + $this->type = $type; + if ($type == 'struct') { + // Turn all the values in the array into new IXR_Value objects + foreach ($this->data as $key => $value) { + $this->data[$key] = new IXR_Value($value); + } + } + if ($type == 'array') { + for ($i = 0, $j = count($this->data); $i < $j; $i++) { + $this->data[$i] = new IXR_Value($this->data[$i]); + } + } + } + + function calculateType() { + if ($this->data === true || $this->data === false) { + return 'boolean'; + } + if (is_integer($this->data)) { + return 'int'; + } + if (is_double($this->data)) { + return 'double'; + } + // Deal with IXR object types base64 and date + if (is_object($this->data) && is_a($this->data, 'IXR_Date')) { + return 'date'; + } + if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) { + return 'base64'; + } + // If it is a normal PHP object convert it into a struct + if (is_object($this->data)) { + $this->data = get_object_vars($this->data); + return 'struct'; + } + if (!is_array($this->data)) { + return 'string'; + } + // We have an array - is it an array or a struct? + if ($this->isStruct($this->data)) { + return 'struct'; + } else { + return 'array'; + } + } + + function getXml() { + // Return XML for this value + switch ($this->type) { + case 'boolean': + return '' . ($this->data ? '1' : '0') . ''; + break; + case 'int': + return '' . $this->data . ''; + break; + case 'double': + return '' . $this->data . ''; + break; + case 'string': + return '' . htmlspecialchars($this->data) . ''; + break; + case 'array': + $return = '' . LF; + foreach ($this->data as $item) { + $return .= ' ' . $item->getXml() . '' . LF; + } + $return .= ''; + return $return; + break; + case 'struct': + $return = '' . LF; + foreach ($this->data as $name => $value) { + $return .= ' ' . $name . ''; + $return .= $value->getXml() . '' . LF; + } + $return .= ''; + return $return; + break; + case 'date': + case 'base64': + return $this->data->getXml(); + break; + } + return false; + } + + function isStruct($array) { + // Nasty function to check if an array is a struct or not + $expected = 0; + foreach ($array as $key => $value) { + if ((string)$key != (string)$expected) { + return true; + } + $expected++; + } + return false; + } +} + + +class IXR_Message { + public $message; + public $messageType; // methodCall / methodResponse / fault + public $faultCode; + public $faultString; + public $methodName; + public $params; + // Current variable stacks + protected $_arraystructs = array(); // Stack to keep track of the current array/struct + protected $_arraystructstypes = array(); // Stack to keep track of whether things are structs or array + protected $_currentStructName = array(); // A stack as well + protected $_param; + protected $_value; + protected $_currentTag; + protected $_currentTagContents; + // The XML parser + protected $_parser; + + function IXR_Message ($message) { + $this->message = $message; + } + + function parse() { + // first remove the XML declaration + $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); + if (trim($this->message) == '') { + return false; + } + $this->_parser = xml_parser_create(); + // Set XML parser to take the case of tags into account + xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); + // Set XML parser callback functions + xml_set_object($this->_parser, $this); + xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); + xml_set_character_data_handler($this->_parser, 'cdata'); + if (!xml_parse($this->_parser, $this->message)) { + /* die(sprintf('GbxRemote XML error: %s at line %d', + xml_error_string(xml_get_error_code($this->_parser)), + xml_get_current_line_number($this->_parser))); */ + return false; + } + xml_parser_free($this->_parser); + // Grab the error messages, if any + if ($this->messageType == 'fault') { + $this->faultCode = $this->params[0]['faultCode']; + $this->faultString = $this->params[0]['faultString']; + } + return true; + } + + function tag_open($parser, $tag, $attr) { + $this->currentTag = $tag; + switch ($tag) { + case 'methodCall': + case 'methodResponse': + case 'fault': + $this->messageType = $tag; + break; + // Deal with stacks of arrays and structs + case 'data': // data is to all intents and purposes more interesting than array + $this->_arraystructstypes[] = 'array'; + $this->_arraystructs[] = array(); + break; + case 'struct': + $this->_arraystructstypes[] = 'struct'; + $this->_arraystructs[] = array(); + break; + } + } + + function cdata($parser, $cdata) { + $this->_currentTagContents .= $cdata; + } + + function tag_close($parser, $tag) { + $valueFlag = false; + switch ($tag) { + case 'int': + case 'i4': + $value = (int)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'double': + $value = (double)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'string': + $value = (string)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'dateTime.iso8601': + $value = new IXR_Date(trim($this->_currentTagContents)); + // $value = $iso->getTimestamp(); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'value': + // If no type is indicated, the type is string + if (trim($this->_currentTagContents) != '') { + $value = (string)$this->_currentTagContents; + $this->_currentTagContents = ''; + $valueFlag = true; + } + break; + case 'boolean': + $value = (boolean)trim($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + case 'base64': + $value = base64_decode($this->_currentTagContents); + $this->_currentTagContents = ''; + $valueFlag = true; + break; + // Deal with stacks of arrays and structs + case 'data': + case 'struct': + $value = array_pop($this->_arraystructs); + array_pop($this->_arraystructstypes); + $valueFlag = true; + break; + case 'member': + array_pop($this->_currentStructName); + break; + case 'name': + $this->_currentStructName[] = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + case 'methodName': + $this->methodName = trim($this->_currentTagContents); + $this->_currentTagContents = ''; + break; + } + + if ($valueFlag) { + /* + if (!is_array($value) && !is_object($value)) { + $value = trim($value); + } + */ + if (count($this->_arraystructs) > 0) { + // Add value to struct or array + if ($this->_arraystructstypes[count($this->_arraystructstypes)-1] == 'struct') { + // Add to struct + $this->_arraystructs[count($this->_arraystructs)-1][$this->_currentStructName[count($this->_currentStructName)-1]] = $value; + } else { + // Add to array + $this->_arraystructs[count($this->_arraystructs)-1][] = $value; + } + } else { + // Just add as a paramater + $this->params[] = $value; + } + } + } +} + + +class IXR_Request { + public $method; + public $args; + public $xml; + + function IXR_Request($method, $args) { + $this->method = $method; + $this->args = $args; + $this->xml = '' . $this->method . ''; + foreach ($this->args as $arg) { + $this->xml .= ''; + $v = new IXR_Value($arg); + $this->xml .= $v->getXml(); + $this->xml .= '' . LF; + } + $this->xml .= ''; + } + + function getLength() { + return strlen($this->xml); + } + + function getXml() { + return $this->xml; + } +} + + +class IXR_Error { + public $code; + public $message; + + function IXR_Error($code, $message) { + $this->code = $code; + $this->message = $message; + } + + function getXml() { + $xml = << + + + + + faultCode + {$this->code} + + + faultString + {$this->message} + + + + + +EOD; + return $xml; + } +} + + +class IXR_Date { + public $year; + public $month; + public $day; + public $hour; + public $minute; + public $second; + + function IXR_Date($time) { + // $time can be a PHP timestamp or an ISO one + if (is_numeric($time)) { + $this->parseTimestamp($time); + } else { + $this->parseIso($time); + } + } + + function parseTimestamp($timestamp) { + $this->year = date('Y', $timestamp); + $this->month = date('Y', $timestamp); + $this->day = date('Y', $timestamp); + $this->hour = date('H', $timestamp); + $this->minute = date('i', $timestamp); + $this->second = date('s', $timestamp); + } + + function parseIso($iso) { + $this->year = substr($iso, 0, 4); + $this->month = substr($iso, 4, 2); + $this->day = substr($iso, 6, 2); + $this->hour = substr($iso, 9, 2); + $this->minute = substr($iso, 12, 2); + $this->second = substr($iso, 15, 2); + } + + function getIso() { + return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second; + } + + function getXml() { + return ''.$this->getIso().''; + } + + function getTimestamp() { + return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year); + } +} + + +class IXR_Base64 { + public $data; + + function IXR_Base64($data) { + $this->data = $data; + } + + function getXml() { + return ''.base64_encode($this->data).''; + } +} + + +////////////////////////////////////////////////////////// +// Nadeo modifications // +// (many thanks to slig for adding callback support) // +////////////////////////////////////////////////////////// +class IXR_Client_Gbx { + public $socket; + public $message = false; + public $cb_message = array(); + public $reqhandle; + public $protocol = 0; + // Storage place for an error message + public $error = false; + + function bigEndianTest() { + list($endiantest) = array_values(unpack('L1L', pack('V', 1))); + if ($endiantest != 1) { + echo "Machine reports itself as BigEndian, float handling must be altered\r\n"; + echo "Overwrite GbxRemote.inc.php with GbxRemote.bem.php\r\n"; + die('App Terminated'); + return false; + } + return true; + } // bigEndianTest + + function IXR_Client_Gbx() { + $this->socket = false; + $this->reqhandle = 0x80000000; + } + + function InitWithIp($ip, $port, $timeout = null) { + + if (!$this->bigEndianTest()) { + $this->error = new IXR_Error(-31999, 'endian error - script doesn\'t match machine type'); + return false; + } + + // open connection, with timeout if specified + if (!isset($timeout)) { + $this->socket = @fsockopen($ip, $port, $errno, $errstr); + } else { + $init_time = microtime(true); + $init_timeout = 5; // retry every 5s + while (true) { + $this->socket = @fsockopen($ip, $port, $errno, $errstr, $init_timeout); + if ($this->socket || (microtime(true) - $init_time >= $timeout)) + break; + } + } + if (!$this->socket) { + $this->error = new IXR_Error(-32300, "transport error - could not open socket (error: $errno, $errstr)"); + return false; + } + // handshake + $array_result = unpack('Vsize', fread($this->socket, 4)); + $size = $array_result['size']; + if ($size > 64) { + $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol header'); + return false; + } + $handshake = fread($this->socket, $size); + if ($handshake == 'GBXRemote 1') { + $this->protocol = 1; + } else if ($handshake == 'GBXRemote 2') { + $this->protocol = 2; + } else { + $this->error = new IXR_Error(-32300, 'transport error - wrong lowlevel protocol version'); + return false; + } + return true; + } + + function Init($port) { + return $this->InitWithIp('localhost', $port); + } + + function Terminate() { + if ($this->socket) { + fclose($this->socket); + $this->socket = false; + } + } + + protected function sendRequest(IXR_Request $request) { + $xml = $request->getXml(); + + @stream_set_timeout($this->socket, 20); // timeout 20s (to write the request) + // send request + $this->reqhandle++; + if ($this->protocol == 1) { + $bytes = pack('Va*', strlen($xml), $xml); + } else { + $bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml); + } + + $bytes_to_write = strlen($bytes); + while ($bytes_to_write > 0) { + $r = @fwrite($this->socket, $bytes); + if ($r === false || $r == 0) { + // connection interrupted + return false; // or die? + } + + $bytes_to_write -= $r; + if ($bytes_to_write == 0) + break; + + $bytes = substr($bytes, $r); + } + + return true; + } + + protected function getResult() { + $contents = ''; + $contents_length = 0; + do { + $size = 0; + $recvhandle = 0; + @stream_set_timeout($this->socket, 20); // timeout 20s (to read the reply header) + // Get result + if ($this->protocol == 1) { + $contents = fread($this->socket, 4); + if (strlen($contents) == 0) { + $this->error = new IXR_Error(-32300, 'transport error - cannot read size'); + return false; + } + $array_result = unpack('Vsize', $contents); + $size = $array_result['size']; + $recvhandle = $this->reqhandle; + } else { + $contents = fread($this->socket, 8); + if (strlen($contents) == 0) { + $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); + return false; + } + $array_result = unpack('Vsize/Vhandle', $contents); + $size = $array_result['size']; + $recvhandle = $array_result['handle']; + // -- amd64 support -- + $bits = sprintf('%b', $recvhandle); + if (strlen($bits) == 64) { + $recvhandle = bindec(substr($bits, 32)); + } + } + + if ($recvhandle == 0 || $size == 0) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + if ($size > 4096*1024) { + $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); + return false; + } + + $contents = ''; + $contents_length = 0; + @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (for successive reads until end) + while ($contents_length < $size) { + $contents .= fread($this->socket, $size-$contents_length); + $contents_length = strlen($contents); + } + + if (($recvhandle & 0x80000000) == 0) { + // this is a callback, not our answer! handle= $recvhandle, xml-rpc= $contents + // just add it to the message list for the user to read + $new_cb_message = new IXR_Message($contents); + if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { + array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); + } + } + } while ((int)$recvhandle != (int)$this->reqhandle); + + $this->message = new IXR_Message($contents); + if (!$this->message->parse()) { + // XML error + $this->error = new IXR_Error(-32700, 'parse error. not well formed'); + return false; + } + // Is the message a fault? + if ($this->message->messageType == 'fault') { + $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); + return false; + } + // Message must be OK + return true; + } + + + function query() { + $args = func_get_args(); + $method = array_shift($args); + + if (!$this->socket || $this->protocol == 0) { + $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); + return false; + } + + $request = new IXR_Request($method, $args); + + // Check if request is larger than 512 Kbytes + if (($size = $request->getLength()) > 512*1024-8) { + $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); + return false; + } + + // Send request + $ok = $this->sendRequest($request); + if (!$ok) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + + // Get result + return $this->getResult(); + } + + // Non-blocking query method: doesn't read the response + function queryIgnoreResult() { + $args = func_get_args(); + $method = array_shift($args); + + if (!$this->socket || $this->protocol == 0) { + $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); + return false; + } + + $request = new IXR_Request($method, $args); + + // Check if the request is greater than 512 Kbytes to avoid errors + // If the method is system.multicall, make two calls (possibly recursively) + if (($size = $request->getLength()) > 512*1024-8) { + if ($method = 'system.multicall' && isset($args[0])) { + $count = count($args[0]); + // If count is 1, query cannot be reduced + if ($count < 2) { + $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); + return false; + } + $length = floor($count/2); + $args1 = array_slice($args[0], 0, $length); + $args2 = array_slice($args[0], $length, ($count-$length)); + + $res1 = $this->queryIgnoreResult('system.multicall', $args1); + $res2 = $this->queryIgnoreResult('system.multicall', $args2); + return ($res1 && $res2); + } + // If the method is not a multicall, just stop + else { + $this->error = new IXR_Error(-32300, "transport error - request too large ($size)"); + return false; + } + } + + // Send request + $ok = $this->sendRequest($request); + if (!$ok) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + return true; + } + + function readCB($timeout = 2000) { // timeout 2 ms + if (!$this->socket || $this->protocol == 0) { + $this->error = new IXR_Error(-32300, 'transport error - client not initialized'); + return false; + } + if ($this->protocol == 1) + return false; + + $something_received = count($this->cb_message)>0; + $contents = ''; + $contents_length = 0; + + @stream_set_timeout($this->socket, 0, 10000); // timeout 10 ms (to read available data) + // (assignment in arguments is forbidden since php 5.1.1) + $read = array($this->socket); + $write = NULL; + $except = NULL; + $nb = @stream_select($read, $write, $except, 0, $timeout); + // workaround for stream_select bug with amd64 + if ($nb !== false) + $nb = count($read); + + while ($nb !== false && $nb > 0) { + $timeout = 0; // we don't want to wait for the full time again, just flush the available data + + $size = 0; + $recvhandle = 0; + // Get result + $contents = fread($this->socket, 8); + if (strlen($contents) == 0) { + $this->error = new IXR_Error(-32300, 'transport error - cannot read size/handle'); + return false; + } + $array_result = unpack('Vsize/Vhandle', $contents); + $size = $array_result['size']; + $recvhandle = $array_result['handle']; + + if ($recvhandle == 0 || $size == 0) { + $this->error = new IXR_Error(-32300, 'transport error - connection interrupted!'); + return false; + } + if ($size > 4096*1024) { + $this->error = new IXR_Error(-32300, "transport error - response too large ($size)"); + return false; + } + + $contents = ''; + $contents_length = 0; + while ($contents_length < $size) { + $contents .= fread($this->socket, $size-$contents_length); + $contents_length = strlen($contents); + } + + if (($recvhandle & 0x80000000) == 0) { + // this is a callback. handle= $recvhandle, xml-rpc= $contents + //echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF; + $new_cb_message = new IXR_Message($contents); + if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault') { + array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params)); + } + $something_received = true; + } + + // (assignment in arguments is forbidden since php 5.1.1) + $read = array($this->socket); + $write = NULL; + $except = NULL; + $nb = @stream_select($read, $write, $except, 0, $timeout); + // workaround for stream_select bug with amd64 + if ($nb !== false) + $nb = count($read); + } + return $something_received; + } + + function getResponse() { + // methodResponses can only have one param - return that + return $this->message->params[0]; + } + + function getCBResponses() { + // (look at the end of basic.php for an example) + $messages = $this->cb_message; + $this->cb_message = array(); + return $messages; + } + + function isError() { + return is_object($this->error); + } + + function resetError() { + $this->error = false; + } + + function getErrorCode() { + if ($this->isError()) + return $this->error->code; + else + return 0; + } + + function getErrorMessage() { + if ($this->isError()) + return $this->error->message; + else + return ''; + } +} + + +class IXR_ClientMulticall_Gbx extends IXR_Client_Gbx { + public $calls = array(); + + function addCall($methodName, $args) { + $struct = array('methodName' => $methodName, 'params' => $args); + $this->calls[] = $struct; + + return (count($this->calls) - 1); + } + + function multiquery($ignoreResult = false) { + // Prepare multicall, then call the parent::query() (or queryIgnoreResult) method + if ($ignoreResult) { + $result = parent::queryIgnoreResult('system.multicall', $this->calls); + } else { + $result = parent::query('system.multicall', $this->calls); + } + $this->calls = array(); // reset for next calls + return $result; + } +} + diff --git a/application/core/Players/PlayerCommands.php b/application/core/Players/PlayerCommands.php index f540d069..63ac0ea5 100644 --- a/application/core/Players/PlayerCommands.php +++ b/application/core/Players/PlayerCommands.php @@ -5,7 +5,6 @@ namespace ManiaControl\Players; use ManiaControl\ManiaControl; use ManiaControl\Admin\AuthenticationManager; use ManiaControl\Commands\CommandListener; -use ManiaControl\Players\Player; /** * Class offering various admin commands related to players @@ -51,7 +50,7 @@ class PlayerCommands implements CommandListener { } $success = $this->maniaControl->client->query('AutoTeamBalance'); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendInformation('$<' . $player->nickname . '$> balanced Teams!'); @@ -85,7 +84,7 @@ class PlayerCommands implements CommandListener { } $success = $this->maniaControl->client->query('Kick', $target->login, $message); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendInformation('$<' . $player->nickname . '$> kicked $<' . $target->nickname . '$>!'); @@ -119,7 +118,7 @@ class PlayerCommands implements CommandListener { } $success = $this->maniaControl->client->query('ForceSpectator', $target->login, $type); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } if ($type != 1) { @@ -156,7 +155,7 @@ class PlayerCommands implements CommandListener { } $success = $this->maniaControl->client->query('ForceSpectator', $target->login, 2); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } if ($type != 1) { @@ -188,7 +187,7 @@ class PlayerCommands implements CommandListener { } } if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Fake players connected!', $player->login); @@ -207,7 +206,7 @@ class PlayerCommands implements CommandListener { } $success = $this->maniaControl->client->query('DisconnectFakePlayer', '*'); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Fake players disconnected!', $player->login); diff --git a/application/core/Players/PlayerManager.php b/application/core/Players/PlayerManager.php index 1242a19c..8ad66de3 100644 --- a/application/core/Players/PlayerManager.php +++ b/application/core/Players/PlayerManager.php @@ -122,7 +122,7 @@ class PlayerManager implements CallbackListener { if ($this->maniaControl->settingManager->getSetting($this, self::SETTING_JOIN_LEAVE_MESSAGES)) { $string = array(0 => 'New Player', 1 => '$0f0Operator', 2 => '$0f0Admin', 3 => '$0f0MasterAdmin', 4 => '$0f0MasterAdmin'); - $nickname = Formatter::stripCodes($player->nickname); //TODO strip codes without colour codes like in serverviewer + $nickname = Formatter::stripCodes($player->nickname); // TODO: strip codes without colour codes like in serverviewer $this->maniaControl->chat->sendChat( '$ff0' . $string[$player->authLevel] . ': $fff' . $nickname . '$z $ff0Nation:$fff ' . $player->getCountry() . ' $ff0Ladder: $fff' . $player->ladderRank); diff --git a/application/core/Server/Server.php b/application/core/Server/Server.php index e0dc1df2..680b800f 100644 --- a/application/core/Server/Server.php +++ b/application/core/Server/Server.php @@ -4,6 +4,7 @@ namespace ManiaControl\Server; use ManiaControl\FileUtil; use ManiaControl\ManiaControl; +use ManiaControl\Players\Player; require_once __DIR__ . '/ServerCommands.php'; @@ -159,7 +160,7 @@ class Server { */ public function getSystemInfo() { if (!$this->maniaControl->client->query('GetSystemInfo')) { - trigger_error("Couldn't fetch server system info. " . $this->maniaControl->getClientErrorText($client)); + trigger_error("Couldn't fetch server system info. " . $this->maniaControl->getClientErrorText($this->maniaControl->client)); return null; } return $this->maniaControl->client->getResponse(); @@ -252,7 +253,7 @@ class Server { $map = $this->getMap(); $gameMode = $this->getGameMode(); $time = time(); - $fileName = "GhostReplays/Ghost.{$login}.{$gameMode}.{$time}.{$map['UId']}.Replay.Gbx"; + $fileName = "GhostReplays/Ghost.{$player->login}.{$gameMode}.{$time}.{$map['UId']}.Replay.Gbx"; // Save ghost replay if (!$this->maniaControl->client->query('SaveBestGhostsReplay', $player->login, $fileName)) { diff --git a/application/core/Server/ServerCommands.php b/application/core/Server/ServerCommands.php index b97f5c4d..82eccc51 100644 --- a/application/core/Server/ServerCommands.php +++ b/application/core/Server/ServerCommands.php @@ -161,7 +161,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $serverName = $params[1]; if (!$this->maniaControl->client->query('SetServerName', $serverName)) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess("Server name changed to: '{$serverName}'!", $player->login); @@ -187,7 +187,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('SetServerPassword', $password); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess($successMessage, $player->login); @@ -213,7 +213,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('SetServerPasswordForSpectator', $password); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess($successMessage, $player->login); @@ -246,7 +246,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('SetMaxPlayers', $amount); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess("Changed max players to: {$amount}", $player->login); @@ -279,7 +279,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('SetMaxSpectators', $amount); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess("Changed max spectators to: {$amount}", $player->login); @@ -298,7 +298,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('SetHideServer', 1); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Server is now hidden!', $player->login); @@ -317,7 +317,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('SetHideServer', 0); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Server is now visible!', $player->login); @@ -336,7 +336,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('AllowMapDownload', true); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Map Download is now enabled!', $player->login); @@ -355,7 +355,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('AllowMapDownload', false); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Map Download is now disabled!', $player->login); @@ -374,7 +374,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('DisableHorns', false); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Horns enabled!', $player->login); @@ -393,7 +393,7 @@ class ServerCommands implements CallbackListener, CommandListener { } $success = $this->maniaControl->client->query('DisableHorns', true); if (!$success) { - $this->maniaControl->chat->sendError('Error occured: ' . $this->maniaControl->getClientErrorText(), $player->login); + $this->maniaControl->chat->sendError('Error occurred: ' . $this->maniaControl->getClientErrorText(), $player->login); return; } $this->maniaControl->chat->sendSuccess('Horns disabled!', $player->login); diff --git a/application/core/Settings/SettingManager.php b/application/core/Settings/SettingManager.php index 55453c82..1f3ad42e 100644 --- a/application/core/Settings/SettingManager.php +++ b/application/core/Settings/SettingManager.php @@ -282,7 +282,7 @@ class SettingManager { * Reset a setting to its default value * * @param object $object - * @param string $settingname + * @param string $settingName * @return bool */ public function resetSetting($object, $settingName) { @@ -312,7 +312,7 @@ class SettingManager { * Delete a setting from the database * * @param object $object - * @param string $settingname + * @param string $settingName * @return bool */ public function deleteSetting($object, $settingName) { diff --git a/application/plugins/Chatlog.php b/application/plugins/Chatlog.php index 143306fc..e23c5c7f 100644 --- a/application/plugins/Chatlog.php +++ b/application/plugins/Chatlog.php @@ -28,7 +28,7 @@ class ChatlogPlugin implements CallbackListener, Plugin { private $logServerMessages = true; /** - * Constuct chatlog plugin + * Construct chatlog plugin * * @param ManiaControl $maniaControl */ @@ -129,7 +129,7 @@ class ChatlogPlugin implements CallbackListener, Plugin { /** * Log the given message * - * @param string $message + * @param string $text * @param string $login */ private function logText($text, $login = null) { diff --git a/application/plugins/Donations.php b/application/plugins/Donations.php index 0518c156..630eb9dd 100644 --- a/application/plugins/Donations.php +++ b/application/plugins/Donations.php @@ -168,7 +168,7 @@ class DonationPlugin implements CallbackListener, CommandListener, Plugin { /** * Handle //getplanets command * - * @param array $chat + * @param array $chatCallback * @param Player $player * @return bool */ diff --git a/application/plugins/Karma.php b/application/plugins/Karma.php index dd5d0800..dd1638ec 100644 --- a/application/plugins/Karma.php +++ b/application/plugins/Karma.php @@ -3,12 +3,10 @@ use ManiaControl\ColorUtil; use ManiaControl\ManiaControl; use ManiaControl\Callbacks\CallbackListener; use ManiaControl\Callbacks\CallbackManager; -use ManiaControl\Manialinks\ManialinkUtil; use ManiaControl\Maps\Map; use ManiaControl\Players\Player; use ManiaControl\Plugins\Plugin; use FML\ManiaLink; -use FML\Controls\Control; use FML\Controls\Frame; use FML\Controls\Label; use FML\Controls\Quad; @@ -226,7 +224,7 @@ class KarmaPlugin implements CallbackListener, Plugin { $vote -= substr_count($message, '-'); $success = $this->handleVote($player, $vote); if (!$success) { - $this->maniaControl->chat->sendError('Error occured.', $player->login); + $this->maniaControl->chat->sendError('Error occurred.', $player->login); return; } $this->maniaControl->chat->sendSuccess('Vote updated!', $player->login); @@ -296,7 +294,7 @@ class KarmaPlugin implements CallbackListener, Plugin { PRIMARY KEY (`index`), UNIQUE KEY `player_map_vote` (`mapIndex`, `playerIndex`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Save players map votes' AUTO_INCREMENT=1;"; - $result = $mysqli->query($query); + $mysqli->query($query); if ($mysqli->error) { trigger_error($mysqli->error, E_USER_ERROR); } @@ -361,7 +359,8 @@ class KarmaPlugin implements CallbackListener, Plugin { /** * Get the current karma of the map * - * @param Map $map + * @param Map $map + * @return float | bool */ private function getMapKarma(Map $map) { $mysqli = $this->maniaControl->database->mysqli; @@ -387,9 +386,10 @@ class KarmaPlugin implements CallbackListener, Plugin { } /** - * Get the current votings for the map + * Get the current Votes for the Map * - * @param Map $map + * @param Map $map + * @return array */ private function getMapVotes(Map $map) { $mysqli = $this->maniaControl->database->mysqli; diff --git a/application/plugins/LocalRecords.php b/application/plugins/LocalRecords.php index 6dcf51f9..b5e069f0 100644 --- a/application/plugins/LocalRecords.php +++ b/application/plugins/LocalRecords.php @@ -1,5 +1,4 @@ query($query); + $mysqli->query($query); if ($mysqli->error) { trigger_error($mysqli->error); return; @@ -222,8 +220,8 @@ class LocalRecordsPlugin implements CallbackListener, Plugin { $this->updateManialink = true; // Announce record - // TODO: setting für nur-zum-spieler senden - // TODO: setting für nur-besten-x-announcen + // TODO: setting to send notification only to the player + // TODO: setting to send notifications only for x best records $newRecord = $this->getLocalRecord($map, $player); if (!$oldRecord || $newRecord->rank < $oldRecord->rank) { $improvement = 'gained the'; @@ -257,7 +255,7 @@ class LocalRecordsPlugin implements CallbackListener, Plugin { /** * Handle ClientUpdated callback * - * @param array $data + * @param array $callback */ public function handleClientUpdated(array $callback) { $this->updateManialink = true; diff --git a/application/plugins/Obstacle.php b/application/plugins/Obstacle.php index 33900834..b94823e2 100644 --- a/application/plugins/Obstacle.php +++ b/application/plugins/Obstacle.php @@ -84,7 +84,8 @@ class ObstaclePlugin implements CallbackListener, CommandListener, Plugin { /** * Handle JumpTo command * - * @param array $chatCallback + * @param array $chatCallback + * @param Player $player * @return bool */ public function command_JumpTo(array $chatCallback, Player $player) { @@ -133,7 +134,7 @@ class ObstaclePlugin implements CallbackListener, CommandListener, Plugin { return; } $time = $data->Run->Time; - // Trigger trackmania player finish callback + // Trigger Trackmania player finish callback $finishCallback = array($player->pid, $player->login, $time); $finishCallback = array(CallbackManager::CB_TM_PLAYERCHECKPOINT, $finishCallback); $this->maniaControl->callbackManager->triggerCallback(CallbackManager::CB_TM_PLAYERCHECKPOINT, $finishCallback); diff --git a/application/readme.txt b/application/readme.txt index 87347004..24e726d8 100644 --- a/application/readme.txt +++ b/application/readme.txt @@ -22,7 +22,7 @@ SETUP: Enter your mysql server information. 2.3 Open the file 'configs/authentication.xml'. - Add the player logins of administrators. + Add the Player Logins of Administrators. 3. Run the tool via the shell script 'ManiaControl.sh' (UNIX) or the batch file 'ManiaControl.bat' (Windows)