Fixed serialization of arrays

This commit is contained in:
danogentili 2016-10-14 17:16:23 +02:00
parent e7da05e617
commit f3f7772f6e
7 changed files with 67 additions and 25 deletions

View File

@ -20,8 +20,11 @@ class API extends Tools
{
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
$this->session = new MTProto($params);
var_dump($future_salts = $this->ping(3));
var_dump($this->get_future_salts(3));
$ping_res = $this->ping(3);
if(isset($ping["_"]) && $ping["_"] == "pong") {
$this->log->log("Pong: ".$ping["ping_id"]);
}
$future_salts = $this->get_future_salts(3);
}
public function __destruct()

View File

@ -41,7 +41,9 @@ class DataCenter extends Tools
public function dc_disconnect($dc_number)
{
unset($this->sockets[$dc_number]);
if (isset($this->sockets[$dc_number])) {
unset($this->sockets[$dc_number]);
}
}
public function dc_connect($dc_number, $settings = [])

View File

@ -132,6 +132,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
}
$this->settings['authorization']['temp_auth_key'] = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in']);
}
$nearestDc = $this->method_call('invokeWithLayer', [
'layer' => $this->settings['tl_schema']['layer'],
'query' => $this->tl->serialize_method('initConnection',
@ -140,8 +141,13 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
['query' => $this->tl->serialize_method('help.getNearestDc', [])]
)
),
]);
var_dump($nearestDc);
]);
$this->log->log("Current dc is ".$nearestDc["this_dc"].", nearest dc is ".$nearestDc["nearest_dc"]." in ".$nearestDc["country"].".");
if ($nearestDc["nearest_dc"] != $nearestDc["this_dc"]) {
$this->log->log("Switching to dc ".$nearestDc["nearest_dc"]."...");
$this->connection->dc_connect($nearestDc["nearest_dc"]);
}
}
public function __destruct()

View File

@ -17,12 +17,15 @@ namespace danog\MadelineProto\MTProtoTools;
*/
class CallHandler extends AuthKeyHandler
{
public function wait_for_response($last_sent)
public function wait_for_response($last_sent, $optional_name = null)
{
if ($optional_name == null) {
$optional_name = $last_sent;
}
$response = null;
$count = 0;
while ($response == null && $count++ < $this->settings['max_tries']['response']) {
$this->log->log('Getting response (try number '.$count.' for '.$last_sent.')...');
$this->log->log('Getting response (try number '.$count.' for '.$optional_name.')...');
$last_received = $this->recv_message();
$this->handle_message($last_sent, $last_received);
if (isset($this->outgoing_messages[$last_sent]['response']) && isset($this->incoming_messages[$this->outgoing_messages[$last_sent]['response']]['content'])) {
@ -49,7 +52,7 @@ class CallHandler extends AuthKeyHandler
$args = $this->tl->get_named_method_args($method, $args);
$int_message_id = $this->send_message($this->tl->serialize_method($method, $args), $this->tl->content_related($method));
$this->outgoing_messages[$int_message_id]['content'] = ['method' => $method, 'args' => $args];
$server_answer = $this->wait_for_response($int_message_id);
$server_answer = $this->wait_for_response($int_message_id, $method);
} catch (Exception $e) {
$this->log->log('An error occurred while calling method '.$method.': '.$e->getMessage().' in '.basename($e->getFile(), '.php').' on line '.$e->getLine().'. Recreating connection and retrying to call method...');
unset($this->connection);

View File

@ -27,7 +27,7 @@ class RSA extends TL\TL
$this->n = $this->key->modulus;
$this->e = $this->key->exponent;
$this->fp_bytes = substr(sha1($this->serialize_param('bytes', $this->n->toBytes()).$this->serialize_param('bytes', $this->e->toBytes()), true), -8);
$this->fp_bytes = substr(sha1($this->serialize_param('bytes', null, $this->n->toBytes()).$this->serialize_param('bytes', null, $this->e->toBytes()), true), -8);
$this->fp = new \phpseclib\Math\BigInteger(strrev($this->fp_bytes), -256);
}

View File

@ -53,7 +53,7 @@ class TL
}
$bytes_io .= \danog\PHP\Struct::pack('<i', $tl_constructor->id);
foreach ($tl_constructor->params as $arg) {
$bytes_io .= $this->serialize_param($arg['type'], $kwargs[$arg['name']]);
$bytes_io .= $this->serialize_param($arg['type'], $arg['subtype'], $kwargs[$arg['name']]);
}
return $bytes_io;
@ -89,13 +89,16 @@ class TL
}
$bytes_io .= \danog\PHP\Struct::pack('<i', $tl_method->id);
foreach ($tl_method->params as $arg) {
$bytes_io .= $this->serialize_param($arg['type'], $kwargs[$arg['name']]);
if (!isset($arg['subtype'])) {
$arg['subtype'] = null;
}
$bytes_io .= $this->serialize_param($arg['type'], $arg['subtype'], $kwargs[$arg['name']]);
}
return $bytes_io;
}
public function serialize_param($type_, $value)
public function serialize_param($type_, $subtype, $value)
{
switch ($type_) {
case 'int':
@ -108,6 +111,16 @@ class TL
return \danog\PHP\Struct::pack('<i', $value);
break;
case '#':
if (!is_numeric($value)) {
throw new Exception("serialize_param: given value isn't numeric");
}
if (!(strlen(decbin($value)) <= 32)) {
throw new Exception('Given value is too long.');
}
return \danog\PHP\Struct::pack('<I', $value);
break;
case 'long':
if (!is_numeric($value)) {
throw new Exception("serialize_param: given value isn't numeric");
@ -123,6 +136,9 @@ class TL
return $value;
break;
case 'double':
return \danog\PHP\Struct::pack('<d', $value);
break;
case 'string':
case 'bytes':
$l = strlen($value);
@ -140,7 +156,14 @@ class TL
return $concat;
break;
case '!X':
return $value;
case 'Vector t':
$concat = \danog\PHP\Struct::pack('<i', $this->constructor_type["vector"]->id);
foreach ($value as $curv) {
$concat .= $this->serialize_param($subtype, null, $curv);
}
return $concat;
default:
throw new Exception("Couldn't serialize param with type ".$type_);
break;

View File

@ -17,21 +17,26 @@ class TLConstructor
public function __construct($json_dict)
{
$this->id = (int) $json_dict['id'];
$this->type = $json_dict['type'];
$this->predicate = $json_dict['predicate'];
$this->type = $json_dict['type'];
$this->params = [];
foreach ($json_dict['params'] as $param) {
if (($param['type'] == 'Vector<long>')) {
$param['type'] = 'Vector t';
$param['subtype'] = 'long';
} elseif (($param['type'] == 'vector<%Message>')) {
$param['type'] = 'vector';
$param['subtype'] = 'message';
} elseif (($param['type'] == 'vector<future_salt>')) {
$param['type'] = 'vector';
$param['subtype'] = 'future_salt';
} else {
$param['subtype'] = null;
switch ($param['type']) {
case 'Vector<long>':
$param['type'] = 'Vector t';
$param['subtype'] = 'long';
break;
case 'vector<%Message>':
$param['type'] = 'vector';
$param['subtype'] = 'message';
break;
case 'vector<future_salt>':
$param['type'] = 'vector';
$param['subtype'] = 'future_salt';
break;
default:
$param['subtype'] = null;
break;
}
$this->params[] = $param;
}