small fixes

This commit is contained in:
kremsy 2014-02-27 15:03:01 +01:00 committed by Steffen Schröder
parent a85f5b36fb
commit 6e77606d7e
3 changed files with 93 additions and 88 deletions

View File

@ -17,26 +17,26 @@ if (!defined('SIZE_MAX'))
define('SIZE_MAX', 4096*1024);
}
class Client
class Client
{
public $socket;
public $message = false;
public $cb_message = array();
public $reqhandle;
public $protocol = 0;
/**
* @var int Timeout in milli-seconds
* @var int Timeout in milli-seconds
*/
public $timeout;
static $received;
static $sent;
function bigEndianTest()
function bigEndianTest()
{
list($endiantest) = array_values(unpack('L1L', pack('V', 1)));
if ($endiantest != 1)
if ($endiantest != 1)
{
if(!function_exists(__NAMESPACE__.'\\unpack'))
{
@ -45,30 +45,30 @@ class Client
* does not have the capability of unpacking double precision floats
* that were packed in the opposite byte order of the current machine.
*/
function unpack($format, $data)
function unpack($format, $data)
{
$ar = unpack($format, $data);
$vals = array_values($ar);
$f = explode('/', $format);
$i = 0;
foreach ($f as $f_k => $f_v)
foreach ($f as $f_k => $f_v)
{
$repeater = intval(substr($f_v, 1));
if ($repeater == 0)
{
$repeater = 1;
}
if ($f_v{1} == '*')
if ($f_v{1} == '*')
{
$repeater = count($ar) - $i;
}
if ($f_v{0} != 'd')
if ($f_v{0} != 'd')
{
$i += $repeater;
continue;
}
$j = $i + $repeater;
for ($a = $i; $a < $j; ++$a)
for ($a = $i; $a < $j; ++$a)
{
$p = pack('d', $vals[$i]);
$p = strrev($p);
@ -77,7 +77,7 @@ class Client
}
}
$a = 0;
foreach ($ar as $ar_k => $ar_v)
foreach ($ar as $ar_k => $ar_v)
{
$ar[$ar_k] = $vals[$a];
++$a;
@ -89,91 +89,91 @@ class Client
}
/**
*
*
* @param string $hostname
* @param int $port
* @param int $timeout In milliseconds
*/
function __construct($hostname, $port, $timeout = 50)
function __construct($hostname, $port, $timeout = 50)
{
$this->socket = false;
$this->reqhandle = 0x80000000;
$this->timeout = $timeout;
$this->init($hostname, $port);
}
function __destruct()
{
$this->terminate();
}
protected function init($hostname, $port)
protected function init($hostname, $port)
{
$this->bigEndianTest();
// open connection
$this->socket = @fsockopen($hostname, $port, $errno, $errstr, $this->timeout/1000);
if (!$this->socket)
$this->socket = @fsockopen($hostname, $port, $errno, $errstr, $this->timeout * 10000);
if (!$this->socket)
{
throw new FatalException("transport error - could not open socket (error: $errno, $errstr)", FatalException::NOT_INITIALIZED);
}
// handshake
$array_result = unpack('Vsize', fread($this->socket, 4));
$size = $array_result['size'];
if ($size > 64)
if ($size > 64)
{
throw new FatalException('transport error - wrong lowlevel protocol header', FatalException::OTHER);
}
$handshake = fread($this->socket, $size);
if ($handshake == 'GBXRemote 1')
if ($handshake == 'GBXRemote 1')
{
$this->protocol = 1;
}
elseif ($handshake == 'GBXRemote 2')
}
elseif ($handshake == 'GBXRemote 2')
{
$this->protocol = 2;
}
else
}
else
{
throw new FatalException('transport error - wrong lowlevel protocol version', FatalException::OTHER);
}
}
function terminate()
function terminate()
{
if ($this->socket)
if ($this->socket)
{
fclose($this->socket);
$this->socket = false;
}
}
protected function sendRequest(Request $request)
protected function sendRequest(Request $request)
{
$xml = $request->getXml();
@stream_set_timeout($this->socket, 0, $this->timeout * 1000 * 100);
@stream_set_timeout($this->socket, 0, $this->timeout * 1000 * 5);
// send request
$this->reqhandle++;
if ($this->protocol == 1)
if ($this->protocol == 1)
{
$bytes = pack('Va*', strlen($xml), $xml);
}
else
}
else
{
$bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml);
}
$bytes_to_write = strlen($bytes);
// increase sent counter ...
self::$sent += $bytes_to_write;
while ($bytes_to_write > 0)
while ($bytes_to_write > 0)
{
$r = fwrite($this->socket, $bytes);
if ($r === false || $r == 0)
if ($r === false || $r == 0)
{
throw new FatalException('Connection interupted', FatalException::INTERRUPTED);
}
@ -188,31 +188,31 @@ class Client
}
}
protected function getResult()
protected function getResult()
{
$contents = '';
$contents_length = 0;
do
do
{
$size = 0;
$recvhandle = 0;
@stream_set_timeout($this->socket, 0, $this->timeout * 1000);
@stream_set_timeout($this->socket, 0, $this->timeout * 1000 * 2);
// Get result
if ($this->protocol == 1)
if ($this->protocol == 1)
{
$contents = fread($this->socket, 4);
if (strlen($contents) == 0 || $contents === false)
if (strlen($contents) == 0 || $contents === false)
{
throw new FatalException('transport error - connection interrupted!', FatalException::INTERRUPTED);
}
$array_result = unpack('Vsize', $contents);
$size = $array_result['size'];
$recvhandle = $this->reqhandle;
}
else
}
else
{
$contents = fread($this->socket, 8);
if (strlen($contents) == 0 || $contents === false)
if (strlen($contents) == 0 || $contents === false)
{
throw new FatalException('transport error - connection interrupted!', FatalException::INTERRUPTED);
}
@ -221,68 +221,68 @@ class Client
$recvhandle = $array_result['handle'];
// -- amd64 support --
$bits = sprintf('%b', $recvhandle);
if (strlen($bits) == 64)
if (strlen($bits) == 64)
{
$recvhandle = bindec(substr($bits, 32));
}
}
if ($recvhandle == 0 || $size == 0)
if ($recvhandle == 0 || $size == 0)
{
throw new FatalException('transport error - connection interrupted!', FatalException::INTERRUPTED);
}
if ($size > SIZE_MAX)
if ($size > SIZE_MAX)
{
throw new Exception("transport error - answer too big ($size)", Exception::ANWSER_TOO_BIG);
}
self::$received += $size;
$contents = '';
$contents_length = 0;
@stream_set_timeout($this->socket, 0, $this->timeout * 1000);
while ($contents_length < $size)
@stream_set_timeout($this->socket, 0, $this->timeout * 1000);
while ($contents_length < $size)
{
$contents .= fread($this->socket, $size-$contents_length);
$contents_length = strlen($contents);
}
if (($recvhandle & 0x80000000) == 0)
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 Message($contents);
if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault')
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 Message($contents);
if (!$this->message->parse())
if (!$this->message->parse())
{
// XML error
throw new Exception('parse error. not well formed', Exception::OTHER);
}
// Is the message a fault?
if ($this->message->messageType == 'fault')
if ($this->message->messageType == 'fault')
{
throw new Exception($this->message->faultString, $this->message->faultCode);
}
return $this->message;
}
function query()
function query()
{
$args = func_get_args();
$method = array_shift($args);
if (!$this->socket || $this->protocol == 0)
if (!$this->socket || $this->protocol == 0)
{
throw new FatalException('transport error - Client not initialized', FatalException::NOT_INITIALIZED);
}
@ -290,7 +290,7 @@ class Client
$request = new Request($method, $args);
// Check if request is larger than 1024 Kbytes
if ($request->getLength() > 1024*1024-8)
if ($request->getLength() > 1024*1024-8)
{
throw new Exception('transport error - request too large!', Exception::REQUEST_TOO_BIG);
}
@ -300,12 +300,12 @@ class Client
}
// Non-blocking query method: doesn't read the response
function queryIgnoreResult()
function queryIgnoreResult()
{
$args = func_get_args();
$method = array_shift($args);
if (!$this->socket || $this->protocol == 0)
if (!$this->socket || $this->protocol == 0)
{
throw new FatalException('transport error - Client not initialized', FatalException::NOT_INITIALIZED);
}
@ -314,13 +314,13 @@ class Client
// Check if the request is greater than 512 Kbytes to avoid errors
// If the method is system.multicall, make two calls (possibly recursively)
if ($request->getLength() > 1024*1024-8)
if ($request->getLength() > 1024*1024-8)
{
if ($method == 'system.multicall' && isset($args[0]))
if ($method == 'system.multicall' && isset($args[0]))
{
$count = count($args[0]);
// If count is 1, query cannot be reduced
if ($count < 2)
if ($count < 2)
{
throw new Exception('transport error - request too large!', Exception::REQUEST_TOO_BIG);
}
@ -334,7 +334,7 @@ class Client
return ($res1 && $res2);
}
// If the method is not a multicall, just stop
else
else
{
throw new Exception('transport error - request too large!', Exception::REQUEST_TOO_BIG);
}
@ -342,16 +342,16 @@ class Client
$this->sendRequest($request);
}
function getResponse()
function getResponse()
{
// methodResponses can only have one param - return that
return $this->message->params[0];
}
function readCallbacks()
function readCallbacks()
{
if (!$this->socket || $this->protocol == 0)
if (!$this->socket || $this->protocol == 0)
throw new FatalException('transport error - Client not initialized', FatalException::NOT_INITIALIZED);
if ($this->protocol == 1)
return false;
@ -361,16 +361,16 @@ class Client
$contents = '';
$contents_length = 0;
@stream_set_timeout($this->socket, 0, $this->timeout * 1000); // timeout 10 ms (to read available data)
@stream_set_timeout($this->socket, 0, $this->timeout * 100); // 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 = false;
try
{
$nb = @stream_select($read, $write, $except, 0, $this->timeout * 1000);
$nb = @stream_select($read, $write, $except, 0, $this->timeout * 100);
}
catch (\Exception $e)
{
@ -387,20 +387,20 @@ class Client
throw $e;
}
}
// workaround for stream_select bug with amd64
if ($nb !== false)
{
$nb = count($read);
}
while ($nb !== false && $nb > 0)
while ($nb !== false && $nb > 0)
{
$size = 0;
$recvhandle = 0;
// Get result
$contents = fread($this->socket, 8);
if (strlen($contents) == 0 || $contents === false)
if (strlen($contents) == 0 || $contents === false)
{
throw new FatalException('transport error - connection interrupted!', FatalException::INTERRUPTED);
}
@ -408,31 +408,31 @@ class Client
$size = $array_result['size'];
$recvhandle = $array_result['handle'];
if ($recvhandle == 0 || $size == 0)
if ($recvhandle == 0 || $size == 0)
{
throw new FatalException('transport error - connection interrupted!', FatalException::INTERRUPTED);
}
if ($size > SIZE_MAX)
if ($size > SIZE_MAX)
{
throw new Exception("transport error - answer too big ($size)", Exception::ANWSER_TOO_BIG);
}
self::$received += $size;
$contents = '';
$contents_length = 0;
while ($contents_length < $size)
while ($contents_length < $size)
{
$contents .= fread($this->socket, $size-$contents_length);
$contents_length = strlen($contents);
}
if (($recvhandle & 0x80000000) == 0)
if (($recvhandle & 0x80000000) == 0)
{
// this is a callback. handle= $recvhandle, xml-rpc= $contents
//echo 'CALLBACK('.$contents_length.')[ '.$contents.' ]' . LF;
$new_cb_message = new Message($contents);
if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault')
if ($new_cb_message->parse() && $new_cb_message->messageType != 'fault')
{
array_push($this->cb_message, array($new_cb_message->methodName, $new_cb_message->params));
}
@ -444,7 +444,7 @@ class Client
$read = array($this->socket);
$write = NULL;
$except = NULL;
try
{
$nb = @stream_select($read, $write, $except, 0, 0); // Notimeout, just flush the data
@ -460,7 +460,7 @@ class Client
throw $e;
}
}
// workaround for stream_select bug with amd64
if ($nb !== false)
{
@ -470,7 +470,7 @@ class Client
return !empty($this->cb_message);
}
function getCallbackResponses()
function getCallbackResponses()
{
// (look at the end of basic.php for an example)
$messages = $this->cb_message;

View File

@ -48,7 +48,7 @@ class ManiaControl implements CommandListener, TimerListener {
const API_VERSION = '2013-04-16';
const OS_UNIX = 'Unix';
const OS_WIN = 'Windows';
const CONNECT_TIMEOUT = 20000;
const CONNECT_TIMEOUT = 50;
const SCRIPT_TIMEOUT = 20;
const URL_WEBSERVICE = 'http://ws.maniacontrol.com/';
const SETTING_PERMISSION_SHUTDOWN = 'Shutdown ManiaControl';
@ -211,6 +211,7 @@ class ManiaControl implements CommandListener, TimerListener {
if ($message) {
$this->log($message);
}
exit();
}
@ -225,10 +226,14 @@ class ManiaControl implements CommandListener, TimerListener {
$this->chat->sendInformation('ManiaControl shutting down.');
if($this->client){
try{
// Hide manialinks
$this->client->sendHideManialinkPage();
// Close the client connection
$this->client->delete($this->server->ip, $this->server->port);
} catch(FatalException $e){
$this->errorHandler->triggerDebugNotice($e->getMessage() ." File: " . $e->getFile() . " Line: " . $e->getLine());
}
}
//Check and Trigger Fatal Errors

View File

@ -323,7 +323,7 @@ class Server implements CallbackListener {
}
// Server not yet in given status - Wait for it...
$waitBegin = time();
$maxWaitTime = 30;
$maxWaitTime = 50;
$lastStatus = $response->name;
$this->maniaControl->log("Waiting for server to reach status {$statusCode}...");
$this->maniaControl->log("Current Status: {$lastStatus}");