From 947a1a973f57d1b25339f3c0f80e238f495e7b80 Mon Sep 17 00:00:00 2001 From: danogentili Date: Thu, 17 Nov 2016 13:49:32 +0300 Subject: [PATCH] Cleaned up TL class, cleaned up API and APIFactory class, fixed bugs in the DataCenter class, fixed getting and setting of time deltas. --- src/danog/MadelineProto/API.php | 21 ++--- src/danog/MadelineProto/APIFactory.php | 16 ++-- src/danog/MadelineProto/DataCenter.php | 13 ++- .../MTProtoTools/AuthKeyHandler.php | 4 +- .../MTProtoTools/MsgIdHandler.php | 6 +- src/danog/MadelineProto/TL/TL.php | 84 ++++++++----------- src/danog/MadelineProto/TL/TLConstructor.php | 37 ++++++-- src/danog/MadelineProto/TL/TLMethod.php | 33 ++++++-- testing.php | 8 +- 9 files changed, 123 insertions(+), 99 deletions(-) diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index d6f3424d..4b17a04b 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -14,21 +14,17 @@ namespace danog\MadelineProto; class API extends Tools { - public $session; + public $API; public $settings; public function __construct($params = []) { set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']); - $this->session = new MTProto($params); - $this->settings = &$this->session->settings; + $this->API = new MTProto($params); \danog\MadelineProto\Logger::log('Running APIFactory...'); - foreach ($this->session->tl->method_names_namespaced as $method) { - if (isset($method[1])) { - if (!isset($this->{$method[0]})) { - $this->{$method[0]} = new APIFactory($method[0], $this->session); - } - $this->{$method[0]}->allowed_methods[] = $method[1]; + foreach ($this->API->tl->methods->method_namespaced as $method) { + if (isset($method[1]) && !isset($this->{$method[0]})) { + $this->{$method[0]} = new APIFactory($method[0], $this->API); } } @@ -42,15 +38,12 @@ class API extends Tools public function __destruct() { - unset($this->session); + unset($this->API); restore_error_handler(); } public function __call($name, $arguments) { - if (!in_array($name, $this->session->tl->method_names)) { - throw new Exception("The called method doesn't exist!"); - } - return $this->session->method_call($name, $arguments[0]); + return $this->API->method_call($name, $arguments[0]); } } diff --git a/src/danog/MadelineProto/APIFactory.php b/src/danog/MadelineProto/APIFactory.php index 2f8cf984..5d3a4d84 100644 --- a/src/danog/MadelineProto/APIFactory.php +++ b/src/danog/MadelineProto/APIFactory.php @@ -15,20 +15,16 @@ namespace danog\MadelineProto; class APIFactory { public $namespace; - public $session; - public $allowed_methods = []; + public $API; - public function __construct($namespace, $session) { - $this->namespace = $namespace; - $this->session = $session; + public function __construct($namespace, $API) { + $this->namespace = $namespace.'.'; + $this->API = $API; } public function __call($name, $arguments) { - if (!in_array($name, $this->allowed_methods)) { - throw new Exception("The called method doesn't exist!"); - } - return $this->session->method_call($this->namespace.'.'.$name, $arguments[0]); + return $this->API->method_call($this->namespace.$name, $arguments[0]); } -} \ No newline at end of file +} diff --git a/src/danog/MadelineProto/DataCenter.php b/src/danog/MadelineProto/DataCenter.php index b7ae5e94..f49e3cd6 100644 --- a/src/danog/MadelineProto/DataCenter.php +++ b/src/danog/MadelineProto/DataCenter.php @@ -18,6 +18,7 @@ namespace danog\MadelineProto; class DataCenter extends Tools { public $referenced_variables = ["time_delta", "temp_auth_key", "auth_key", "session_id", "seq_no"]; + public $sockets; public function __construct($dclist, $settings) { @@ -42,10 +43,12 @@ class DataCenter extends Tools public function dc_disconnect($dc_number) { + if ($this->curdc == $dc_number) { + $this->unset_curdc(); + } if (isset($this->sockets[$dc_number])) { \danog\MadelineProto\Logger::log('Disconnecting from DC '.$dc_number.'...'); unset($this->sockets[$dc_number]); - unset($this->curdc); } } @@ -53,7 +56,10 @@ class DataCenter extends Tools { if (isset($this->sockets[$dc_number])) { return false; + $this->set_curdc($dc_number); } + $this->set_curdc($dc_number); + \danog\MadelineProto\Logger::log('Connecting to DC '.$dc_number.'...'); if ($settings == []) { @@ -66,19 +72,18 @@ class DataCenter extends Tools $address = 'https://'.$subdomain.'.web.telegram.org/'.$path; } $this->sockets[$dc_number] = new Connection($address, $settings['port'], $settings['protocol']); - $this->set_curdc($dc_number); return true; } public function set_curdc($dc_number) { $this->curdc = $dc_number; - foreach ($referenced_variables as $key) { + foreach ($this->referenced_variables as $key) { $this->{$key} = &$this->sockets[$dc_number]->{$key}; } } public function unset_curdc($dc_number) { unset($this->curdc); - foreach ($referenced_variables as $key) { + foreach ($this->referenced_variables as $key) { unset($this->sockets[$dc_number]->{$key}); } } diff --git a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php index 97513278..ae1ec7e2 100644 --- a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php @@ -253,9 +253,9 @@ class AuthKeyHandler extends AckHandler * Time delta */ $server_time = $server_DH_inner_data['server_time']; - $this->datacenter->set_time_delta($server_time - time()); + $this->datacenter->time_delta = $server_time - time(); - \danog\MadelineProto\Logger::log(sprintf('Server-client time delta = %.1f s', $this->datacenter->get_time_delta())); + \danog\MadelineProto\Logger::log(sprintf('Server-client time delta = %.1f s', $this->datacenter->time_delta)); /* diff --git a/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php b/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php index e6e5e236..3862722f 100644 --- a/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/MsgIdHandler.php @@ -19,10 +19,10 @@ class MsgIdHandler extends MessageHandler { public function check_message_id($new_message_id, $outgoing, $container = false) { - if (((int) ((time() + $this->datacenter->get_time_delta() - 300) * pow(2, 30)) * 4) > $new_message_id) { + if (((int) ((time() + $this->datacenter->time_delta - 300) * pow(2, 30)) * 4) > $new_message_id) { throw new Exception('Given message id ('.$new_message_id.') is too old.'); } - if (((int) ((time() + $this->datacenter->get_time_delta() + 30) * pow(2, 30)) * 4) < $new_message_id) { + if (((int) ((time() + $this->datacenter->time_delta + 30) * pow(2, 30)) * 4) < $new_message_id) { throw new Exception('Given message id ('.$new_message_id.') is too new.'); } if ($outgoing) { @@ -66,7 +66,7 @@ class MsgIdHandler extends MessageHandler public function generate_message_id() { - $int_message_id = (int) ((time() + $this->datacenter->get_time_delta()) << 32); + $int_message_id = (int) ((time() + $this->datacenter->time_delta) << 32); /* $int_message_id = (int) ( ((int) ($ms_time / 1000) << 32) | ($this->posmod($ms_time, 1000) << 22) | diff --git a/src/danog/MadelineProto/TL/TL.php b/src/danog/MadelineProto/TL/TL.php index 9f059047..808dcc08 100644 --- a/src/danog/MadelineProto/TL/TL.php +++ b/src/danog/MadelineProto/TL/TL.php @@ -16,52 +16,37 @@ class TL extends \danog\MadelineProto\Tools { public function __construct($filename) { - if (is_array($filename)) { - $TL_dict = ['constructors' => [], 'methods' => []]; - foreach ($filename as $file) { - $TL_dict['constructors'] = array_merge(json_decode(file_get_contents($file), true)['constructors'], $TL_dict['constructors']); - $TL_dict['methods'] = array_merge(json_decode(file_get_contents($file), true)['methods'], $TL_dict['methods']); - } - } else { - $TL_dict = json_decode(file_get_contents($filename), true); + \danog\MadelineProto\Logger::log('Loading TL schemes...'); + $TL_dict = ['constructors' => [], 'methods' => []]; + foreach ($filename as $file) { + $TL_dict['constructors'] = array_merge(json_decode(file_get_contents($file), true)['constructors'], $TL_dict['constructors']); + $TL_dict['methods'] = array_merge(json_decode(file_get_contents($file), true)['methods'], $TL_dict['methods']); } \danog\MadelineProto\Logger::log('Translating objects...'); - $this->constructors = $TL_dict['constructors']; - $this->constructor_id = []; - $this->constructor_type = []; - foreach ($this->constructors as $elem) { - $z = new \danog\MadelineProto\TL\TLConstructor($elem); - $this->constructor_id[$z->id] = $z; - $this->constructor_type[$z->predicate] = $z; + $this->constructors = new \danog\MadelineProto\TL\TLConstructor(); + foreach ($TL_dict['constructors'] as $elem) { + $this->constructors->add($elem); } \danog\MadelineProto\Logger::log('Translating methods...'); - $this->methods = $TL_dict['methods']; - $this->method_id = []; - $this->method_name = []; - $this->method_name_namespaced = []; - foreach ($this->methods as $elem) { - $z = new \danog\MadelineProto\TL\TLMethod($elem); - $this->method_id[$z->id] = $z; - $this->method_name[$z->method] = $z; - $this->method_names[$z->method] = $z->method; - $this->method_names_namespaced[$z->method] = explode('.', $z->method); + $this->methods = new \danog\MadelineProto\TL\TLMethod(); + foreach ($TL_dict['methods'] as $elem) { + $this->methods->add($elem); } } public function get_named_method_args($method, $arguments) { - if (!isset($this->method_name[$method])) { + $tl_method = $this->methods->find_by_method($method); + if ($tl_method == false) { throw new Exception('Could not extract type: '.$method); } - $tl_method = $this->method_name[$method]; - if (count(array_filter(array_keys($arguments), 'is_string')) == 0) { $argcount = 0; $newargs = []; - foreach ($tl_method->params as $current_argument) { + foreach ($tl_method['params'] as $current_argument) { $newargs[$current_argument['name']] = $arguments[$argcount++]; } $arguments = $newargs; @@ -72,14 +57,14 @@ class TL extends \danog\MadelineProto\Tools public function serialize_obj($object, $arguments) { - if (!isset($this->constructor_type[$object])) { + $tl_constructor = $this->constructors->find_by_type($object); + if ($tl_constructor == false) { throw new Exception('Could not extract type: '.$object); } - $tl_method = $this->constructor_type[$object]; - $serialized = \danog\PHP\Struct::pack('id); + $serialized = \danog\PHP\Struct::pack('params as $current_argument) { + foreach ($tl_constructor['params'] as $current_argument) { $serialized .= $this->serialize_param($current_argument['type'], $current_argument['subtype'], $arguments[$current_argument['name']]); } @@ -88,14 +73,14 @@ class TL extends \danog\MadelineProto\Tools public function serialize_method($method, $arguments) { - if (!isset($this->method_name[$method])) { + $tl_method = $this->methods->find_by_method($method); + if ($tl_method == false) { throw new Exception('Could not extract type: '.$method); } - $tl_method = $this->method_name[$method]; - $serialized = \danog\PHP\Struct::pack('id); + $serialized = \danog\PHP\Struct::pack('params as $current_argument) { + foreach ($tl_method['params'] as $current_argument) { if (!isset($arguments[$current_argument['name']])) { if ($current_argument['name'] == 'flags') { $arguments['flags'] = 0; @@ -163,7 +148,7 @@ class TL extends \danog\MadelineProto\Tools case '!X': return $value; case 'Vector t': - $concat = \danog\PHP\Struct::pack('constructor_type['vector']->id); + $concat = \danog\PHP\Struct::pack('constructors->find_by_type('vector')['id']); $concat .= \danog\PHP\Struct::pack('constructor_type[$type])) { - $tl_elem = $this->constructor_type[$type]; - } else { - $i = \danog\PHP\Struct::unpack('constructor_id[$i])) { - throw new Exception('Could not extract type: '.$type); + $tl_elem = $this->constructors->find_by_type($type); + if ($tl_elem == false) { + $id = \danog\PHP\Struct::unpack('constructors->find_by_id($id); + if ($tl_elem == false) { + throw new Exception('Could not extract type: '.$type.' with id '.$id); } - $tl_elem = $this->constructor_id[$i]; } $base_boxed_types = ['Vector t', 'Int', 'Long', 'Double', 'String', 'Int128', 'Int256']; - if (in_array($tl_elem->type, $base_boxed_types)) { - $x = $this->deserialize($bytes_io, $tl_elem->predicate, $subtype); + if (in_array($tl_elem['type'], $base_boxed_types)) { + $x = $this->deserialize($bytes_io, $tl_elem['predicate'], $subtype); } else { - $x = ['_' => $tl_elem->predicate]; - foreach ($tl_elem->params as $arg) { + $x = ['_' => $tl_elem['predicate']]; + foreach ($tl_elem['params'] as $arg) { $x[$arg['name']] = $this->deserialize($bytes_io, $arg['type'], $arg['subtype']); } } diff --git a/src/danog/MadelineProto/TL/TLConstructor.php b/src/danog/MadelineProto/TL/TLConstructor.php index a575aec1..a3f86f0b 100644 --- a/src/danog/MadelineProto/TL/TLConstructor.php +++ b/src/danog/MadelineProto/TL/TLConstructor.php @@ -14,13 +14,19 @@ namespace danog\MadelineProto\TL; class TLConstructor { - public function __construct($json_dict) + public $id = []; + public $predicate = []; + public $type = []; + public $params = []; + public $key = 0; + + public function add($json_dict) { - $this->id = (int) $json_dict['id']; - $this->predicate = $json_dict['predicate']; - $this->type = $json_dict['type']; - $this->params = $json_dict['params']; - foreach ($this->params as &$param) { + $this->id[$this->key] = (int) $json_dict['id']; + $this->predicate[$this->key] = $json_dict['predicate']; + $this->type[$this->key] = $json_dict['type']; + $this->params[$this->key] = $json_dict['params']; + foreach ($this->params[$this->key] as &$param) { $param['opt'] = false; $param['subtype'] = null; if (preg_match('/^flags\.\d\?/', $param['type'])) { @@ -42,5 +48,24 @@ class TLConstructor } } } + $this->key++; + } + public function find_by_type($type) { + $key = array_search($type, $this->type); + return ($key == false) ? false : [ + 'id' => $this->id[$key], + 'predicate' => $this->predicate[$key], + 'type' => $this->type[$key], + 'params' => $this->params[$key], + ]; + } + public function find_by_id($id) { + $key = array_search($id, $this->id); + return ($key == false) ? false : [ + 'id' => $this->id[$key], + 'predicate' => $this->predicate[$key], + 'type' => $this->type[$key], + 'params' => $this->params[$key], + ]; } } diff --git a/src/danog/MadelineProto/TL/TLMethod.php b/src/danog/MadelineProto/TL/TLMethod.php index 8d05f8c6..1f9edc90 100644 --- a/src/danog/MadelineProto/TL/TLMethod.php +++ b/src/danog/MadelineProto/TL/TLMethod.php @@ -14,13 +14,22 @@ namespace danog\MadelineProto\TL; class TLMethod { - public function __construct($json_dict) + public $id = []; + public $method = []; + public $type = []; + public $params = []; + public $method_namespaced = []; + public $key = 0; + + public function add($json_dict) { - $this->id = (int) $json_dict['id']; - $this->type = $json_dict['type']; - $this->method = $json_dict['method']; - $this->params = $json_dict['params']; - foreach ($this->params as &$param) { + $this->id[$this->key] = (int) $json_dict['id']; + $this->method[$this->key] = $json_dict['method']; + $this->type[$this->key] = $json_dict['type']; + $this->params[$this->key] = $json_dict['params']; + $this->method_namespaced[$this->key] = explode('.', $json_dict['method']); + + foreach ($this->params[$this->key] as &$param) { $param['opt'] = false; $param['subtype'] = null; if (preg_match('/^flags\.\d\?/', $param['type'])) { @@ -42,5 +51,17 @@ class TLMethod } } } + $this->key++; } + public function find_by_method($method) { + $key = array_search($method, $this->method); + return ($key == false) ? false : [ + 'id' => $this->id[$key], + 'method' => $this->method[$key], + 'type' => $this->type[$key], + 'params' => $this->params[$key], + 'method_namespaced' => $this->method_namespaced[$key], + ]; + } + } diff --git a/testing.php b/testing.php index 85ada4d9..731b68c2 100755 --- a/testing.php +++ b/testing.php @@ -14,16 +14,16 @@ If not, see . require_once 'vendor/autoload.php'; $MadelineProto = new \danog\MadelineProto\API(); - +var_dump(strlen(var_export($MadelineProto,true))); if (file_exists('number.php')) { include_once 'number.php'; $sendCode = $MadelineProto->auth->sendCode( [ 'phone_number' => $number, 'sms_type' => 5, - 'api_id' => $MadelineProto->settings['app_info']['api_id'], - 'api_hash' => $MadelineProto->settings['app_info']['api_hash'], - 'lang_code' => $MadelineProto->settings['app_info']['lang_code'], + 'api_id' => $MadelineProto->API->settings['app_info']['api_id'], + 'api_hash' => $MadelineProto->API->settings['app_info']['api_hash'], + 'lang_code' => $MadelineProto->API->settings['app_info']['lang_code'], ] ); var_dump($sendCode);