Make everything CamelCase

This commit is contained in:
Daniil Gentili 2019-10-29 21:33:23 +01:00
parent a64cfca66c
commit 7a9da5718e
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
86 changed files with 1093 additions and 1091 deletions

View File

@ -46,7 +46,7 @@ class API extends InternalDoc
public function __magic_construct($params = [], $settings = []) public function __magic_construct($params = [], $settings = [])
{ {
Magic::class_exists(); Magic::classExists();
$deferred = new Deferred(); $deferred = new Deferred();
$this->asyncAPIPromise = $deferred->promise(); $this->asyncAPIPromise = $deferred->promise();
$this->asyncAPIPromise->onResolve(function () { $this->asyncAPIPromise->onResolve(function () {
@ -81,7 +81,7 @@ class API extends InternalDoc
} finally { } finally {
$unlock(); $unlock();
} }
\danog\MadelineProto\Magic::class_exists(); \danog\MadelineProto\Magic::classExists();
try { try {
$unserialized = \unserialize($tounserialize); $unserialized = \unserialize($tounserialize);
@ -153,7 +153,7 @@ class API extends InternalDoc
Logger::constructorFromSettings($settings); Logger::constructorFromSettings($settings);
if (!isset($params['app_info']['api_id']) || !$params['app_info']['api_id']) { if (!isset($params['app_info']['api_id']) || !$params['app_info']['api_id']) {
$app = yield $this->api_start_async($params); $app = yield $this->APIStart($params);
$params['app_info']['api_id'] = $app['api_id']; $params['app_info']['api_id'] = $app['api_id'];
$params['app_info']['api_hash'] = $app['api_hash']; $params['app_info']['api_hash'] = $app['api_hash'];
} }
@ -188,7 +188,7 @@ class API extends InternalDoc
public function __destruct() public function __destruct()
{ {
if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread()) || Magic::is_fork()) { if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread()) || Magic::isFork()) {
return; return;
} }
if ($this->asyncInitPromise) { if ($this->asyncInitPromise) {
@ -213,7 +213,7 @@ class API extends InternalDoc
} }
public function my_get_self() public function myGetSelf()
{ {
return isset($this->API) && isset($this->API->authorization['user']) ? $this->API->authorization['user'] : false; return isset($this->API) && isset($this->API->authorization['user']) ? $this->API->authorization['user'] : false;
} }
@ -221,7 +221,7 @@ class API extends InternalDoc
public function APIFactory() public function APIFactory()
{ {
if ($this->API && !$this->API->asyncInitPromise) { if ($this->API && !$this->API->asyncInitPromise) {
foreach ($this->API->get_method_namespaces() as $namespace) { foreach ($this->API->getMethodNamespaces() as $namespace) {
$this->{$namespace} = new APIFactory($namespace, $this->API, $this->async); $this->{$namespace} = new APIFactory($namespace, $this->API, $this->async);
} }
$methods = \get_class_methods($this->API); $methods = \get_class_methods($this->API);
@ -254,7 +254,7 @@ class API extends InternalDoc
if (\strpos($method, '_') !== false) { if (\strpos($method, '_') !== false) {
$this->methods[\strtolower(\str_replace('_', '', $method))] = $actual_method; $this->methods[\strtolower(\str_replace('_', '', $method))] = $actual_method;
} else { } else {
$this->methods[\strtolower(Tools::from_camel_case($method))] = $actual_method; $this->methods[\strtolower(Tools::fromCamelCase($method))] = $actual_method;
} }
} }
@ -265,7 +265,7 @@ class API extends InternalDoc
} }
} }
public function get_all_methods() public function getAllMethods()
{ {
if ($this->asyncInitPromise) { if ($this->asyncInitPromise) {
$this->init(); $this->init();

View File

@ -149,7 +149,7 @@ class APIFactory extends AsyncConstruct
try { try {
$yielded = Tools::wait($yielded); $yielded = Tools::wait($yielded);
Lua::convert_objects($yielded); Lua::convertObjects($yielded);
return $yielded; return $yielded;
} catch (\Throwable $e) { } catch (\Throwable $e) {
@ -163,7 +163,7 @@ class APIFactory extends AsyncConstruct
yield $this->initAsynchronously(); yield $this->initAsynchronously();
$this->API->logger->logger('Finished init asynchronously'); $this->API->logger->logger('Finished init asynchronously');
} }
if (Magic::is_fork() && !Magic::$processed_fork) { if (Magic::isFork() && !Magic::$processed_fork) {
throw new Exception('Forking not supported, use async logic, instead: https://docs.madelineproto.xyz/docs/ASYNC.html'); throw new Exception('Forking not supported, use async logic, instead: https://docs.madelineproto.xyz/docs/ASYNC.html');
} }
if (!$this->API) { if (!$this->API) {
@ -195,7 +195,7 @@ class APIFactory extends AsyncConstruct
$aargs['datacenter'] = $this->API->datacenter->curdc; $aargs['datacenter'] = $this->API->datacenter->curdc;
$args = isset($arguments[0]) && \is_array($arguments[0]) ? $arguments[0] : []; $args = isset($arguments[0]) && \is_array($arguments[0]) ? $arguments[0] : [];
return yield $this->API->method_call_async_read($name, $args, $aargs); return yield $this->API->methodCallAsyncRead($name, $args, $aargs);
} }
return yield $this->methods[$lower_name](...$arguments); return yield $this->methods[$lower_name](...$arguments);
} }

View File

@ -34,7 +34,7 @@ class AnnotationsBuilder
$this->settings = $settings; $this->settings = $settings;
} }
public function mk_annotations() public function mkAnnotations()
{ {
\danog\MadelineProto\Logger::log('Generating annotations...', \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log('Generating annotations...', \danog\MadelineProto\Logger::NOTICE);
$this->setProperties(); $this->setProperties();
@ -62,7 +62,7 @@ class AnnotationsBuilder
} }
} }
} }
foreach ($this->get_method_namespaces() as $namespace) { foreach ($this->getMethodNamespaces() as $namespace) {
$content = \preg_replace('/(class( \\w+[,]?){0,}\\n{\\n)/', '${1}'." /**\n"." * @internal this is a internal property generated by build_docs.php, don't change manually\n"." *\n"." * @var {$namespace}\n"." */\n"." public \${$namespace};\n", $content); $content = \preg_replace('/(class( \\w+[,]?){0,}\\n{\\n)/', '${1}'." /**\n"." * @internal this is a internal property generated by build_docs.php, don't change manually\n"." *\n"." * @var {$namespace}\n"." */\n"." public \${$namespace};\n", $content);
} }
\file_put_contents($filename, $content); \file_put_contents($filename, $content);
@ -92,7 +92,7 @@ class AnnotationsBuilder
continue; continue;
} }
list($namespace, $method) = \explode('.', $data['method']); list($namespace, $method) = \explode('.', $data['method']);
if (!\in_array($namespace, $this->get_method_namespaces())) { if (!\in_array($namespace, $this->getMethodNamespaces())) {
continue; continue;
} }
$internalDoc[$namespace][$method]['title'] = Lang::$current_lang["method_{$data['method']}"] ?? ''; $internalDoc[$namespace][$method]['title'] = Lang::$current_lang["method_{$data['method']}"] ?? '';
@ -170,7 +170,7 @@ class AnnotationsBuilder
$name = \str_ireplace('async', '', $name); $name = \str_ireplace('async', '', $name);
} }
} }
$name = Tools::from_snake_case($name); $name = Tools::fromSnakeCase($name);
$name = \str_ireplace(['mtproto', 'api'], ['MTProto', 'API'], $name); $name = \str_ireplace(['mtproto', 'api'], ['MTProto', 'API'], $name);
$doc = 'public function '; $doc = 'public function ';

View File

@ -37,7 +37,7 @@ class CombinedAPI
public function __magic_construct($session, $paths = []) public function __magic_construct($session, $paths = [])
{ {
\set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']); \set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
\danog\MadelineProto\Magic::class_exists(); \danog\MadelineProto\Magic::classExists();
$realpaths = Serialization::realpaths($session); $realpaths = Serialization::realpaths($session);
$this->session = $realpaths['file']; $this->session = $realpaths['file'];
@ -118,7 +118,7 @@ class CombinedAPI
public function __destruct() public function __destruct()
{ {
if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread()) || Magic::is_fork()) { if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread()) || Magic::isFork()) {
return; return;
} }
@ -200,7 +200,7 @@ class CombinedAPI
} }
} }
public function event_update_handler($update, $instance) public function eventUpdateHandler($update, $instance)
{ {
if (isset($this->event_handler_methods[$update['_']])) { if (isset($this->event_handler_methods[$update['_']])) {
return $this->event_handler_methods[$update['_']]($update, $instance); return $this->event_handler_methods[$update['_']]($update, $instance);
@ -222,7 +222,7 @@ class CombinedAPI
$this->loop_callback = $callback; $this->loop_callback = $callback;
} }
public function get_updates($params = []) public function getUpdates($params = [])
{ {
} }
@ -243,7 +243,7 @@ class CombinedAPI
$instance->API->startUpdateSystem(); $instance->API->startUpdateSystem();
} }
$instance->setCallback(function ($update) use ($path) { $instance->setCallback(function ($update) use ($path) {
return $this->event_update_handler($update, $path); return $this->eventUpdateHandler($update, $path);
}, ['async' => false]); }, ['async' => false]);
if ($this->loop_callback !== null) { if ($this->loop_callback !== null) {
$instance->setLoopCallback($this->loop_callback, ['async' => false]); $instance->setLoopCallback($this->loop_callback, ['async' => false]);

View File

@ -439,9 +439,9 @@ class Connection extends Session
} }
if ($message['method']) { if ($message['method']) {
$body = yield $this->API->serialize_method_async($message['_'], $body); $body = yield $this->API->serializeMethod($message['_'], $body);
} else { } else {
$body = yield $this->API->serialize_object_async(['type' => $message['_']], $body, $message['_']); $body = yield $this->API->serializeObject(['type' => $message['_']], $body, $message['_']);
} }
if ($refresh_next) { if ($refresh_next) {
$this->API->referenceDatabase->refreshNext(false); $this->API->referenceDatabase->refreshNext(false);
@ -558,7 +558,7 @@ class Connection extends Session
{ {
$this->API->logger->logger("Reconnecting DC {$this->datacenterId}"); $this->API->logger->logger("Reconnecting DC {$this->datacenterId}");
$this->disconnect(true); $this->disconnect(true);
yield $this->API->datacenter->dcConnectAsync($this->ctx->getDc(), $this->id); yield $this->API->datacenter->dcConnect($this->ctx->getDc(), $this->id);
} }
/** /**

View File

@ -200,7 +200,7 @@ class DataCenter
$changedSettings = $this->settings !== $settings; $changedSettings = $this->settings !== $settings;
if (!$reconnectAll) { if (!$reconnectAll) {
$changed = []; $changed = [];
$test = ($API->get_cached_config()['test_mode'] ?? false) ? 'test' : 'main'; $test = ($API->getCachedConfig()['test_mode'] ?? false) ? 'test' : 'main';
foreach ($dclist[$test] as $ipv6 => $dcs) { foreach ($dclist[$test] as $ipv6 => $dcs) {
foreach ($dcs as $id => $dc) { foreach ($dcs as $id => $dc) {
if ($dc !== ($this->dclist[$test][$ipv6][$id] ?? [])) { if ($dc !== ($this->dclist[$test][$ipv6][$id] ?? [])) {
@ -234,7 +234,7 @@ class DataCenter
new HttpSocketPool( new HttpSocketPool(
new ProxySocketPool( new ProxySocketPool(
function (string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null) { function (string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null) {
return $this->rawConnectAsync($uri, $token, $ctx, true); return $this->rawConnect($uri, $token, $ctx, true);
} }
) )
) )
@ -493,7 +493,7 @@ class DataCenter
}); });
} }
public function rawConnectAsync(string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null, $fromDns = false): \Generator public function rawConnect(string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null, $fromDns = false): \Generator
{ {
$ctxs = $this->generateContexts(0, $uri, $ctx); $ctxs = $this->generateContexts(0, $uri, $ctx);
if (empty($ctxs)) { if (empty($ctxs)) {
@ -524,7 +524,7 @@ class DataCenter
throw new \danog\MadelineProto\Exception("Could not connect to URI $uri"); throw new \danog\MadelineProto\Exception("Could not connect to URI $uri");
} }
public function dcConnectAsync(string $dc_number, int $id = -1): \Generator public function dcConnect(string $dc_number, int $id = -1): \Generator
{ {
$old = isset($this->sockets[$dc_number]) && ( $old = isset($this->sockets[$dc_number]) && (
$this->sockets[$dc_number]->shouldReconnect() || $this->sockets[$dc_number]->shouldReconnect() ||
@ -958,7 +958,7 @@ class DataCenter
* *
* @return array * @return array
*/ */
public function get_dcs($all = true): array public function getDcs($all = true): array
{ {
$test = $this->settings['all']['test_mode'] ? 'test' : 'main'; $test = $this->settings['all']['test_mode'] ? 'test' : 'main';
$ipv6 = $this->settings['all']['ipv6'] ? 'ipv6' : 'ipv4'; $ipv6 = $this->settings['all']['ipv6'] ? 'ipv6' : 'ipv4';

View File

@ -59,7 +59,7 @@ class DocsBuilder
return \str_replace('_', '\\_', $hwat); return \str_replace('_', '\\_', $hwat);
} }
public function mk_docs() public function mkDocs()
{ {
\danog\MadelineProto\Logger::log('Generating documentation index...', \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log('Generating documentation index...', \danog\MadelineProto\Logger::NOTICE);
\file_put_contents($this->index, '--- \file_put_contents($this->index, '---
@ -78,7 +78,7 @@ image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png
[Types](types/)'); [Types](types/)');
$this->mk_methodS(); $this->mk_methodS();
$this->mk_constructors(); $this->mkConstructors();
foreach (\glob('types/*') as $unlink) { foreach (\glob('types/*') as $unlink) {
\unlink($unlink); \unlink($unlink);
} }
@ -634,7 +634,7 @@ class Lang
public static $current_lang = %s; public static $current_lang = %s;
}'; }';
public function add_to_lang($key) public function addToLang($key)
{ {
if (!isset(\danog\MadelineProto\Lang::$lang['en'][$key])) { if (!isset(\danog\MadelineProto\Lang::$lang['en'][$key])) {
\danog\MadelineProto\Lang::$lang['en'][$key] = ''; \danog\MadelineProto\Lang::$lang['en'][$key] = '';

View File

@ -21,7 +21,7 @@ namespace danog\MadelineProto\DocsBuilder;
trait Constructors trait Constructors
{ {
public function mk_constructors() public function mkConstructors()
{ {
foreach (\glob('constructors/'.$this->any) as $unlink) { foreach (\glob('constructors/'.$this->any) as $unlink) {
\unlink($unlink); \unlink($unlink);
@ -41,7 +41,7 @@ trait Constructors
$got[$id] = ''; $got[$id] = '';
/* /*
if (preg_match('/%/', $type)) { if (preg_match('/%/', $type)) {
$type = $this->constructors->find_by_type(str_replace('%', '', $type))['predicate']; $type = $this->constructors->findByType(str_replace('%', '', $type))['predicate'];
}*/ }*/
$layer = isset($data['layer']) && $data['layer'] !== '' ? '_'.$data['layer'] : ''; $layer = isset($data['layer']) && $data['layer'] !== '' ? '_'.$data['layer'] : '';
$type = \str_replace(['.', '<', '>'], ['_', '_of_', ''], $data['type']); $type = \str_replace(['.', '<', '>'], ['_', '_of_', ''], $data['type']);
@ -67,7 +67,7 @@ trait Constructors
$type_or_bare_type = \ctype_upper($this->end(\explode('.', $param[$type_or_subtype]))[0]) || \in_array($param[$type_or_subtype], ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int53', 'int', 'long', 'int128', 'int256', 'int512']) ? 'types' : 'constructors'; $type_or_bare_type = \ctype_upper($this->end(\explode('.', $param[$type_or_subtype]))[0]) || \in_array($param[$type_or_subtype], ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int53', 'int', 'long', 'int128', 'int256', 'int512']) ? 'types' : 'constructors';
$param[$type_or_subtype] = \str_replace(['.', 'true', 'false'], ['_', 'Bool', 'Bool'], $param[$type_or_subtype]); $param[$type_or_subtype] = \str_replace(['.', 'true', 'false'], ['_', 'Bool', 'Bool'], $param[$type_or_subtype]);
if (\preg_match('/%/', $param[$type_or_subtype])) { if (\preg_match('/%/', $param[$type_or_subtype])) {
$param[$type_or_subtype] = $this->constructors->find_by_type(\str_replace('%', '', $param[$type_or_subtype]))['predicate']; $param[$type_or_subtype] = $this->constructors->findByType(\str_replace('%', '', $param[$type_or_subtype]))['predicate'];
} }
if (\substr($param[$type_or_subtype], -1) === '>') { if (\substr($param[$type_or_subtype], -1) === '>') {
$param[$type_or_subtype] = \substr($param[$type_or_subtype], 0, -1); $param[$type_or_subtype] = \substr($param[$type_or_subtype], 0, -1);
@ -86,7 +86,7 @@ trait Constructors
|----------|---------------|----------| |----------|---------------|----------|
'; ';
if (!isset($this->td_descriptions['constructors'][$data['predicate']])) { if (!isset($this->td_descriptions['constructors'][$data['predicate']])) {
$this->add_to_lang('object_'.$data['predicate']); $this->addToLang('object_'.$data['predicate']);
if (\danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']] !== '') { if (\danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']] !== '') {
$this->td_descriptions['constructors'][$data['predicate']]['description'] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']]; $this->td_descriptions['constructors'][$data['predicate']]['description'] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']];
} }
@ -124,7 +124,7 @@ trait Constructors
} }
}*/ }*/
if (\preg_match('/%/', $ptype)) { if (\preg_match('/%/', $ptype)) {
$ptype = $this->constructors->find_by_type(\str_replace('%', '', $ptype))['predicate']; $ptype = $this->constructors->findByType(\str_replace('%', '', $ptype))['predicate'];
} }
$type_or_bare_type = (\ctype_upper($this->end(\explode('_', $ptype))[0]) || \in_array($ptype, ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int53', 'int', 'long', 'int128', 'int256', 'int512'])) && $ptype !== 'MTmessage' ? 'types' : 'constructors'; $type_or_bare_type = (\ctype_upper($this->end(\explode('_', $ptype))[0]) || \in_array($ptype, ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int53', 'int', 'long', 'int128', 'int256', 'int512'])) && $ptype !== 'MTmessage' ? 'types' : 'constructors';
if (\substr($ptype, -1) === '>') { if (\substr($ptype, -1) === '>') {
@ -154,10 +154,10 @@ trait Constructors
if (\in_array($ptype, ['InputEncryptedFile']) && !isset($this->settings['td'])) { if (\in_array($ptype, ['InputEncryptedFile']) && !isset($this->settings['td'])) {
$human_ptype = 'File path or '.$ptype; $human_ptype = 'File path or '.$ptype;
} }
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || $this->constructors->find_by_predicate(\lcfirst($param['type']).'Empty') || ($data['type'] === 'InputMedia' && $param['name'] === 'mime_type') || ($data['type'] === 'DocumentAttribute' && \in_array($param['name'], ['w', 'h', 'duration'])) ? 'Optional' : 'Yes').'|'; $table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || $this->constructors->findByPredicate(\lcfirst($param['type']).'Empty') || ($data['type'] === 'InputMedia' && $param['name'] === 'mime_type') || ($data['type'] === 'DocumentAttribute' && \in_array($param['name'], ['w', 'h', 'duration'])) ? 'Optional' : 'Yes').'|';
if (!isset($this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']])) { if (!isset($this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']])) {
$this->add_to_lang('object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']); $this->addToLang('object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']);
if (isset($this->td_descriptions['constructors'][$data['predicate']]['description'])) { if (isset($this->td_descriptions['constructors'][$data['predicate']]['description'])) {
$this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']]; $this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']];
} }

View File

@ -21,7 +21,7 @@ namespace danog\MadelineProto\DocsBuilder;
trait Methods trait Methods
{ {
public function mk_methods() public function mkMethods()
{ {
static $bots; static $bots;
if (!$bots) { if (!$bots) {
@ -82,7 +82,7 @@ trait Methods
$params .= "'".$param['name']."' => ".(isset($param['subtype']) ? '\\['.$param[$type_or_subtype].'\\]' : $param[$type_or_subtype]).', '; $params .= "'".$param['name']."' => ".(isset($param['subtype']) ? '\\['.$param[$type_or_subtype].'\\]' : $param[$type_or_subtype]).', ';
} }
if (!isset($this->td_descriptions['methods'][$data['method']])) { if (!isset($this->td_descriptions['methods'][$data['method']])) {
$this->add_to_lang('method_'.$data['method']); $this->addToLang('method_'.$data['method']);
if (\danog\MadelineProto\Lang::$lang['en']['method_'.$data['method']] !== '') { if (\danog\MadelineProto\Lang::$lang['en']['method_'.$data['method']] !== '') {
$this->td_descriptions['methods'][$data['method']]['description'] = \danog\MadelineProto\Lang::$lang['en']['method_'.$data['method']]; $this->td_descriptions['methods'][$data['method']]['description'] = \danog\MadelineProto\Lang::$lang['en']['method_'.$data['method']];
@ -161,16 +161,16 @@ trait Methods
} }
$type_or_bare_type = \ctype_upper($this->end(\explode('.', $param[$type_or_subtype]))[0]) || \in_array($param[$type_or_subtype], ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int', 'long', 'int128', 'int256', 'int512', 'int53']) ? 'types' : 'constructors'; $type_or_bare_type = \ctype_upper($this->end(\explode('.', $param[$type_or_subtype]))[0]) || \in_array($param[$type_or_subtype], ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int', 'long', 'int128', 'int256', 'int512', 'int53']) ? 'types' : 'constructors';
if (!isset($this->td_descriptions['methods'][$data['method']]['params'][$param['name']])) { if (!isset($this->td_descriptions['methods'][$data['method']]['params'][$param['name']])) {
$this->add_to_lang('method_'.$data['method'].'_param_'.$param['name'].'_type_'.$param['type']); $this->addToLang('method_'.$data['method'].'_param_'.$param['name'].'_type_'.$param['type']);
if (isset($this->td_descriptions['methods'][$data['method']]['description'])) { if (isset($this->td_descriptions['methods'][$data['method']]['description'])) {
$this->td_descriptions['methods'][$data['method']]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['method_'.$data['method'].'_param_'.$param['name'].'_type_'.$param['type']]; $this->td_descriptions['methods'][$data['method']]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['method_'.$data['method'].'_param_'.$param['name'].'_type_'.$param['type']];
} }
} }
if (isset($this->td_descriptions['methods'][$data['method']])) { if (isset($this->td_descriptions['methods'][$data['method']])) {
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.$this->td_descriptions['methods'][$data['method']]['params'][$param['name']].' | '.(isset($param['pow']) || (($id = $this->constructors->find_by_predicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->constructors->find_by_predicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|'; $table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.$this->td_descriptions['methods'][$data['method']]['params'][$param['name']].' | '.(isset($param['pow']) || (($id = $this->constructors->findByPredicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->constructors->findByPredicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|';
} else { } else {
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || (($id = $this->constructors->find_by_predicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->constructors->find_by_predicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|'; $table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || (($id = $this->constructors->findByPredicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->constructors->findByPredicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|';
} }
$table .= PHP_EOL; $table .= PHP_EOL;
$pptype = \in_array($ptype, ['string', 'bytes']) ? "'".$ptype."'" : $ptype; $pptype = \in_array($ptype, ['string', 'bytes']) ? "'".$ptype."'" : $ptype;

View File

@ -29,7 +29,7 @@ class EventHandler extends InternalDoc
$this->API = $MadelineProto->API; $this->API = $MadelineProto->API;
$this->async = &$MadelineProto->async; $this->async = &$MadelineProto->async;
$this->methods = &$MadelineProto->methods; $this->methods = &$MadelineProto->methods;
foreach ($this->API->get_method_namespaces() as $namespace) { foreach ($this->API->getMethodNamespaces() as $namespace) {
$this->{$namespace} = new APIFactory($namespace, $this->API, $this->async); $this->{$namespace} = new APIFactory($namespace, $this->API, $this->async);
} }
} }

View File

@ -31,7 +31,7 @@ class Exception extends \Exception
public function __construct($message = null, $code = 0, self $previous = null, $file = null, $line = null) public function __construct($message = null, $code = 0, self $previous = null, $file = null, $line = null)
{ {
$this->prettify_tl(); $this->prettifyTl();
if ($file !== null) { if ($file !== null) {
$this->file = $file; $this->file = $file;
} }
@ -75,7 +75,7 @@ class Exception extends \Exception
* *
* Error handler * Error handler
*/ */
public static function ExceptionErrorHandler($errno = 0, $errstr = null, $errfile = null, $errline = null) public static function exceptionErrorHandler($errno = 0, $errstr = null, $errfile = null, $errline = null)
{ {
// If error is suppressed with @, don't throw an exception // If error is suppressed with @, don't throw an exception
if (\error_reporting() === 0 || \strpos($errstr, 'headers already sent') || ($errfile && \strpos($errfile, 'vendor/amphp') !== false)) { if (\error_reporting() === 0 || \strpos($errstr, 'headers already sent') || ($errfile && \strpos($errfile, 'vendor/amphp') !== false)) {
@ -90,7 +90,7 @@ class Exception extends \Exception
* *
* Error handler * Error handler
*/ */
public static function ExceptionHandler($exception) public static function exceptionHandler($exception)
{ {
Logger::log($exception, Logger::FATAL_ERROR); Logger::log($exception, Logger::FATAL_ERROR);
Magic::shutdown(1); Magic::shutdown(1);

View File

@ -74,7 +74,7 @@ class CheckLoop extends ResumableSignalLoop
} }
if ($connection->hasPendingCalls()) { if ($connection->hasPendingCalls()) {
$last_msgid = $connection->get_max_id(true); $last_msgid = $connection->getMaxId(true);
$last_chunk = $connection->getLastChunk(); $last_chunk = $connection->getLastChunk();
if ($shared->hasTempAuthKey()) { if ($shared->hasTempAuthKey()) {
@ -109,11 +109,11 @@ class CheckLoop extends ResumableSignalLoop
case 2: case 2:
case 3: case 3:
if ($connection->outgoing_messages[$message_id]['_'] === 'msgs_state_req') { if ($connection->outgoing_messages[$message_id]['_'] === 'msgs_state_req') {
$connection->got_response_for_outgoing_message_id($message_id); $connection->gotResponseForOutgoingMessageId($message_id);
break; break;
} }
$API->logger->logger('Message '.$connection->outgoing_messages[$message_id]['_'].' with message ID '.($message_id).' not received by server, resending...', \danog\MadelineProto\Logger::ERROR); $API->logger->logger('Message '.$connection->outgoing_messages[$message_id]['_'].' with message ID '.($message_id).' not received by server, resending...', \danog\MadelineProto\Logger::ERROR);
$connection->method_recall('watcherId', ['message_id' => $message_id, 'postpone' => true]); $connection->methodRecall('watcherId', ['message_id' => $message_id, 'postpone' => true]);
break; break;
case 4: case 4:
if ($chr & 32) { if ($chr & 32) {
@ -131,7 +131,7 @@ class CheckLoop extends ResumableSignalLoop
} }
} }
if ($reply) { if ($reply) {
$this->callFork($connection->object_call_async('msg_resend_ans_req', ['msg_ids' => $reply], ['postpone' => true])); $this->callFork($connection->objectCall('msg_resend_ans_req', ['msg_ids' => $reply], ['postpone' => true]));
} }
$connection->flush(); $connection->flush();
} }
@ -142,7 +142,7 @@ class CheckLoop extends ResumableSignalLoop
$list .= $connection->outgoing_messages[$message_id]['_'].', '; $list .= $connection->outgoing_messages[$message_id]['_'].', ';
} }
$API->logger->logger("Still missing $list on DC $datacenter, sending state request", \danog\MadelineProto\Logger::ERROR); $API->logger->logger("Still missing $list on DC $datacenter, sending state request", \danog\MadelineProto\Logger::ERROR);
yield $connection->object_call_async('msgs_state_req', ['msg_ids' => $message_ids], ['promise' => $deferred]); yield $connection->objectCall('msgs_state_req', ['msg_ids' => $message_ids], ['promise' => $deferred]);
} }
} else { } else {
foreach ($connection->new_outgoing as $message_id) { foreach ($connection->new_outgoing as $message_id) {
@ -151,7 +151,7 @@ class CheckLoop extends ResumableSignalLoop
&& $connection->outgoing_messages[$message_id]['unencrypted'] && $connection->outgoing_messages[$message_id]['unencrypted']
) { ) {
$API->logger->logger('Still missing '.$connection->outgoing_messages[$message_id]['_'].' with message id '.($message_id)." on DC $datacenter, resending", \danog\MadelineProto\Logger::ERROR); $API->logger->logger('Still missing '.$connection->outgoing_messages[$message_id]['_'].' with message id '.($message_id)." on DC $datacenter, resending", \danog\MadelineProto\Logger::ERROR);
$connection->method_recall('', ['message_id' => $message_id, 'postpone' => true]); $connection->methodRecall('', ['message_id' => $message_id, 'postpone' => true]);
} }
} }
$connection->flush(); $connection->flush();
@ -160,7 +160,7 @@ class CheckLoop extends ResumableSignalLoop
return; return;
} }
if ($connection->get_max_id(true) === $last_msgid && $connection->getLastChunk() === $last_chunk) { if ($connection->getMaxId(true) === $last_msgid && $connection->getLastChunk() === $last_chunk) {
$API->logger->logger("We did not receive a response for $timeout seconds: reconnecting and exiting check loop on DC $datacenter"); $API->logger->logger("We did not receive a response for $timeout seconds: reconnecting and exiting check loop on DC $datacenter");
//$this->exitedLoop(); //$this->exitedLoop();
Tools::callForkDefer($connection->reconnect()); Tools::callForkDefer($connection->reconnect());

View File

@ -76,7 +76,7 @@ class PingLoop extends ResumableSignalLoop
if (\time() - $connection->getLastChunk() >= $timeout) { if (\time() - $connection->getLastChunk() >= $timeout) {
$API->logger->logger("Ping DC $datacenter"); $API->logger->logger("Ping DC $datacenter");
try { try {
yield $connection->method_call_async_read('ping', ['ping_id' => \random_bytes(8)]); yield $connection->methodCallAsyncRead('ping', ['ping_id' => \random_bytes(8)]);
} catch (\Throwable $e) { } catch (\Throwable $e) {
$API->logger->logger("Error while pinging DC $datacenter"); $API->logger->logger("Error while pinging DC $datacenter");
$API->logger->logger((string) $e); $API->logger->logger((string) $e);

View File

@ -101,7 +101,7 @@ class ReadLoop extends SignalLoop
$connection->outgoing_messages[$message_id]['sent'] = 0; $connection->outgoing_messages[$message_id]['sent'] = 0;
} }
yield $shared->reconnect(); yield $shared->reconnect();
yield $API->init_authorization_async(); yield $API->initAuthorization();
} else { } else {
yield $connection->reconnect(); yield $connection->reconnect();
} }
@ -163,7 +163,7 @@ class ReadLoop extends SignalLoop
} }
if ($payload_length === 4) { if ($payload_length === 4) {
$payload = $this->unpack_signed_int(yield $buffer->bufferRead(4)); $payload = $this->unpackSignedInt(yield $buffer->bufferRead(4));
$API->logger->logger("Received $payload from DC ".$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger("Received $payload from DC ".$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE);
return $payload; return $payload;
@ -176,7 +176,7 @@ class ReadLoop extends SignalLoop
if ($auth_key_id === "\0\0\0\0\0\0\0\0") { if ($auth_key_id === "\0\0\0\0\0\0\0\0") {
$message_id = yield $buffer->bufferRead(8); $message_id = yield $buffer->bufferRead(8);
if (!\in_array($message_id, [1, 0])) { if (!\in_array($message_id, [1, 0])) {
$connection->check_message_id($message_id, ['outgoing' => false, 'container' => false]); $connection->checkMessageId($message_id, ['outgoing' => false, 'container' => false]);
} }
$message_length = \unpack('V', yield $buffer->bufferRead(4))[1]; $message_length = \unpack('V', yield $buffer->bufferRead(4))[1];
$message_data = yield $buffer->bufferRead($message_length); $message_data = yield $buffer->bufferRead($message_length);
@ -191,14 +191,14 @@ class ReadLoop extends SignalLoop
$connection->incoming_messages[$message_id] = []; $connection->incoming_messages[$message_id] = [];
} elseif ($auth_key_id === $shared->getTempAuthKey()->getID()) { } elseif ($auth_key_id === $shared->getTempAuthKey()->getID()) {
$message_key = yield $buffer->bufferRead(16); $message_key = yield $buffer->bufferRead(16);
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, $shared->getTempAuthKey()->getAuthKey(), false); list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $shared->getTempAuthKey()->getAuthKey(), false);
$encrypted_data = yield $buffer->bufferRead($payload_length - 24); $encrypted_data = yield $buffer->bufferRead($payload_length - 24);
$protocol_padding = \strlen($encrypted_data) % 16; $protocol_padding = \strlen($encrypted_data) % 16;
if ($protocol_padding) { if ($protocol_padding) {
$encrypted_data = \substr($encrypted_data, 0, -$protocol_padding); $encrypted_data = \substr($encrypted_data, 0, -$protocol_padding);
} }
$decrypted_data = $this->ige_decrypt($encrypted_data, $aes_key, $aes_iv); $decrypted_data = $this->igeDecrypt($encrypted_data, $aes_key, $aes_iv);
/* /*
$server_salt = substr($decrypted_data, 0, 8); $server_salt = substr($decrypted_data, 0, 8);
if ($server_salt != $shared->getTempAuthKey()->getServerSalt()) { if ($server_salt != $shared->getTempAuthKey()->getServerSalt()) {
@ -212,7 +212,7 @@ class ReadLoop extends SignalLoop
throw new NothingInTheSocketException(); throw new NothingInTheSocketException();
} }
$message_id = \substr($decrypted_data, 16, 8); $message_id = \substr($decrypted_data, 16, 8);
$connection->check_message_id($message_id, ['outgoing' => false, 'container' => false]); $connection->checkMessageId($message_id, ['outgoing' => false, 'container' => false]);
$seq_no = \unpack('V', \substr($decrypted_data, 24, 4))[1]; $seq_no = \unpack('V', \substr($decrypted_data, 24, 4))[1];
$message_data_length = \unpack('V', \substr($decrypted_data, 28, 4))[1]; $message_data_length = \unpack('V', \substr($decrypted_data, 28, 4))[1];

View File

@ -113,7 +113,7 @@ class WriteLoop extends ResumableSignalLoop
} }
} }
public function unencryptedWriteLoopAsync() public function unencryptedWriteLoop()
{ {
$API = $this->API; $API = $this->API;
$datacenter = $this->datacenter; $datacenter = $this->datacenter;
@ -133,16 +133,16 @@ class WriteLoop extends ResumableSignalLoop
$API->logger->logger("Sending {$message['_']} as unencrypted message to DC {$datacenter}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger("Sending {$message['_']} as unencrypted message to DC {$datacenter}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$message_id = isset($message['msg_id']) ? $message['msg_id'] : $connection->generate_message_id(); $message_id = isset($message['msg_id']) ? $message['msg_id'] : $connection->generateMessageId();
$length = \strlen($message['serialized_body']); $length = \strlen($message['serialized_body']);
$pad_length = -$length & 15; $pad_length = -$length & 15;
$pad_length += 16 * $this->random_int($modulus = 16); $pad_length += 16 * $this->randomInt($modulus = 16);
$pad = $this->random($pad_length); $pad = $this->random($pad_length);
$buffer = yield $connection->stream->getWriteBuffer(8 + 8 + 4 + $pad_length + $length); $buffer = yield $connection->stream->getWriteBuffer(8 + 8 + 4 + $pad_length + $length);
yield $buffer->bufferWrite("\0\0\0\0\0\0\0\0".$message_id.$this->pack_unsigned_int($length).$message['serialized_body'].$pad); yield $buffer->bufferWrite("\0\0\0\0\0\0\0\0".$message_id.$this->packUnsignedInt($length).$message['serialized_body'].$pad);
//var_dump("plain ".bin2hex($message_id)); //var_dump("plain ".bin2hex($message_id));
$connection->httpSent(); $connection->httpSent();
@ -165,7 +165,7 @@ class WriteLoop extends ResumableSignalLoop
} }
} }
public function encryptedWriteLoopAsync(): \Generator public function encryptedWriteLoop(): \Generator
{ {
$API = $this->API; $API = $this->API;
$datacenter = $this->datacenter; $datacenter = $this->datacenter;
@ -182,7 +182,7 @@ class WriteLoop extends ResumableSignalLoop
$temporary_keys = []; $temporary_keys = [];
if (\count($to_ack = $connection->ack_queue)) { if (\count($to_ack = $connection->ack_queue)) {
foreach (\array_chunk($connection->ack_queue, 8192) as $acks) { foreach (\array_chunk($connection->ack_queue, 8192) as $acks) {
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'msgs_ack', 'serialized_body' => yield $this->API->serialize_object_async(['type' => 'msgs_ack'], ['msg_ids' => $acks], 'msgs_ack'), 'content_related' => false, 'unencrypted' => false, 'method' => false]; $connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'msgs_ack', 'serialized_body' => yield $this->API->serializeObject(['type' => 'msgs_ack'], ['msg_ids' => $acks], 'msgs_ack'), 'content_related' => false, 'unencrypted' => false, 'method' => false];
$temporary_keys[$connection->pending_outgoing_key] = true; $temporary_keys[$connection->pending_outgoing_key] = true;
$API->logger->logger("Adding msgs_ack {$connection->pending_outgoing_key}", Logger::ULTRA_VERBOSE); $API->logger->logger("Adding msgs_ack {$connection->pending_outgoing_key}", Logger::ULTRA_VERBOSE);
$connection->pending_outgoing_key++; $connection->pending_outgoing_key++;
@ -200,7 +200,7 @@ class WriteLoop extends ResumableSignalLoop
} }
if ($shared->isHttp() && !$has_http_wait) { if ($shared->isHttp() && !$has_http_wait) {
$API->logger->logger("Adding http_wait {$connection->pending_outgoing_key}", Logger::ULTRA_VERBOSE); $API->logger->logger("Adding http_wait {$connection->pending_outgoing_key}", Logger::ULTRA_VERBOSE);
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'http_wait', 'serialized_body' => yield $this->API->serialize_object_async(['type' => ''], ['_' => 'http_wait', 'max_wait' => 30000, 'wait_after' => 0, 'max_delay' => 0], 'http_wait'), 'content_related' => true, 'unencrypted' => false, 'method' => true]; $connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'http_wait', 'serialized_body' => yield $this->API->serializeObject(['type' => ''], ['_' => 'http_wait', 'max_wait' => 30000, 'wait_after' => 0, 'max_delay' => 0], 'http_wait'), 'content_related' => true, 'unencrypted' => false, 'method' => true];
$temporary_keys[$connection->pending_outgoing_key] = true; $temporary_keys[$connection->pending_outgoing_key] = true;
$connection->pending_outgoing_key++; $connection->pending_outgoing_key++;
} }
@ -230,21 +230,21 @@ class WriteLoop extends ResumableSignalLoop
break; break;
} }
$message_id = isset($message['msg_id']) ? $message['msg_id'] : $connection->generate_message_id(); $message_id = isset($message['msg_id']) ? $message['msg_id'] : $connection->generateMessageId();
$API->logger->logger("Sending {$message['_']} as encrypted message to DC {$datacenter}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger("Sending {$message['_']} as encrypted message to DC {$datacenter}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$MTmessage = ['_' => 'MTmessage', 'msg_id' => $message_id, 'body' => $message['serialized_body'], 'seqno' => $connection->generate_out_seq_no($message['content_related'])]; $MTmessage = ['_' => 'MTmessage', 'msg_id' => $message_id, 'body' => $message['serialized_body'], 'seqno' => $connection->generateOutSeqNo($message['content_related'])];
if (isset($message['method']) && $message['method'] && $message['_'] !== 'http_wait') { if (isset($message['method']) && $message['method'] && $message['_'] !== 'http_wait') {
if (!$shared->getTempAuthKey()->isInited() && $message['_'] !== 'auth.bindTempAuthKey' && !$inited) { if (!$shared->getTempAuthKey()->isInited() && $message['_'] !== 'auth.bindTempAuthKey' && !$inited) {
$inited = true; $inited = true;
$API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $message['_']), \danog\MadelineProto\Logger::NOTICE); $API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $message['_']), \danog\MadelineProto\Logger::NOTICE);
$MTmessage['body'] = yield $API->serialize_method_async( $MTmessage['body'] = yield $API->serializeMethod(
'invokeWithLayer', 'invokeWithLayer',
[ [
'layer' => $API->settings['tl_schema']['layer'], 'layer' => $API->settings['tl_schema']['layer'],
'query' => yield $API->serialize_method_async( 'query' => yield $API->serializeMethod(
'initConnection', 'initConnection',
[ [
'api_id' => $API->settings['app_info']['api_id'], 'api_id' => $API->settings['app_info']['api_id'],
@ -266,7 +266,7 @@ class WriteLoop extends ResumableSignalLoop
if (!isset($connection->call_queue[$message['queue']])) { if (!isset($connection->call_queue[$message['queue']])) {
$connection->call_queue[$message['queue']] = []; $connection->call_queue[$message['queue']] = [];
} }
$MTmessage['body'] = yield $API->serialize_method_async('invokeAfterMsgs', ['msg_ids' => $connection->call_queue[$message['queue']], 'query' => $MTmessage['body']]); $MTmessage['body'] = yield $API->serializeMethod('invokeAfterMsgs', ['msg_ids' => $connection->call_queue[$message['queue']], 'query' => $MTmessage['body']]);
$connection->call_queue[$message['queue']][$message_id] = $message_id; $connection->call_queue[$message['queue']][$message_id] = $message_id;
if (\count($connection->call_queue[$message['queue']]) > $API->settings['msg_array_limit']['call_queue']) { if (\count($connection->call_queue[$message['queue']]) > $API->settings['msg_array_limit']['call_queue']) {
@ -278,7 +278,7 @@ class WriteLoop extends ResumableSignalLoop
// TODO // TODO
/* if ($API->settings['requests']['gzip_encode_if_gt'] !== -1 && ($l = strlen($MTmessage['body'])) > $API->settings['requests']['gzip_encode_if_gt']) { /* if ($API->settings['requests']['gzip_encode_if_gt'] !== -1 && ($l = strlen($MTmessage['body'])) > $API->settings['requests']['gzip_encode_if_gt']) {
if (($g = strlen($gzipped = gzencode($MTmessage['body']))) < $l) { if (($g = strlen($gzipped = gzencode($MTmessage['body']))) < $l) {
$MTmessage['body'] = yield $API->serialize_object_async(['type' => 'gzip_packed'], ['packed_data' => $gzipped], 'gzipped data'); $MTmessage['body'] = yield $API->serializeObject(['type' => 'gzip_packed'], ['packed_data' => $gzipped], 'gzipped data');
$API->logger->logger('Using GZIP compression for ' . $message['_'] . ', saved ' . ($l - $g) . ' bytes of data, reduced call size by ' . $g * 100 / $l . '%', \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger('Using GZIP compression for ' . $message['_'] . ', saved ' . ($l - $g) . ' bytes of data, reduced call size by ' . $g * 100 / $l . '%', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
} }
unset($gzipped); unset($gzipped);
@ -311,16 +311,16 @@ class WriteLoop extends ResumableSignalLoop
if ($count > 1) { if ($count > 1) {
$API->logger->logger("Wrapping in msg_container ($count messages of total size $total_length) as encrypted message for DC {$datacenter}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger("Wrapping in msg_container ($count messages of total size $total_length) as encrypted message for DC {$datacenter}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$message_id = $connection->generate_message_id(); $message_id = $connection->generateMessageId();
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'msg_container', 'container' => \array_values($keys), 'content_related' => false, 'method' => false, 'unencrypted' => false]; $connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'msg_container', 'container' => \array_values($keys), 'content_related' => false, 'method' => false, 'unencrypted' => false];
//var_dumP("container ".bin2hex($message_id)); //var_dumP("container ".bin2hex($message_id));
$keys[$connection->pending_outgoing_key++] = $message_id; $keys[$connection->pending_outgoing_key++] = $message_id;
$message_data = yield $API->serialize_object_async(['type' => ''], ['_' => 'msg_container', 'messages' => $messages], 'container'); $message_data = yield $API->serializeObject(['type' => ''], ['_' => 'msg_container', 'messages' => $messages], 'container');
$message_data_length = \strlen($message_data); $message_data_length = \strlen($message_data);
$seq_no = $connection->generate_out_seq_no(false); $seq_no = $connection->generateOutSeqNo(false);
} elseif ($count) { } elseif ($count) {
$message = $messages[0]; $message = $messages[0];
$message_data = $message['body']; $message_data = $message['body'];
@ -342,8 +342,8 @@ class WriteLoop extends ResumableSignalLoop
} }
$padding = $this->random($padding); $padding = $this->random($padding);
$message_key = \substr(\hash('sha256', \substr($shared->getTempAuthKey()->getAuthKey(), 88, 32).$plaintext.$padding, true), 8, 16); $message_key = \substr(\hash('sha256', \substr($shared->getTempAuthKey()->getAuthKey(), 88, 32).$plaintext.$padding, true), 8, 16);
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, $shared->getTempAuthKey()->getAuthKey()); list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $shared->getTempAuthKey()->getAuthKey());
$message = $shared->getTempAuthKey()->getID().$message_key.$this->ige_encrypt($plaintext.$padding, $aes_key, $aes_iv); $message = $shared->getTempAuthKey()->getID().$message_key.$this->igeEncrypt($plaintext.$padding, $aes_key, $aes_iv);
$buffer = yield $connection->stream->getWriteBuffer($len = \strlen($message)); $buffer = yield $connection->stream->getWriteBuffer($len = \strlen($message));

View File

@ -59,7 +59,7 @@ class FeedLoop extends ResumableSignalLoop
return; return;
} }
} }
$this->state = $this->channelId === false ? (yield $API->load_update_state_async()) : $API->loadChannelState($this->channelId); $this->state = $this->channelId === false ? (yield $API->loadUpdateState()) : $API->loadChannelState($this->channelId);
while (true) { while (true) {
while (!$this->API->settings['updates']['handle_updates'] || !$API->hasAllAuth()) { while (!$this->API->settings['updates']['handle_updates'] || !$API->hasAllAuth()) {
@ -84,7 +84,7 @@ class FeedLoop extends ResumableSignalLoop
$parsedUpdates = $this->parsedUpdates; $parsedUpdates = $this->parsedUpdates;
$this->parsedUpdates = []; $this->parsedUpdates = [];
foreach ($parsedUpdates as $update) { foreach ($parsedUpdates as $update) {
yield $API->save_update_async($update); yield $API->saveUpdate($update);
} }
$parsedUpdates = null; $parsedUpdates = null;
$this->API->signalUpdate(); $this->API->signalUpdate();
@ -128,7 +128,7 @@ class FeedLoop extends ResumableSignalLoop
continue; continue;
} }
if (isset($update['message']['id'], $update['message']['to_id']) && !\in_array($update['_'], ['updateEditMessage', 'updateEditChannelMessage', 'updateMessageID'])) { if (isset($update['message']['id'], $update['message']['to_id']) && !\in_array($update['_'], ['updateEditMessage', 'updateEditChannelMessage', 'updateMessageID'])) {
if (!$this->API->check_msg_id($update['message'])) { if (!$this->API->checkMsgId($update['message'])) {
$logger('MSGID duplicate'); $logger('MSGID duplicate');
continue; continue;
@ -201,11 +201,11 @@ class FeedLoop extends ResumableSignalLoop
$via_bot = false; $via_bot = false;
$entities = false; $entities = false;
if ($update['message']['_'] !== 'messageEmpty' && ( if ($update['message']['_'] !== 'messageEmpty' && (
($from = isset($update['message']['from_id']) && !yield $this->API->peer_isset_async($update['message']['from_id'])) || ($from = isset($update['message']['from_id']) && !yield $this->API->peerIsset($update['message']['from_id'])) ||
($to = !yield $this->API->peer_isset_async($update['message']['to_id'])) || ($to = !yield $this->API->peerIsset($update['message']['to_id'])) ||
($via_bot = isset($update['message']['via_bot_id']) && !yield $this->API->peer_isset_async($update['message']['via_bot_id'])) || ($via_bot = isset($update['message']['via_bot_id']) && !yield $this->API->peerIsset($update['message']['via_bot_id'])) ||
($entities = isset($update['message']['entities']) && !yield $this->API->entities_peer_isset_async($update['message']['entities'])) // || ($entities = isset($update['message']['entities']) && !yield $this->API->entitiesPeerIsset($update['message']['entities'])) // ||
//isset($update['message']['fwd_from']) && !yield $this->fwd_peer_isset_async($update['message']['fwd_from']) //isset($update['message']['fwd_from']) && !yield $this->fwdPeerIsset($update['message']['fwd_from'])
)) { )) {
$log = ''; $log = '';
if ($from) { if ($from) {
@ -232,7 +232,7 @@ class FeedLoop extends ResumableSignalLoop
} }
break; break;
default: default:
if ($channelId && !yield $this->API->peer_isset_async($this->API->to_supergroup($channelId))) { if ($channelId && !yield $this->API->peerIsset($this->API->toSupergroup($channelId))) {
$this->API->logger->logger('Skipping update, I do not have the channel id '.$channelId, \danog\MadelineProto\Logger::ERROR); $this->API->logger->logger('Skipping update, I do not have the channel id '.$channelId, \danog\MadelineProto\Logger::ERROR);
return false; return false;
@ -261,7 +261,7 @@ class FeedLoop extends ResumableSignalLoop
public function saveMessages($messages) public function saveMessages($messages)
{ {
foreach ($messages as $message) { foreach ($messages as $message) {
if (!$this->API->check_msg_id($message)) { if (!$this->API->checkMsgId($message)) {
$this->API->logger->logger("MSGID duplicate ({$message['id']}) in $this"); $this->API->logger->logger("MSGID duplicate ({$message['id']}) in $this");
continue; continue;

View File

@ -51,7 +51,7 @@ class SeqLoop extends ResumableSignalLoop
return; return;
} }
} }
$this->state = yield $API->load_update_state_async(); $this->state = yield $API->loadUpdateState();
while (true) { while (true) {
while (!$this->API->settings['updates']['handle_updates'] || !$API->hasAllAuth()) { while (!$this->API->settings['updates']['handle_updates'] || !$API->hasAllAuth()) {

View File

@ -54,7 +54,7 @@ class UpdateLoop extends ResumableSignalLoop
return; return;
} }
} }
$this->state = $state = $this->channelId === false ? (yield $API->load_update_state_async()) : $API->loadChannelState($this->channelId); $this->state = $state = $this->channelId === false ? (yield $API->loadUpdateState()) : $API->loadChannelState($this->channelId);
$timeout = $API->settings['updates']['getdifference_interval']; $timeout = $API->settings['updates']['getdifference_interval'];
$first = true; $first = true;
@ -82,7 +82,7 @@ class UpdateLoop extends ResumableSignalLoop
$request_pts = $state->pts(); $request_pts = $state->pts();
try { try {
$difference = yield $API->method_call_async_read('updates.getChannelDifference', ['channel' => 'channel#'.$this->channelId, 'filter' => ['_' => 'channelMessagesFilterEmpty'], 'pts' => $request_pts, 'limit' => $limit, 'force' => true], ['datacenter' => $API->datacenter->curdc, 'postpone' => $first]); $difference = yield $API->methodCallAsyncRead('updates.getChannelDifference', ['channel' => 'channel#'.$this->channelId, 'filter' => ['_' => 'channelMessagesFilterEmpty'], 'pts' => $request_pts, 'limit' => $limit, 'force' => true], ['datacenter' => $API->datacenter->curdc, 'postpone' => $first]);
} catch (RPCErrorException $e) { } catch (RPCErrorException $e) {
if (\in_array($e->rpc, ['CHANNEL_PRIVATE', 'CHAT_FORBIDDEN', 'CHANNEL_INVALID'])) { if (\in_array($e->rpc, ['CHANNEL_PRIVATE', 'CHAT_FORBIDDEN', 'CHANNEL_INVALID'])) {
$feeder->signal(true); $feeder->signal(true);
@ -149,7 +149,7 @@ class UpdateLoop extends ResumableSignalLoop
} else { } else {
$API->logger->logger('Resumed and fetching normal difference...', \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger('Resumed and fetching normal difference...', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$difference = yield $API->method_call_async_read('updates.getDifference', ['pts' => $state->pts(), 'date' => $state->date(), 'qts' => $state->qts()], ['datacenter' => $API->settings['connection_settings']['default_dc']]); $difference = yield $API->methodCallAsyncRead('updates.getDifference', ['pts' => $state->pts(), 'date' => $state->date(), 'qts' => $state->qts()], ['datacenter' => $API->settings['connection_settings']['default_dc']]);
$API->logger->logger('Got '.$difference['_'], \danog\MadelineProto\Logger::ULTRA_VERBOSE); $API->logger->logger('Got '.$difference['_'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
switch ($difference['_']) { switch ($difference['_']) {
case 'updates.differenceEmpty': case 'updates.differenceEmpty':

View File

@ -55,7 +55,7 @@ class Lua
$this->Lua->registerCallback($method, [$this->MadelineProto, $method]); $this->Lua->registerCallback($method, [$this->MadelineProto, $method]);
} }
$methods = []; $methods = [];
foreach ($this->MadelineProto->get_methods_namespaced() as $pair) { foreach ($this->MadelineProto->getMethodsNamespaced() as $pair) {
$namespace = \key($pair); $namespace = \key($pair);
$method = $pair[$namespace]; $method = $pair[$namespace];
if ($namespace === 'upload') { if ($namespace === 'upload') {
@ -63,7 +63,7 @@ class Lua
} }
$methods[$namespace][$method] = [$this->MadelineProto->{$namespace}, $method]; $methods[$namespace][$method] = [$this->MadelineProto->{$namespace}, $method];
} }
foreach ($this->MadelineProto->get_methods_namespaced() as $pair) { foreach ($this->MadelineProto->getMethodsNamespaced() as $pair) {
$namespace = \key($pair); $namespace = \key($pair);
$method = $pair[$namespace]; $method = $pair[$namespace];
if ($namespace === 'upload') { if ($namespace === 'upload') {
@ -72,19 +72,19 @@ class Lua
$this->{$namespace} = $methods[$namespace]; $this->{$namespace} = $methods[$namespace];
} }
$this->MadelineProto->lua = true; $this->MadelineProto->lua = true;
foreach ($this->MadelineProto->get_methods_namespaced() as $pair) { foreach ($this->MadelineProto->getMethodsNamespaced() as $pair) {
$namespace = \key($pair); $namespace = \key($pair);
$this->MadelineProto->{$namespace}->lua = true; $this->MadelineProto->{$namespace}->lua = true;
} }
} }
public function tdcli_function($params, $cb = null, $cb_extra = null) public function tdcliFunction($params, $cb = null, $cb_extra = null)
{ {
$params = $this->MadelineProto->td_to_mtproto($this->MadelineProto->tdcli_to_td($params)); $params = $this->MadelineProto->td_to_mtproto($this->MadelineProto->tdcliToTd($params));
if ($params === 0) { if ($params === 0) {
return 0; return 0;
} }
$result = $this->MadelineProto->API->method_call($params['_'], $params, ['datacenter' => $this->MadelineProto->API->datacenter->curdc]); $result = $this->MadelineProto->API->methodCall($params['_'], $params, ['datacenter' => $this->MadelineProto->API->datacenter->curdc]);
if (\is_callable($cb)) { if (\is_callable($cb)) {
$cb($this->MadelineProto->mtproto_to_td($result), $cb_extra); $cb($this->MadelineProto->mtproto_to_td($result), $cb_extra);
} }
@ -92,23 +92,23 @@ class Lua
return $result; return $result;
} }
public function madeline_function($params, $cb = null, $cb_extra = null) public function madelineFunction($params, $cb = null, $cb_extra = null)
{ {
$result = $this->MadelineProto->API->method_call($params['_'], $params, ['datacenter' => $this->MadelineProto->API->datacenter->curdc]); $result = $this->MadelineProto->API->methodCall($params['_'], $params, ['datacenter' => $this->MadelineProto->API->datacenter->curdc]);
if (\is_callable($cb)) { if (\is_callable($cb)) {
$cb($result, $cb_extra); $cb($result, $cb_extra);
} }
self::convert_objects($result); self::convertObjects($result);
return $result; return $result;
} }
public function tdcli_update_callback($update) public function tdcliUpdateCallback($update)
{ {
$this->Lua->tdcli_update_callback($this->MadelineProto->mtproto_to_tdcli($update)); $this->Lua->tdcliUpdateCallback($this->MadelineProto->mtproto_to_tdcli($update));
} }
private function convert_array($array) private function convertArray($array)
{ {
if (!\is_array($array)) { if (!\is_array($array)) {
return $array; return $array;
@ -120,7 +120,7 @@ class Lua
} }
} }
private function is_sequential(array $arr) private function isSequential(array $arr)
{ {
if ([] === $arr) { if ([] === $arr) {
return false; return false;
@ -140,7 +140,7 @@ class Lua
public function __call($name, $params) public function __call($name, $params)
{ {
self::convert_objects($params); self::convertObjects($params);
try { try {
return $this->Lua->{$name}(...$params); return $this->Lua->{$name}(...$params);
@ -166,7 +166,7 @@ class Lua
return $this->Lua->{$name} = $value; return $this->Lua->{$name} = $value;
} }
public static function convert_objects(&$data) public static function convertObjects(&$data)
{ {
\array_walk_recursive($data, function (&$value, $key) { \array_walk_recursive($data, function (&$value, $key) {
if (\is_object($value) && !$value instanceof \phpseclib\Math\BigInteger) { if (\is_object($value) && !$value instanceof \phpseclib\Math\BigInteger) {

View File

@ -431,9 +431,9 @@ class MTProto extends AsyncConstruct implements TLCallback
*/ */
public function __construct_async($settings = []) public function __construct_async($settings = [])
{ {
\danog\MadelineProto\Magic::class_exists(); \danog\MadelineProto\Magic::classExists();
// Parse settings // Parse settings
$this->parse_settings($settings); $this->parseSettings($settings);
// Connect to servers // Connect to servers
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['inst_dc'], Logger::ULTRA_VERBOSE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['inst_dc'], Logger::ULTRA_VERBOSE);
if (!($this->channels_state instanceof CombinedUpdatesState)) { if (!($this->channels_state instanceof CombinedUpdatesState)) {
@ -472,12 +472,12 @@ class MTProto extends AsyncConstruct implements TLCallback
$callbacks []= $this->minDatabase; $callbacks []= $this->minDatabase;
} }
$this->construct_TL($this->settings['tl_schema']['src'], $callbacks); $this->construct_TL($this->settings['tl_schema']['src'], $callbacks);
yield $this->connect_to_all_dcs_async(); yield $this->connectToAllDcs();
$this->startLoops(); $this->startLoops();
$this->datacenter->curdc = 2; $this->datacenter->curdc = 2;
if ((!isset($this->authorization['user']['bot']) || !$this->authorization['user']['bot']) && $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->hasTempAuthKey()) { if ((!isset($this->authorization['user']['bot']) || !$this->authorization['user']['bot']) && $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->hasTempAuthKey()) {
try { try {
$nearest_dc = yield $this->method_call_async_read('help.getNearestDc', [], ['datacenter' => $this->datacenter->curdc]); $nearest_dc = yield $this->methodCallAsyncRead('help.getNearestDc', [], ['datacenter' => $this->datacenter->curdc]);
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['nearest_dc'], $nearest_dc['country'], $nearest_dc['nearest_dc']), Logger::NOTICE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['nearest_dc'], $nearest_dc['country'], $nearest_dc['nearest_dc']), Logger::NOTICE);
if ($nearest_dc['nearest_dc'] != $nearest_dc['this_dc']) { if ($nearest_dc['nearest_dc'] != $nearest_dc['this_dc']) {
$this->settings['connection_settings']['default_dc'] = $this->datacenter->curdc = (int) $nearest_dc['nearest_dc']; $this->settings['connection_settings']['default_dc'] = $this->datacenter->curdc = (int) $nearest_dc['nearest_dc'];
@ -488,7 +488,7 @@ class MTProto extends AsyncConstruct implements TLCallback
} }
} }
} }
yield $this->get_config_async([], ['datacenter' => $this->datacenter->curdc]); yield $this->getConfig([], ['datacenter' => $this->datacenter->curdc]);
$this->startUpdateSystem(true); $this->startUpdateSystem(true);
$this->v = self::V; $this->v = self::V;
} }
@ -514,7 +514,7 @@ class MTProto extends AsyncConstruct implements TLCallback
if (!($this->authorization['user']['bot'] ?? false)) { if (!($this->authorization['user']['bot'] ?? false)) {
$callbacks []= $this->minDatabase; $callbacks []= $this->minDatabase;
} }
$this->update_callbacks($callbacks); $this->updateCallbacks($callbacks);
return $this; return $this;
} }
@ -641,7 +641,7 @@ class MTProto extends AsyncConstruct implements TLCallback
public function __wakeup_async($backtrace) public function __wakeup_async($backtrace)
{ {
\set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']); \set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
$this->setup_logger(); $this->setupLogger();
if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread())) { if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread())) {
return; return;
} }
@ -659,7 +659,7 @@ class MTProto extends AsyncConstruct implements TLCallback
if (!($this->authorization['user']['bot'] ?? false)) { if (!($this->authorization['user']['bot'] ?? false)) {
$callbacks []= $this->minDatabase; $callbacks []= $this->minDatabase;
} }
$this->update_callbacks($callbacks); $this->updateCallbacks($callbacks);
$this->settings['connection_settings']['all']['ipv6'] = \danog\MadelineProto\Magic::$ipv6; $this->settings['connection_settings']['all']['ipv6'] = \danog\MadelineProto\Magic::$ipv6;
/*if (isset($this->settings['pwr']['update_handler']) && $this->settings['pwr']['update_handler'] === $this->settings['updates']['callback']) { /*if (isset($this->settings['pwr']['update_handler']) && $this->settings['pwr']['update_handler'] === $this->settings['updates']['callback']) {
@ -697,7 +697,7 @@ class MTProto extends AsyncConstruct implements TLCallback
$this->resetMTProtoSession(); $this->resetMTProtoSession();
if (isset($backtrace[2]['function'], $backtrace[2]['class'], $backtrace[2]['args']) && $backtrace[2]['class'] === 'danog\\MadelineProto\\API' && $backtrace[2]['function'] === '__construct_async') { if (isset($backtrace[2]['function'], $backtrace[2]['class'], $backtrace[2]['args']) && $backtrace[2]['class'] === 'danog\\MadelineProto\\API' && $backtrace[2]['function'] === '__construct_async') {
if (\count($backtrace[2]['args']) >= 2) { if (\count($backtrace[2]['args']) >= 2) {
$this->parse_settings(\array_replace_recursive($this->settings, $backtrace[2]['args'][1])); $this->parseSettings(\array_replace_recursive($this->settings, $backtrace[2]['args'][1]));
} }
} }
@ -780,7 +780,7 @@ class MTProto extends AsyncConstruct implements TLCallback
foreach ($this->secret_chats as $chat => $data) { foreach ($this->secret_chats as $chat => $data) {
try { try {
if (isset($this->secret_chats[$chat]) && $this->secret_chats[$chat]['InputEncryptedChat'] !== null) { if (isset($this->secret_chats[$chat]) && $this->secret_chats[$chat]['InputEncryptedChat'] !== null) {
yield $this->notify_layer_async($chat); yield $this->notifyLayer($chat);
} }
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
} }
@ -792,7 +792,7 @@ class MTProto extends AsyncConstruct implements TLCallback
$this->msg_ids = []; $this->msg_ids = [];
$this->got_state = false; $this->got_state = false;
}*/ }*/
yield $this->connect_to_all_dcs_async(); yield $this->connectToAllDcs();
foreach ($this->calls as $id => $controller) { foreach ($this->calls as $id => $controller) {
if (!\is_object($controller)) { if (!\is_object($controller)) {
unset($this->calls[$id]); unset($this->calls[$id]);
@ -804,17 +804,17 @@ class MTProto extends AsyncConstruct implements TLCallback
} }
} }
$this->startLoops(); $this->startLoops();
if (yield $this->get_self_async()) { if (yield $this->getSelf()) {
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
} }
if ($this->authorized === self::LOGGED_IN) { if ($this->authorized === self::LOGGED_IN) {
yield $this->get_cdn_config_async($this->datacenter->curdc); yield $this->getCdnConfig($this->datacenter->curdc);
$this->setup_logger(); $this->setupLogger();
} }
$this->startUpdateSystem(true); $this->startUpdateSystem(true);
if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot'] && $this->settings['peer']['cache_all_peers_on_startup']) { if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot'] && $this->settings['peer']['cache_all_peers_on_startup']) {
yield $this->get_dialogs_async($force); yield $this->getDialogs($force);
} }
if ($this->authorized === self::LOGGED_IN && $this->settings['updates']['handle_updates']) { if ($this->authorized === self::LOGGED_IN && $this->settings['updates']['handle_updates']) {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getupdates_deserialization'], Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getupdates_deserialization'], Logger::NOTICE);
@ -850,7 +850,7 @@ class MTProto extends AsyncConstruct implements TLCallback
public static function getSettings($settings, $previousSettings = []) public static function getSettings($settings, $previousSettings = [])
{ {
Magic::class_exists(); Magic::classExists();
if (isset($previousSettings['connection_settings']['default_dc'])) { if (isset($previousSettings['connection_settings']['default_dc'])) {
$settings['connection_settings']['default_dc'] = $previousSettings['connection_settings']['default_dc']; $settings['connection_settings']['default_dc'] = $previousSettings['connection_settings']['default_dc'];
} }
@ -1175,7 +1175,7 @@ class MTProto extends AsyncConstruct implements TLCallback
} }
return $settings; return $settings;
} }
public function parse_settings($settings) public function parseSettings($settings)
{ {
$settings = self::getSettings($settings, $this->settings); $settings = self::getSettings($settings, $this->settings);
if ($settings['app_info'] === null) { if ($settings['app_info'] === null) {
@ -1186,10 +1186,10 @@ class MTProto extends AsyncConstruct implements TLCallback
$this->updates = []; $this->updates = [];
} }
// Setup logger // Setup logger
$this->setup_logger(); $this->setupLogger();
} }
public function setup_logger() public function setupLogger()
{ {
$this->logger = Logger::getLoggerFromSettings($this->settings, isset($this->authorization['user']) ? isset($this->authorization['user']['username']) ? $this->authorization['user']['username'] : $this->authorization['user']['id'] : ''); $this->logger = Logger::getLoggerFromSettings($this->settings, isset($this->authorization['user']) ? isset($this->authorization['user']['username']) ? $this->authorization['user']['username'] : $this->authorization['user']['id'] : '');
} }
@ -1230,7 +1230,7 @@ class MTProto extends AsyncConstruct implements TLCallback
} }
// Connects to all datacenters and if necessary creates authorization keys, binds them and writes client info // Connects to all datacenters and if necessary creates authorization keys, binds them and writes client info
public function connect_to_all_dcs_async(bool $reconnectAll = true): \Generator public function connectToAllDcs(bool $reconnectAll = true): \Generator
{ {
$this->channels_state->get(false); $this->channels_state->get(false);
foreach ($this->channels_state->get() as $state) { foreach ($this->channels_state->get() as $state) {
@ -1248,21 +1248,21 @@ class MTProto extends AsyncConstruct implements TLCallback
$this->datacenter->__construct($this, $this->settings['connection'], $this->settings['connection_settings'], $reconnectAll); $this->datacenter->__construct($this, $this->settings['connection'], $this->settings['connection_settings'], $reconnectAll);
$dcs = []; $dcs = [];
foreach ($this->datacenter->get_dcs() as $new_dc) { foreach ($this->datacenter->getDcs() as $new_dc) {
$dcs[] = $this->datacenter->dcConnectAsync($new_dc); $dcs[] = $this->datacenter->dcConnect($new_dc);
} }
yield $this->all($dcs); yield $this->all($dcs);
yield $this->init_authorization_async(); yield $this->initAuthorization();
yield $this->parse_config_async(); yield $this->parseConfig();
$dcs = []; $dcs = [];
foreach ($this->datacenter->get_dcs(false) as $new_dc) { foreach ($this->datacenter->getDcs(false) as $new_dc) {
$dcs[] = $this->datacenter->dcConnectAsync($new_dc); $dcs[] = $this->datacenter->dcConnect($new_dc);
} }
yield $this->all($dcs); yield $this->all($dcs);
yield $this->init_authorization_async(); yield $this->initAuthorization();
yield $this->parse_config_async(); yield $this->parseConfig();
yield $this->get_phone_config_async(); yield $this->getPhoneConfig();
} }
public function resetSession() public function resetSession()
{ {
@ -1371,25 +1371,25 @@ class MTProto extends AsyncConstruct implements TLCallback
} }
} }
public function get_phone_config_async($watcherId = null) public function getPhoneConfig($watcherId = null)
{ {
if ($this->authorized === self::LOGGED_IN && \class_exists(VoIPServerConfigInternal::class) && !$this->authorization['user']['bot'] && $this->datacenter->getDataCenterConnection($this->settings['connection_settings']['default_dc'])->hasTempAuthKey()) { if ($this->authorized === self::LOGGED_IN && \class_exists(VoIPServerConfigInternal::class) && !$this->authorization['user']['bot'] && $this->datacenter->getDataCenterConnection($this->settings['connection_settings']['default_dc'])->hasTempAuthKey()) {
$this->logger->logger('Fetching phone config...'); $this->logger->logger('Fetching phone config...');
VoIPServerConfig::updateDefault(yield $this->method_call_async_read('phone.getCallConfig', [], ['datacenter' => $this->settings['connection_settings']['default_dc']])); VoIPServerConfig::updateDefault(yield $this->methodCallAsyncRead('phone.getCallConfig', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]));
} else { } else {
$this->logger->logger('Not fetching phone config'); $this->logger->logger('Not fetching phone config');
} }
} }
public function get_cdn_config_async($datacenter) public function getCdnConfig($datacenter)
{ {
/* /*
* *********************************************************************** * ***********************************************************************
* Fetch RSA keys for CDN datacenters * Fetch RSA keys for CDN datacenters
*/ */
try { try {
foreach ((yield $this->method_call_async_read('help.getCdnConfig', [], ['datacenter' => $datacenter]))['public_keys'] as $curkey) { foreach ((yield $this->methodCallAsyncRead('help.getCdnConfig', [], ['datacenter' => $datacenter]))['public_keys'] as $curkey) {
$tempkey = new \danog\MadelineProto\RSA($curkey['public_key']); $tempkey = new \danog\MadelineProto\RSA($curkey['public_key']);
$this->cdn_rsa_keys[$tempkey->fp] = $tempkey; $this->cdn_rsa_keys[$tempkey->fp] = $tempkey;
} }
@ -1398,34 +1398,34 @@ class MTProto extends AsyncConstruct implements TLCallback
} }
} }
public function get_cached_config() public function getCachedConfig()
{ {
return $this->config; return $this->config;
} }
public function get_config_async($config = [], $options = []) public function getConfig($config = [], $options = [])
{ {
if ($this->config['expires'] > \time()) { if ($this->config['expires'] > \time()) {
return $this->config; return $this->config;
} }
$this->config = empty($config) ? yield $this->method_call_async_read('help.getConfig', $config, empty($options) ? ['datacenter' => $this->settings['connection_settings']['default_dc']] : $options) : $config; $this->config = empty($config) ? yield $this->methodCallAsyncRead('help.getConfig', $config, empty($options) ? ['datacenter' => $this->settings['connection_settings']['default_dc']] : $options) : $config;
yield $this->parse_config_async(); yield $this->parseConfig();
return $this->config; return $this->config;
} }
public function parse_config_async() public function parseConfig()
{ {
if (isset($this->config['dc_options'])) { if (isset($this->config['dc_options'])) {
$options = $this->config['dc_options']; $options = $this->config['dc_options'];
unset($this->config['dc_options']); unset($this->config['dc_options']);
yield $this->parse_dc_options_async($options); yield $this->parseDcOptions($options);
} }
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['config_updated'], Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['config_updated'], Logger::NOTICE);
$this->logger->logger($this->config, Logger::NOTICE); $this->logger->logger($this->config, Logger::NOTICE);
} }
public function parse_dc_options_async($dc_options) public function parseDcOptions($dc_options)
{ {
foreach ($dc_options as $dc) { foreach ($dc_options as $dc) {
$test = $this->config['test_mode'] ? 'test' : 'main'; $test = $this->config['test_mode'] ? 'test' : 'main';
@ -1449,15 +1449,15 @@ class MTProto extends AsyncConstruct implements TLCallback
$curdc = $this->datacenter->curdc; $curdc = $this->datacenter->curdc;
if (!$this->datacenter->has($curdc) || $this->datacenter->getDataCenterConnection($curdc)->byIPAddress()) { if (!$this->datacenter->has($curdc) || $this->datacenter->getDataCenterConnection($curdc)->byIPAddress()) {
$this->logger->logger('Got new DC options, reconnecting'); $this->logger->logger('Got new DC options, reconnecting');
yield $this->connect_to_all_dcs_async(false); yield $this->connectToAllDcs(false);
} }
$this->datacenter->curdc = $curdc; $this->datacenter->curdc = $curdc;
} }
public function get_self_async() public function getSelf()
{ {
try { try {
$this->authorization = ['user' => (yield $this->method_call_async_read('users.getUsers', ['id' => [['_' => 'inputUserSelf']]], ['datacenter' => $this->datacenter->curdc]))[0]]; $this->authorization = ['user' => (yield $this->methodCallAsyncRead('users.getUsers', ['id' => [['_' => 'inputUserSelf']]], ['datacenter' => $this->datacenter->curdc]))[0]];
} catch (RPCErrorException $e) { } catch (RPCErrorException $e) {
$this->logger->logger($e->getMessage()); $this->logger->logger($e->getMessage());

View File

@ -24,7 +24,7 @@ namespace danog\MadelineProto\MTProtoSession;
*/ */
trait AckHandler trait AckHandler
{ {
public function ack_outgoing_message_id($message_id): bool public function ackOutgoingMessageId($message_id): bool
{ {
// The server acknowledges that it received my message // The server acknowledges that it received my message
if (!isset($this->outgoing_messages[$message_id])) { if (!isset($this->outgoing_messages[$message_id])) {
@ -43,7 +43,7 @@ trait AckHandler
return true; return true;
} }
public function got_response_for_outgoing_message_id($message_id): bool public function gotResponseForOutgoingMessageId($message_id): bool
{ {
// The server acknowledges that it received my message // The server acknowledges that it received my message
if (!isset($this->outgoing_messages[$message_id])) { if (!isset($this->outgoing_messages[$message_id])) {
@ -64,7 +64,7 @@ trait AckHandler
return true; return true;
} }
public function ack_incoming_message_id($message_id): bool public function ackIncomingMessageId($message_id): bool
{ {
// I let the server know that I received its message // I let the server know that I received its message
if (!isset($this->incoming_messages[$message_id])) { if (!isset($this->incoming_messages[$message_id])) {

View File

@ -40,7 +40,7 @@ trait CallHandler
* *
* @return void * @return void
*/ */
public function method_recall(string $watcherId, array $args) public function methodRecall(string $watcherId, array $args)
{ {
$message_id = $args['message_id']; $message_id = $args['message_id'];
$postpone = $args['postpone'] ?? false; $postpone = $args['postpone'] ?? false;
@ -59,8 +59,8 @@ trait CallHandler
$res = $this->sendMessage($this->outgoing_messages[$message_id], false); $res = $this->sendMessage($this->outgoing_messages[$message_id], false);
} }
$this->callFork($res); $this->callFork($res);
$this->ack_outgoing_message_id($message_id); $this->ackOutgoingMessageId($message_id);
$this->got_response_for_outgoing_message_id($message_id); $this->gotResponseForOutgoingMessageId($message_id);
} else { } else {
$this->logger->logger('Could not resend '.(isset($this->outgoing_messages[$message_id]['_']) ? $this->outgoing_messages[$message_id]['_'] : $message_id)); $this->logger->logger('Could not resend '.(isset($this->outgoing_messages[$message_id]['_']) ? $this->outgoing_messages[$message_id]['_'] : $message_id));
} }
@ -85,10 +85,10 @@ trait CallHandler
* *
* @return Promise * @return Promise
*/ */
public function method_call_async_read(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise public function methodCallAsyncRead(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise
{ {
$deferred = new Deferred(); $deferred = new Deferred();
$this->method_call_async_write($method, $args, $aargs)->onResolve(function ($e, $read_deferred) use ($deferred) { $this->methodCallAsyncWrite($method, $args, $aargs)->onResolve(function ($e, $read_deferred) use ($deferred) {
if ($e) { if ($e) {
$deferred->fail($e); $deferred->fail($e);
} else { } else {
@ -118,9 +118,9 @@ trait CallHandler
* *
* @return Promise * @return Promise
*/ */
public function method_call_async_write(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise public function methodCallAsyncWrite(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise
{ {
return $this->call($this->method_call_async_write_generator($method, $args, $aargs)); return $this->call($this->methodCallAsyncWriteGenerator($method, $args, $aargs));
} }
/** /**
@ -132,7 +132,7 @@ trait CallHandler
* *
* @return Generator * @return Generator
*/ */
public function method_call_async_write_generator(string $method, $args = [], array $aargs = ['msg_id' => null]): \Generator public function methodCallAsyncWriteGenerator(string $method, $args = [], array $aargs = ['msg_id' => null]): \Generator
{ {
if (\is_array($args) if (\is_array($args)
&& isset($args['id']['_']) && isset($args['id']['_'])
@ -140,11 +140,11 @@ trait CallHandler
&& $args['id']['_'] === 'inputBotInlineMessageID' && $args['id']['_'] === 'inputBotInlineMessageID'
&& $this->datacenter !== $args['id']['dc_id'] && $this->datacenter !== $args['id']['dc_id']
) { ) {
return yield $this->API->datacenter->getConnection($args['id']['dc_id'])->method_call_async_write_generator($method, $args, $aargs); return yield $this->API->datacenter->getConnection($args['id']['dc_id'])->methodCallAsyncWriteGenerator($method, $args, $aargs);
} }
if (($aargs['file'] ?? false) && !$this->isMedia() && $this->API->datacenter->has($this->datacenter.'_media')) { if (($aargs['file'] ?? false) && !$this->isMedia() && $this->API->datacenter->has($this->datacenter.'_media')) {
$this->logger->logger('Using media DC'); $this->logger->logger('Using media DC');
return yield $this->API->datacenter->getConnection($this->datacenter.'_media')->method_call_async_write_generator($method, $args, $aargs); return yield $this->API->datacenter->getConnection($this->datacenter.'_media')->methodCallAsyncWriteGenerator($method, $args, $aargs);
} }
if (\in_array($method, ['messages.setEncryptedTyping', 'messages.readEncryptedHistory', 'messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService', 'messages.receivedQueue'])) { if (\in_array($method, ['messages.setEncryptedTyping', 'messages.readEncryptedHistory', 'messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService', 'messages.receivedQueue'])) {
$aargs['queue'] = 'secret'; $aargs['queue'] = 'secret';
@ -154,8 +154,8 @@ trait CallHandler
if (isset($args['multiple'])) { if (isset($args['multiple'])) {
$aargs['multiple'] = true; $aargs['multiple'] = true;
} }
if (isset($args['message']) && \is_string($args['message']) && \mb_strlen($args['message'], 'UTF-8') > (yield $this->API->get_config_async())['message_length_max'] && \mb_strlen((yield $this->API->parse_mode_async($args))['message'], 'UTF-8') > (yield $this->API->get_config_async())['message_length_max']) { if (isset($args['message']) && \is_string($args['message']) && \mb_strlen($args['message'], 'UTF-8') > (yield $this->API->getConfig())['message_length_max'] && \mb_strlen((yield $this->API->parseMode($args))['message'], 'UTF-8') > (yield $this->API->getConfig())['message_length_max']) {
$args = yield $this->API->split_to_chunks_async($args); $args = yield $this->API->splitToChunks($args);
$promises = []; $promises = [];
$aargs['queue'] = $method; $aargs['queue'] = $method;
$aargs['multiple'] = true; $aargs['multiple'] = true;
@ -169,7 +169,7 @@ trait CallHandler
unset($args['multiple']); unset($args['multiple']);
} }
foreach ($args as $single_args) { foreach ($args as $single_args) {
$promises[] = $this->method_call_async_write($method, $single_args, $new_aargs); $promises[] = $this->methodCallAsyncWrite($method, $single_args, $new_aargs);
} }
if (!isset($aargs['postpone'])) { if (!isset($aargs['postpone'])) {
@ -178,9 +178,9 @@ trait CallHandler
return yield all($promises); return yield all($promises);
} }
$args = yield $this->API->botAPI_to_MTProto_async($args); $args = yield $this->API->botAPIToMTProto($args);
if (isset($args['ping_id']) && \is_int($args['ping_id'])) { if (isset($args['ping_id']) && \is_int($args['ping_id'])) {
$args['ping_id'] = Tools::pack_signed_long($args['ping_id']); $args['ping_id'] = Tools::packSignedLong($args['ping_id']);
} }
} }
@ -189,8 +189,8 @@ trait CallHandler
$aargs, $aargs,
[ [
'_' => $method, '_' => $method,
'type' => $this->API->methods->find_by_method($method)['type'], 'type' => $this->API->methods->findByMethod($method)['type'],
'content_related' => $this->content_related($method), 'content_related' => $this->contentRelated($method),
'promise' => $deferred, 'promise' => $deferred,
'method' => true, 'method' => true,
'unencrypted' => !$this->shared->hasTempAuthKey() && \strpos($method, '.') === false 'unencrypted' => !$this->shared->hasTempAuthKey() && \strpos($method, '.') === false
@ -223,9 +223,9 @@ trait CallHandler
* *
* @return Promise * @return Promise
*/ */
public function object_call_async(string $object, $args = [], array $aargs = ['msg_id' => null]): \Generator public function objectCall(string $object, $args = [], array $aargs = ['msg_id' => null]): \Generator
{ {
$message = ['_' => $object, 'body' => $args, 'content_related' => $this->content_related($object), 'unencrypted' => !$this->shared->hasTempAuthKey(), 'method' => false]; $message = ['_' => $object, 'body' => $args, 'content_related' => $this->contentRelated($object), 'unencrypted' => !$this->shared->hasTempAuthKey(), 'method' => false];
if (isset($aargs['promise'])) { if (isset($aargs['promise'])) {
$message['promise'] = $aargs['promise']; $message['promise'] = $aargs['promise'];
} }

View File

@ -27,7 +27,7 @@ trait MsgIdHandler
public $max_incoming_id; public $max_incoming_id;
public $max_outgoing_id; public $max_outgoing_id;
public function check_message_id($new_message_id, $aargs) public function checkMessageId($new_message_id, $aargs)
{ {
if (!\is_object($new_message_id)) { if (!\is_object($new_message_id)) {
$new_message_id = new \phpseclib\Math\BigInteger(\strrev($new_message_id), 256); $new_message_id = new \phpseclib\Math\BigInteger(\strrev($new_message_id), 256);
@ -44,7 +44,7 @@ trait MsgIdHandler
if (!$new_message_id->divide(\danog\MadelineProto\Magic::$four)[1]->equals(\danog\MadelineProto\Magic::$zero)) { if (!$new_message_id->divide(\danog\MadelineProto\Magic::$four)[1]->equals(\danog\MadelineProto\Magic::$zero)) {
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is not divisible by 4. Consider syncing your date.'); throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is not divisible by 4. Consider syncing your date.');
} }
if (!\danog\MadelineProto\Magic::$has_thread && $new_message_id->compare($key = $this->get_max_id($incoming = false)) <= 0) { if (!\danog\MadelineProto\Magic::$has_thread && $new_message_id->compare($key = $this->getMaxId($incoming = false)) <= 0) {
throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.'). Consider syncing your date.', 1); throw new \danog\MadelineProto\Exception('Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.'). Consider syncing your date.', 1);
} }
if (\count($this->outgoing_messages) > $this->API->settings['msg_array_limit']['outgoing']) { if (\count($this->outgoing_messages) > $this->API->settings['msg_array_limit']['outgoing']) {
@ -60,13 +60,13 @@ trait MsgIdHandler
if (!$new_message_id->divide(\danog\MadelineProto\Magic::$four)[1]->equals(\danog\MadelineProto\Magic::$one) && !$new_message_id->divide(\danog\MadelineProto\Magic::$four)[1]->equals(\danog\MadelineProto\Magic::$three)) { if (!$new_message_id->divide(\danog\MadelineProto\Magic::$four)[1]->equals(\danog\MadelineProto\Magic::$one) && !$new_message_id->divide(\danog\MadelineProto\Magic::$four)[1]->equals(\danog\MadelineProto\Magic::$three)) {
throw new \danog\MadelineProto\Exception('message id mod 4 != 1 or 3'); throw new \danog\MadelineProto\Exception('message id mod 4 != 1 or 3');
} }
$key = $this->get_max_id($incoming = true); $key = $this->getMaxId($incoming = true);
if ($aargs['container']) { if ($aargs['container']) {
if ($new_message_id->compare($key = $this->get_max_id($incoming = true)) >= 0) { if ($new_message_id->compare($key = $this->getMaxId($incoming = true)) >= 0) {
$this->API->logger->logger('WARNING: Given message id ('.$new_message_id.') is bigger than or equal to the current limit ('.$key.'). Consider syncing your date.', \danog\MadelineProto\Logger::WARNING); $this->API->logger->logger('WARNING: Given message id ('.$new_message_id.') is bigger than or equal to the current limit ('.$key.'). Consider syncing your date.', \danog\MadelineProto\Logger::WARNING);
} }
} else { } else {
if ($new_message_id->compare($key = $this->get_max_id($incoming = true)) <= 0) { if ($new_message_id->compare($key = $this->getMaxId($incoming = true)) <= 0) {
$this->API->logger->logger('WARNING: Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.'). Consider syncing your date.', \danog\MadelineProto\Logger::WARNING); $this->API->logger->logger('WARNING: Given message id ('.$new_message_id.') is lower than or equal to the current limit ('.$key.'). Consider syncing your date.', \danog\MadelineProto\Logger::WARNING);
} }
} }
@ -82,18 +82,18 @@ trait MsgIdHandler
} }
} }
public function generate_message_id() public function generateMessageId()
{ {
$message_id = (new \phpseclib\Math\BigInteger(\time() + $this->time_delta))->bitwise_leftShift(32); $message_id = (new \phpseclib\Math\BigInteger(\time() + $this->time_delta))->bitwise_leftShift(32);
if ($message_id->compare($key = $this->get_max_id($incoming = false)) <= 0) { if ($message_id->compare($key = $this->getMaxId($incoming = false)) <= 0) {
$message_id = $key->add(\danog\MadelineProto\Magic::$four); $message_id = $key->add(\danog\MadelineProto\Magic::$four);
} }
$this->check_message_id($message_id, ['outgoing' => true, 'container' => false]); $this->checkMessageId($message_id, ['outgoing' => true, 'container' => false]);
return \strrev($message_id->toBytes()); return \strrev($message_id->toBytes());
} }
public function get_max_id($incoming) public function getMaxId($incoming)
{ {
$incoming = $incoming ? 'incoming' : 'outgoing'; $incoming = $incoming ? 'incoming' : 'outgoing';
if (isset($this->{'max_'.$incoming.'_id'}) && \is_object($this->{'max_'.$incoming.'_id'})) { if (isset($this->{'max_'.$incoming.'_id'}) && \is_object($this->{'max_'.$incoming.'_id'})) {

View File

@ -27,7 +27,7 @@ use danog\MadelineProto\MTProto;
*/ */
trait ResponseHandler trait ResponseHandler
{ {
public function send_msgs_state_info_async($req_msg_id, $msg_ids) public function sendMsgsStateInfo($req_msg_id, $msg_ids)
{ {
$this->logger->logger('Sending state info for '.\count($msg_ids).' message IDs'); $this->logger->logger('Sending state info for '.\count($msg_ids).' message IDs');
$info = ''; $info = '';
@ -51,12 +51,12 @@ trait ResponseHandler
} }
$info .= \chr($cur_info); $info .= \chr($cur_info);
} }
$this->outgoing_messages[yield $this->object_call_async('msgs_state_info', ['req_msg_id' => $req_msg_id, 'info' => $info], ['postpone' => true])]['response'] = $req_msg_id; $this->outgoing_messages[yield $this->objectCall('msgs_state_info', ['req_msg_id' => $req_msg_id, 'info' => $info], ['postpone' => true])]['response'] = $req_msg_id;
} }
public $n = 0; public $n = 0;
public function handle_messages() public function handleMessages()
{ {
$only_updates = true; $only_updates = true;
while ($this->new_incoming) { while ($this->new_incoming) {
@ -71,10 +71,10 @@ trait ResponseHandler
switch ($this->incoming_messages[$current_msg_id]['content']['_']) { switch ($this->incoming_messages[$current_msg_id]['content']['_']) {
case 'msgs_ack': case 'msgs_ack':
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
foreach ($this->incoming_messages[$current_msg_id]['content']['msg_ids'] as $msg_id) { foreach ($this->incoming_messages[$current_msg_id]['content']['msg_ids'] as $msg_id) {
$this->ack_outgoing_message_id($msg_id); $this->ackOutgoingMessageId($msg_id);
// Acknowledge that the server received my message // Acknowledge that the server received my message
} }
@ -82,14 +82,14 @@ trait ResponseHandler
break; break;
case 'rpc_result': case 'rpc_result':
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->ack_incoming_message_id($current_msg_id); $this->ackIncomingMessageId($current_msg_id);
$only_updates = false; $only_updates = false;
// Acknowledge that the server received my request // Acknowledge that the server received my request
$req_msg_id = $this->incoming_messages[$current_msg_id]['content']['req_msg_id']; $req_msg_id = $this->incoming_messages[$current_msg_id]['content']['req_msg_id'];
$this->incoming_messages[$current_msg_id]['content'] = $this->incoming_messages[$current_msg_id]['content']['result']; $this->incoming_messages[$current_msg_id]['content'] = $this->incoming_messages[$current_msg_id]['content']['result'];
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$this->handle_response($req_msg_id, $current_msg_id); $this->handleResponse($req_msg_id, $current_msg_id);
break; break;
case 'future_salts': case 'future_salts':
@ -103,20 +103,20 @@ trait ResponseHandler
case 'pong': case 'pong':
$msg_id_type = isset($msg_id_type) ? $msg_id_type : 'msg_id'; $msg_id_type = isset($msg_id_type) ? $msg_id_type : 'msg_id';
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
$this->handle_response($this->incoming_messages[$current_msg_id]['content'][$msg_id_type], $current_msg_id); $this->handleResponse($this->incoming_messages[$current_msg_id]['content'][$msg_id_type], $current_msg_id);
unset($msg_id_type); unset($msg_id_type);
break; break;
case 'new_session_created': case 'new_session_created':
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
$this->shared->getTempAuthKey()->setServerSalt($this->incoming_messages[$current_msg_id]['content']['server_salt']); $this->shared->getTempAuthKey()->setServerSalt($this->incoming_messages[$current_msg_id]['content']['server_salt']);
$this->ack_incoming_message_id($current_msg_id); $this->ackIncomingMessageId($current_msg_id);
// Acknowledge that I received the server's response // Acknowledge that I received the server's response
if ($this->API->authorized === MTProto::LOGGED_IN && !$this->API->isInitingAuthorization() && $this->API->datacenter->getDataCenterConnection($this->API->datacenter->curdc)->hasTempAuthKey() && isset($this->API->updaters[false])) { if ($this->API->authorized === MTProto::LOGGED_IN && !$this->API->isInitingAuthorization() && $this->API->datacenter->getDataCenterConnection($this->API->datacenter->curdc)->hasTempAuthKey() && isset($this->API->updaters[false])) {
@ -130,29 +130,29 @@ trait ResponseHandler
$only_updates = false; $only_updates = false;
foreach ($this->incoming_messages[$current_msg_id]['content']['messages'] as $message) { foreach ($this->incoming_messages[$current_msg_id]['content']['messages'] as $message) {
$this->check_message_id($message['msg_id'], ['outgoing' => false, 'container' => true]); $this->checkMessageId($message['msg_id'], ['outgoing' => false, 'container' => true]);
$this->incoming_messages[$message['msg_id']] = ['seq_no' => $message['seqno'], 'content' => $message['body'], 'from_container' => true]; $this->incoming_messages[$message['msg_id']] = ['seq_no' => $message['seqno'], 'content' => $message['body'], 'from_container' => true];
$this->new_incoming[$message['msg_id']] = $message['msg_id']; $this->new_incoming[$message['msg_id']] = $message['msg_id'];
} }
\ksort($this->new_incoming); \ksort($this->new_incoming);
//$this->handle_messages(); //$this->handleMessages();
//$this->check_in_seq_no($current_msg_id); //$this->checkInSeqNo($current_msg_id);
unset($this->incoming_messages[$current_msg_id]['content']); unset($this->incoming_messages[$current_msg_id]['content']);
break; break;
case 'msg_copy': case 'msg_copy':
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
$this->ack_incoming_message_id($current_msg_id); $this->ackIncomingMessageId($current_msg_id);
// Acknowledge that I received the server's response // Acknowledge that I received the server's response
if (isset($this->incoming_messages[$this->incoming_messages[$current_msg_id]['content']['orig_message']['msg_id']])) { if (isset($this->incoming_messages[$this->incoming_messages[$current_msg_id]['content']['orig_message']['msg_id']])) {
$this->ack_incoming_message_id($this->incoming_messages[$current_msg_id]['content']['orig_message']['msg_id']); $this->ackIncomingMessageId($this->incoming_messages[$current_msg_id]['content']['orig_message']['msg_id']);
// Acknowledge that I received the server's response // Acknowledge that I received the server's response
} else { } else {
$message = $this->incoming_messages[$current_msg_id]['content']; $message = $this->incoming_messages[$current_msg_id]['content'];
$this->check_message_id($message['orig_message']['msg_id'], ['outgoing' => false, 'container' => true]); $this->checkMessageId($message['orig_message']['msg_id'], ['outgoing' => false, 'container' => true]);
$this->incoming_messages[$message['orig_message']['msg_id']] = ['content' => $this->incoming_messages[$current_msg_id]['content']['orig_message']]; $this->incoming_messages[$message['orig_message']['msg_id']] = ['content' => $this->incoming_messages[$current_msg_id]['content']['orig_message']];
$this->new_incoming[$message['orig_message']['msg_id']] = $message['orig_message']['msg_id']; $this->new_incoming[$message['orig_message']['msg_id']] = $message['orig_message']['msg_id'];
} }
@ -162,7 +162,7 @@ trait ResponseHandler
case 'http_wait': case 'http_wait':
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
$this->logger->logger($this->incoming_messages[$current_msg_id]['content'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger($this->incoming_messages[$current_msg_id]['content'], \danog\MadelineProto\Logger::NOTICE);
@ -171,15 +171,15 @@ trait ResponseHandler
break; break;
case 'msgs_state_req': case 'msgs_state_req':
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->callFork($this->send_msgs_state_info_async($current_msg_id, $this->incoming_messages[$current_msg_id]['content']['msg_ids'])); $this->callFork($this->sendMsgsStateInfo($current_msg_id, $this->incoming_messages[$current_msg_id]['content']['msg_ids']));
unset($this->incoming_messages[$current_msg_id]['content']); unset($this->incoming_messages[$current_msg_id]['content']);
break; break;
case 'msgs_all_info': case 'msgs_all_info':
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
@ -188,7 +188,7 @@ trait ResponseHandler
$msg_id = new \phpseclib\Math\BigInteger(\strrev($msg_id), 256); $msg_id = new \phpseclib\Math\BigInteger(\strrev($msg_id), 256);
$status = 'Status for message id '.$msg_id.': '; $status = 'Status for message id '.$msg_id.': ';
/*if ($info & 4) { /*if ($info & 4) {
*$this->got_response_for_outgoing_message_id($msg_id); *$this->gotResponseForOutgoingMessageId($msg_id);
*} *}
*/ */
foreach (MTProto::MSGS_INFO_FLAGS as $flag => $description) { foreach (MTProto::MSGS_INFO_FLAGS as $flag => $description) {
@ -200,31 +200,31 @@ trait ResponseHandler
} }
break; break;
case 'msg_detailed_info': case 'msg_detailed_info':
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$only_updates = false; $only_updates = false;
if (isset($this->outgoing_messages[$this->incoming_messages[$current_msg_id]['content']['msg_id']])) { if (isset($this->outgoing_messages[$this->incoming_messages[$current_msg_id]['content']['msg_id']])) {
if (isset($this->incoming_messages[$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']])) { if (isset($this->incoming_messages[$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']])) {
$this->handle_response($this->incoming_messages[$current_msg_id]['content']['msg_id'], $this->incoming_messages[$current_msg_id]['content']['answer_msg_id']); $this->handleResponse($this->incoming_messages[$current_msg_id]['content']['msg_id'], $this->incoming_messages[$current_msg_id]['content']['answer_msg_id']);
} else { } else {
$this->callFork($this->object_call_async('msg_resend_req', ['msg_ids' => [$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']]], ['postpone' => true])); $this->callFork($this->objectCall('msg_resend_req', ['msg_ids' => [$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']]], ['postpone' => true]));
} }
} }
break; break;
case 'msg_new_detailed_info': case 'msg_new_detailed_info':
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
if (isset($this->incoming_messages[$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']])) { if (isset($this->incoming_messages[$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']])) {
$this->ack_incoming_message_id($this->incoming_messages[$current_msg_id]['content']['answer_msg_id']); $this->ackIncomingMessageId($this->incoming_messages[$current_msg_id]['content']['answer_msg_id']);
} else { } else {
$this->callFork($this->object_call_async('msg_resend_req', ['msg_ids' => [$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']]], ['postpone' => true])); $this->callFork($this->objectCall('msg_resend_req', ['msg_ids' => [$this->incoming_messages[$current_msg_id]['content']['answer_msg_id']]], ['postpone' => true]));
} }
break; break;
case 'msg_resend_req': case 'msg_resend_req':
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
@ -236,36 +236,36 @@ trait ResponseHandler
} }
if ($ok) { if ($ok) {
foreach ($this->incoming_messages[$current_msg_id]['content']['msg_ids'] as $msg_id) { foreach ($this->incoming_messages[$current_msg_id]['content']['msg_ids'] as $msg_id) {
$this->method_recall('', ['message_id' => $msg_id, 'postpone' => true]); $this->methodRecall('', ['message_id' => $msg_id, 'postpone' => true]);
} }
} else { } else {
$this->callFork($this->send_msgs_state_info_async($current_msg_id, $this->incoming_messages[$current_msg_id]['content']['msg_ids'])); $this->callFork($this->sendMsgsStateInfo($current_msg_id, $this->incoming_messages[$current_msg_id]['content']['msg_ids']));
} }
break; break;
case 'msg_resend_ans_req': case 'msg_resend_ans_req':
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$only_updates = false; $only_updates = false;
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->callFork($this->send_msgs_state_info_async($current_msg_id, $this->incoming_messages[$current_msg_id]['content']['msg_ids'])); $this->callFork($this->sendMsgsStateInfo($current_msg_id, $this->incoming_messages[$current_msg_id]['content']['msg_ids']));
foreach ($this->incoming_messages[$current_msg_id]['content']['msg_ids'] as $msg_id) { foreach ($this->incoming_messages[$current_msg_id]['content']['msg_ids'] as $msg_id) {
if (isset($this->incoming_messages[$msg_id]['response']) && isset($this->outgoing_messages[$this->incoming_messages[$msg_id]['response']])) { if (isset($this->incoming_messages[$msg_id]['response']) && isset($this->outgoing_messages[$this->incoming_messages[$msg_id]['response']])) {
$this->callFork($this->object_call_async($this->outgoing_messages[$this->incoming_messages[$msg_id]['response']]['_'], $this->outgoing_messages[$this->incoming_messages[$msg_id]['response']]['body'], ['postpone' => true])); $this->callFork($this->objectCall($this->outgoing_messages[$this->incoming_messages[$msg_id]['response']]['_'], $this->outgoing_messages[$this->incoming_messages[$msg_id]['response']]['body'], ['postpone' => true]));
} }
} }
break; break;
default: default:
$this->check_in_seq_no($current_msg_id); $this->checkInSeqNo($current_msg_id);
$this->ack_incoming_message_id($current_msg_id); $this->ackIncomingMessageId($current_msg_id);
// Acknowledge that I received the server's response // Acknowledge that I received the server's response
$response_type = $this->API->constructors->find_by_predicate($this->incoming_messages[$current_msg_id]['content']['_'])['type']; $response_type = $this->API->constructors->findByPredicate($this->incoming_messages[$current_msg_id]['content']['_'])['type'];
switch ($response_type) { switch ($response_type) {
case 'Updates': case 'Updates':
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
if (!$this->isCdn()) { if (!$this->isCdn()) {
$this->callForkDefer($this->API->handle_updates_async($this->incoming_messages[$current_msg_id]['content'])); $this->callForkDefer($this->API->handleUpdates($this->incoming_messages[$current_msg_id]['content']));
} }
unset($this->incoming_messages[$current_msg_id]['content']); unset($this->incoming_messages[$current_msg_id]['content']);
@ -285,7 +285,7 @@ trait ResponseHandler
if ($response_type === $expecting['type']) { if ($response_type === $expecting['type']) {
$this->logger->logger('Yes', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Yes', \danog\MadelineProto\Logger::VERBOSE);
unset($this->new_incoming[$current_msg_id]); unset($this->new_incoming[$current_msg_id]);
$this->handle_response($expecting_msg_id, $current_msg_id); $this->handleResponse($expecting_msg_id, $current_msg_id);
break 2; break 2;
} }
$this->logger->logger('No', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('No', \danog\MadelineProto\Logger::VERBOSE);
@ -315,7 +315,7 @@ trait ResponseHandler
* *
* @return void * @return void
*/ */
public function handle_reject(array &$request, \Throwable $data) public function handleReject(array &$request, \Throwable $data)
{ {
if (isset($request['promise']) && \is_object($request['promise'])) { if (isset($request['promise']) && \is_object($request['promise'])) {
Loop::defer(function () use (&$request, $data) { Loop::defer(function () use (&$request, $data) {
@ -337,7 +337,7 @@ trait ResponseHandler
}); });
} elseif (isset($request['container'])) { } elseif (isset($request['container'])) {
foreach ($request['container'] as $message_id) { foreach ($request['container'] as $message_id) {
$this->handle_reject($this->outgoing_messages[$message_id], $data); $this->handleReject($this->outgoing_messages[$message_id], $data);
} }
} else { } else {
$this->logger->logger('Rejecting: already got response for '.(isset($request['_']) ? $request['_'] : '-')); $this->logger->logger('Rejecting: already got response for '.(isset($request['_']) ? $request['_'] : '-'));
@ -345,7 +345,7 @@ trait ResponseHandler
} }
} }
public function handle_response($request_id, $response_id) public function handleResponse($request_id, $response_id)
{ {
$response = &$this->incoming_messages[$response_id]['content']; $response = &$this->incoming_messages[$response_id]['content'];
unset($this->incoming_messages[$response_id]['content']); unset($this->incoming_messages[$response_id]['content']);
@ -359,8 +359,8 @@ trait ResponseHandler
} }
if (\in_array($response['error_message'], ['PERSISTENT_TIMESTAMP_EMPTY', 'PERSISTENT_TIMESTAMP_INVALID'])) { if (\in_array($response['error_message'], ['PERSISTENT_TIMESTAMP_EMPTY', 'PERSISTENT_TIMESTAMP_INVALID'])) {
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->handle_reject($request, new \danog\MadelineProto\PTSException($response['error_message'])); $this->handleReject($request, new \danog\MadelineProto\PTSException($response['error_message']));
return; return;
} }
@ -375,7 +375,7 @@ trait ResponseHandler
unset($request['serialized_body']); unset($request['serialized_body']);
} }
$this->method_recall('', ['message_id' => $request_id, 'postpone' => true]); $this->methodRecall('', ['message_id' => $request_id, 'postpone' => true]);
return; return;
} }
@ -384,7 +384,7 @@ trait ResponseHandler
case -500: case -500:
if ($response['error_message'] === 'MSG_WAIT_FAILED') { if ($response['error_message'] === 'MSG_WAIT_FAILED') {
$this->call_queue[$request['queue']] = []; $this->call_queue[$request['queue']] = [];
$this->method_recall('', ['message_id' => $request_id, 'postpone' => true]); $this->methodRecall('', ['message_id' => $request_id, 'postpone' => true]);
return; return;
} }
@ -392,9 +392,9 @@ trait ResponseHandler
Loop::delay(1 * 1000, [$this, 'method_recall'], ['message_id' => $request_id, ]); Loop::delay(1 * 1000, [$this, 'method_recall'], ['message_id' => $request_id, ]);
return; return;
} }
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
return; return;
case 303: case 303:
@ -409,7 +409,7 @@ trait ResponseHandler
$this->API->settings['connection_settings']['default_dc'] = $this->API->authorized_dc = $this->API->datacenter->curdc; $this->API->settings['connection_settings']['default_dc'] = $this->API->authorized_dc = $this->API->datacenter->curdc;
} }
Loop::defer([$this, 'method_recall'], ['message_id' => $request_id, 'datacenter' => $datacenter]); Loop::defer([$this, 'method_recall'], ['message_id' => $request_id, 'datacenter' => $datacenter]);
//$this->API->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter, 'postpone' => true]); //$this->API->methodRecall('', ['message_id' => $request_id, 'datacenter' => $datacenter, 'postpone' => true]);
return; return;
case 401: case 401:
@ -417,7 +417,7 @@ trait ResponseHandler
case 'USER_DEACTIVATED': case 'USER_DEACTIVATED':
case 'SESSION_REVOKED': case 'SESSION_REVOKED':
case 'SESSION_EXPIRED': case 'SESSION_EXPIRED':
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->logger->logger($response['error_message'], \danog\MadelineProto\Logger::FATAL_ERROR); $this->logger->logger($response['error_message'], \danog\MadelineProto\Logger::FATAL_ERROR);
foreach ($this->API->datacenter->getDataCenterConnections() as $socket) { foreach ($this->API->datacenter->getDataCenterConnections() as $socket) {
@ -439,21 +439,21 @@ trait ResponseHandler
$this->API->resetSession(); $this->API->resetSession();
$this->callFork((function () use (&$request, &$response) { $this->callFork((function () use (&$request, &$response) {
yield $this->API->init_authorization_async(); yield $this->API->initAuthorization();
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
})()); })());
return; return;
case 'AUTH_KEY_UNREGISTERED': case 'AUTH_KEY_UNREGISTERED':
case 'AUTH_KEY_INVALID': case 'AUTH_KEY_INVALID':
if ($this->API->authorized !== MTProto::LOGGED_IN) { if ($this->API->authorized !== MTProto::LOGGED_IN) {
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->callFork((function () use (&$request, &$response) { $this->callFork((function () use (&$request, &$response) {
yield $this->API->init_authorization_async(); yield $this->API->initAuthorization();
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
})()); })());
return; return;
@ -465,7 +465,7 @@ trait ResponseHandler
$this->logger->logger('Auth key not registered, resetting temporary and permanent auth keys...', \danog\MadelineProto\Logger::ERROR); $this->logger->logger('Auth key not registered, resetting temporary and permanent auth keys...', \danog\MadelineProto\Logger::ERROR);
if ($this->API->authorized_dc === $this->datacenter && $this->API->authorized === MTProto::LOGGED_IN) { if ($this->API->authorized_dc === $this->datacenter && $this->API->authorized === MTProto::LOGGED_IN) {
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->logger->logger('Permanent auth key was main authorized key, logging out...', \danog\MadelineProto\Logger::FATAL_ERROR); $this->logger->logger('Permanent auth key was main authorized key, logging out...', \danog\MadelineProto\Logger::FATAL_ERROR);
foreach ($this->API->datacenter->getDataCenterConnections() as $socket) { foreach ($this->API->datacenter->getDataCenterConnections() as $socket) {
@ -484,17 +484,17 @@ trait ResponseHandler
$this->API->resetSession(); $this->API->resetSession();
$this->callFork((function () use (&$request, &$response) { $this->callFork((function () use (&$request, &$response) {
yield $this->API->init_authorization_async(); yield $this->API->initAuthorization();
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
})()); })());
return; return;
} }
$this->callFork((function () use ($request_id) { $this->callFork((function () use ($request_id) {
yield $this->API->init_authorization_async(); yield $this->API->initAuthorization();
$this->method_recall('', ['message_id' => $request_id, ]); $this->methodRecall('', ['message_id' => $request_id, ]);
})()); })());
return; return;
@ -503,22 +503,22 @@ trait ResponseHandler
$this->shared->setTempAuthKey(null); $this->shared->setTempAuthKey(null);
$this->callFork((function () use ($request_id) { $this->callFork((function () use ($request_id) {
yield $this->API->init_authorization_async(); yield $this->API->initAuthorization();
$this->method_recall('', ['message_id' => $request_id, ]); $this->methodRecall('', ['message_id' => $request_id, ]);
})()); })());
return; return;
} }
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
return; return;
case 420: case 420:
$seconds = \preg_replace('/[^0-9]+/', '', $response['error_message']); $seconds = \preg_replace('/[^0-9]+/', '', $response['error_message']);
$limit = isset($request['FloodWaitLimit']) ? $request['FloodWaitLimit'] : $this->API->settings['flood_timeout']['wait_if_lt']; $limit = isset($request['FloodWaitLimit']) ? $request['FloodWaitLimit'] : $this->API->settings['flood_timeout']['wait_if_lt'];
if (\is_numeric($seconds) && $seconds < $limit) { if (\is_numeric($seconds) && $seconds < $limit) {
//$this->got_response_for_outgoing_message_id($request_id); //$this->gotResponseForOutgoingMessageId($request_id);
$this->logger->logger('Flood, waiting '.$seconds.' seconds before repeating async call...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Flood, waiting '.$seconds.' seconds before repeating async call...', \danog\MadelineProto\Logger::NOTICE);
$request['sent'] += $seconds; $request['sent'] += $seconds;
@ -528,9 +528,9 @@ trait ResponseHandler
} }
// no break // no break
default: default:
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
return; return;
} }
@ -546,7 +546,7 @@ trait ResponseHandler
switch ($response['error_code']) { switch ($response['error_code']) {
case 48: case 48:
$this->shared->getTempAuthKey()->setServerSalt($response['new_server_salt']); $this->shared->getTempAuthKey()->setServerSalt($response['new_server_salt']);
$this->method_recall('', ['message_id' => $request_id, 'postpone' => true]); $this->methodRecall('', ['message_id' => $request_id, 'postpone' => true]);
return; return;
case 16: case 16:
@ -556,14 +556,14 @@ trait ResponseHandler
$this->API->resetMTProtoSession(); $this->API->resetMTProtoSession();
$this->shared->setTempAuthKey(null); $this->shared->setTempAuthKey(null);
$this->callFork((function () use ($request_id) { $this->callFork((function () use ($request_id) {
yield $this->API->init_authorization_async(); yield $this->API->initAuthorization();
$this->method_recall('', ['message_id' => $request_id, ]); $this->methodRecall('', ['message_id' => $request_id, ]);
})()); })());
return; return;
} }
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$this->handle_reject($request, new \danog\MadelineProto\RPCErrorException('Received bad_msg_notification: '.MTProto::BAD_MSG_ERROR_CODES[$response['error_code']], $response['error_code'], isset($request['_']) ? $request['_'] : '')); $this->handleReject($request, new \danog\MadelineProto\RPCErrorException('Received bad_msg_notification: '.MTProto::BAD_MSG_ERROR_CODES[$response['error_code']], $response['error_code'], isset($request['_']) ? $request['_'] : ''));
return; return;
} }
@ -579,12 +579,12 @@ trait ResponseHandler
return; return;
} }
$botAPI = isset($request['botAPI']) && $request['botAPI']; $botAPI = isset($request['botAPI']) && $request['botAPI'];
if (isset($response['_']) && !$this->isCdn() && $this->API->constructors->find_by_predicate($response['_'])['type'] === 'Updates') { if (isset($response['_']) && !$this->isCdn() && $this->API->constructors->findByPredicate($response['_'])['type'] === 'Updates') {
$response['request'] = $request; $response['request'] = $request;
$this->callForkDefer($this->API->handle_updates_async($response)); $this->callForkDefer($this->API->handleUpdates($response));
} }
unset($request); unset($request);
$this->got_response_for_outgoing_message_id($request_id); $this->gotResponseForOutgoingMessageId($request_id);
$r = isset($response['_']) ? $response['_'] : \json_encode($response); $r = isset($response['_']) ? $response['_'] : \json_encode($response);
$this->logger->logger("Defer sending $r to deferred"); $this->logger->logger("Defer sending $r to deferred");
$this->callFork(( $this->callFork((
@ -592,7 +592,7 @@ trait ResponseHandler
$r = isset($response['_']) ? $response['_'] : \json_encode($response); $r = isset($response['_']) ? $response['_'] : \json_encode($response);
$this->logger->logger("Deferred: sent $r to deferred"); $this->logger->logger("Deferred: sent $r to deferred");
if ($botAPI) { if ($botAPI) {
$response = yield $this->MTProto_to_botAPI_async($response); $response = yield $this->MTProtoToBotAPI($response);
} }
if (isset($this->outgoing_messages[$request_id]['promise'])) { // This should not happen but happens, should debug if (isset($this->outgoing_messages[$request_id]['promise'])) { // This should not happen but happens, should debug
$promise = $this->outgoing_messages[$request_id]['promise']; $promise = $this->outgoing_messages[$request_id]['promise'];

View File

@ -31,7 +31,7 @@ trait SeqNoHandler
public $session_id; public $session_id;
public function generate_out_seq_no($content_related) public function generateOutSeqNo($content_related)
{ {
$in = $content_related ? 1 : 0; $in = $content_related ? 1 : 0;
$value = $this->session_out_seq_no; $value = $this->session_out_seq_no;
@ -40,17 +40,17 @@ trait SeqNoHandler
return $value * 2 + $in; return $value * 2 + $in;
} }
public function check_in_seq_no($current_msg_id) public function checkInSeqNo($current_msg_id)
{ {
$type = isset($this->incoming_messages[$current_msg_id]['content']['_']) ? $this->incoming_messages[$current_msg_id]['content']['_'] : '-'; $type = isset($this->incoming_messages[$current_msg_id]['content']['_']) ? $this->incoming_messages[$current_msg_id]['content']['_'] : '-';
if (isset($this->incoming_messages[$current_msg_id]['seq_no']) && ($seq_no = $this->generate_in_seq_no($this->content_related($this->incoming_messages[$current_msg_id]['content']))) !== $this->incoming_messages[$current_msg_id]['seq_no']) { if (isset($this->incoming_messages[$current_msg_id]['seq_no']) && ($seq_no = $this->generateInSeqNo($this->contentRelated($this->incoming_messages[$current_msg_id]['content']))) !== $this->incoming_messages[$current_msg_id]['seq_no']) {
$this->API->logger->logger('SECURITY WARNING: Seqno mismatch (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ULTRA_VERBOSE); $this->API->logger->logger('SECURITY WARNING: Seqno mismatch (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
} elseif (isset($seq_no)) { } elseif (isset($seq_no)) {
$this->API->logger->logger('Seqno OK (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ULTRA_VERBOSE); $this->API->logger->logger('Seqno OK (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
} }
} }
public function generate_in_seq_no($content_related) public function generateInSeqNo($content_related)
{ {
$in = $content_related ? 1 : 0; $in = $content_related ? 1 : 0;
$value = $this->session_in_seq_no; $value = $this->session_in_seq_no;
@ -59,7 +59,7 @@ trait SeqNoHandler
return $value * 2 + $in; return $value * 2 + $in;
} }
public function content_related($method) public function contentRelated($method)
{ {
$method = \is_array($method) && isset($method['_']) ? $method['_'] : $method; $method = \is_array($method) && isset($method['_']) ? $method['_'] : $method;

View File

@ -55,7 +55,7 @@ trait AuthKeyHandler
* *
* @return \Generator<AuthKey> * @return \Generator<AuthKey>
*/ */
public function create_auth_key_async(int $expires_in, string $datacenter): \Generator public function createAuthKey(int $expires_in, string $datacenter): \Generator
{ {
$connection = $this->datacenter->getAuthConnection($datacenter); $connection = $this->datacenter->getAuthConnection($datacenter);
$cdn = $connection->isCDN(); $cdn = $connection->isCDN();
@ -82,7 +82,7 @@ trait AuthKeyHandler
* ] * ]
*/ */
$nonce = $this->random(16); $nonce = $this->random(16);
$ResPQ = yield $connection->method_call_async_read($req_pq, ['nonce' => $nonce]); $ResPQ = yield $connection->methodCallAsyncRead($req_pq, ['nonce' => $nonce]);
/* /*
* *********************************************************************** * ***********************************************************************
* Check if the client's nonce and the server's nonce are the same * Check if the client's nonce and the server's nonce are the same
@ -160,7 +160,7 @@ trait AuthKeyHandler
if (!$pq->equals($p->multiply($q))) { if (!$pq->equals($p->multiply($q))) {
$this->logger->logger('Automatic factorization failed, trying wolfram module', \danog\MadelineProto\Logger::ERROR); $this->logger->logger('Automatic factorization failed, trying wolfram module', \danog\MadelineProto\Logger::ERROR);
$p = new \phpseclib\Math\BigInteger(yield $this->wolfram_single_async($pq->__toString())); $p = new \phpseclib\Math\BigInteger(yield $this->wolframSingle($pq->__toString()));
if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { if (!$p->equals(\danog\MadelineProto\Magic::$zero)) {
$q = $pq->divide($p)[0]; $q = $pq->divide($p)[0];
if ($p->compare($q) > 0) { if ($p->compare($q) > 0) {
@ -186,7 +186,7 @@ trait AuthKeyHandler
$q_bytes = $q->toBytes(); $q_bytes = $q->toBytes();
$new_nonce = $this->random(32); $new_nonce = $this->random(32);
$data_unserialized = ['pq' => $pq_bytes, 'p' => $p_bytes, 'q' => $q_bytes, 'nonce' => $nonce, 'server_nonce' => $server_nonce, 'new_nonce' => $new_nonce, 'expires_in' => $expires_in, 'dc' => \preg_replace('|_.*|', '', $datacenter)]; $data_unserialized = ['pq' => $pq_bytes, 'p' => $p_bytes, 'q' => $q_bytes, 'nonce' => $nonce, 'server_nonce' => $server_nonce, 'new_nonce' => $new_nonce, 'expires_in' => $expires_in, 'dc' => \preg_replace('|_.*|', '', $datacenter)];
$p_q_inner_data = yield $this->serialize_object_async(['type' => 'p_q_inner_data'.($expires_in < 0 ? '' : '_temp')], $data_unserialized, 'p_q_inner_data'); $p_q_inner_data = yield $this->serializeObject(['type' => 'p_q_inner_data'.($expires_in < 0 ? '' : '_temp')], $data_unserialized, 'p_q_inner_data');
/* /*
* *********************************************************************** * ***********************************************************************
* Encrypt serialized object * Encrypt serialized object
@ -216,7 +216,7 @@ trait AuthKeyHandler
* ] * ]
*/ */
// //
$server_dh_params = yield $connection->method_call_async_read('req_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'p' => $p_bytes, 'q' => $q_bytes, 'public_key_fingerprint' => $key->fp, 'encrypted_data' => $encrypted_data]); $server_dh_params = yield $connection->methodCallAsyncRead('req_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'p' => $p_bytes, 'q' => $q_bytes, 'public_key_fingerprint' => $key->fp, 'encrypted_data' => $encrypted_data]);
/* /*
* *********************************************************************** * ***********************************************************************
* Check if the client's nonce and the server's nonce are the same * Check if the client's nonce and the server's nonce are the same
@ -246,7 +246,7 @@ trait AuthKeyHandler
$encrypted_answer = $server_dh_params['encrypted_answer']; $encrypted_answer = $server_dh_params['encrypted_answer'];
$tmp_aes_key = \sha1($new_nonce.$server_nonce, true).\substr(\sha1($server_nonce.$new_nonce, true), 0, 12); $tmp_aes_key = \sha1($new_nonce.$server_nonce, true).\substr(\sha1($server_nonce.$new_nonce, true), 0, 12);
$tmp_aes_iv = \substr(\sha1($server_nonce.$new_nonce, true), 12, 8).\sha1($new_nonce.$new_nonce, true).\substr($new_nonce, 0, 4); $tmp_aes_iv = \substr(\sha1($server_nonce.$new_nonce, true), 12, 8).\sha1($new_nonce.$new_nonce, true).\substr($new_nonce, 0, 4);
$answer_with_hash = $this->ige_decrypt($encrypted_answer, $tmp_aes_key, $tmp_aes_iv); $answer_with_hash = $this->igeDecrypt($encrypted_answer, $tmp_aes_key, $tmp_aes_iv);
/* /*
* *********************************************************************** * ***********************************************************************
* Separate answer and hash * Separate answer and hash
@ -270,7 +270,7 @@ trait AuthKeyHandler
* *********************************************************************** * ***********************************************************************
* Do some checks * Do some checks
*/ */
$server_DH_inner_data_length = $this->get_length($answer); $server_DH_inner_data_length = $this->getLength($answer);
if (\sha1(\substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) { if (\sha1(\substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) {
throw new \danog\MadelineProto\SecurityException('answer_hash mismatch.'); throw new \danog\MadelineProto\SecurityException('answer_hash mismatch.');
} }
@ -290,14 +290,14 @@ trait AuthKeyHandler
$server_time = $server_DH_inner_data['server_time']; $server_time = $server_DH_inner_data['server_time'];
$connection->time_delta = $server_time - \time(); $connection->time_delta = $server_time - \time();
$this->logger->logger(\sprintf('Server-client time delta = %.1f s', $connection->time_delta), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf('Server-client time delta = %.1f s', $connection->time_delta), \danog\MadelineProto\Logger::VERBOSE);
$this->check_p_g($dh_prime, $g); $this->checkPG($dh_prime, $g);
$this->check_G($g_a, $dh_prime); $this->checkG($g_a, $dh_prime);
for ($retry_id = 0; $retry_id <= $this->settings['max_tries']['authorization']; $retry_id++) { for ($retry_id = 0; $retry_id <= $this->settings['max_tries']['authorization']; $retry_id++) {
$this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE);
$b = new \phpseclib\Math\BigInteger($this->random(256), 256); $b = new \phpseclib\Math\BigInteger($this->random(256), 256);
$this->logger->logger('Generating g_b...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating g_b...', \danog\MadelineProto\Logger::VERBOSE);
$g_b = $g->powMod($b, $dh_prime); $g_b = $g->powMod($b, $dh_prime);
$this->check_G($g_b, $dh_prime); $this->checkG($g_b, $dh_prime);
/* /*
* *********************************************************************** * ***********************************************************************
* Check validity of g_b * Check validity of g_b
@ -320,14 +320,14 @@ trait AuthKeyHandler
* string $g_b : g^b mod dh_prime * string $g_b : g^b mod dh_prime
* ] * ]
*/ */
$data = yield $this->serialize_object_async(['type' => 'client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str], 'client_DH_inner_data'); $data = yield $this->serializeObject(['type' => 'client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str], 'client_DH_inner_data');
/* /*
* *********************************************************************** * ***********************************************************************
* encrypt client_DH_inner_data * encrypt client_DH_inner_data
*/ */
$data_with_sha = \sha1($data, true).$data; $data_with_sha = \sha1($data, true).$data;
$data_with_sha_padded = $data_with_sha.$this->random($this->posmod(-\strlen($data_with_sha), 16)); $data_with_sha_padded = $data_with_sha.$this->random($this->posmod(-\strlen($data_with_sha), 16));
$encrypted_data = $this->ige_encrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv); $encrypted_data = $this->igeEncrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv);
$this->logger->logger('Executing set_client_DH_params...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Executing set_client_DH_params...', \danog\MadelineProto\Logger::VERBOSE);
/* /*
* *********************************************************************** * ***********************************************************************
@ -346,7 +346,7 @@ trait AuthKeyHandler
* int128 $new_nonce_hash2 : Return this value if server responds with dh_gen_fail * int128 $new_nonce_hash2 : Return this value if server responds with dh_gen_fail
* ] * ]
*/ */
$Set_client_DH_params_answer = yield $connection->method_call_async_read('set_client_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'encrypted_data' => $encrypted_data]); $Set_client_DH_params_answer = yield $connection->methodCallAsyncRead('set_client_DH_params', ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'encrypted_data' => $encrypted_data]);
/* /*
* *********************************************************************** * ***********************************************************************
* Generate auth_key * Generate auth_key
@ -436,7 +436,7 @@ trait AuthKeyHandler
* *
* @return bool * @return bool
*/ */
public function check_G(BigInteger $g_a, BigInteger $p): bool public function checkG(BigInteger $g_a, BigInteger $p): bool
{ {
/* /*
* *********************************************************************** * ***********************************************************************
@ -463,7 +463,7 @@ trait AuthKeyHandler
* *
* @return boolean * @return boolean
*/ */
public function check_p_g(BigInteger $p, BigInteger $g): bool public function checkPG(BigInteger $p, BigInteger $g): bool
{ {
/* /*
* *********************************************************************** * ***********************************************************************
@ -514,9 +514,9 @@ trait AuthKeyHandler
* *
* @return \Generator<array> * @return \Generator<array>
*/ */
public function get_dh_config_async(): \Generator public function getDhConfig(): \Generator
{ {
$dh_config = yield $this->method_call_async_read('messages.getDhConfig', ['version' => $this->dh_config['version'], 'random_length' => 0], ['datacenter' => $this->datacenter->curdc]); $dh_config = yield $this->methodCallAsyncRead('messages.getDhConfig', ['version' => $this->dh_config['version'], 'random_length' => 0], ['datacenter' => $this->datacenter->curdc]);
if ($dh_config['_'] === 'messages.dhConfigNotModified') { if ($dh_config['_'] === 'messages.dhConfigNotModified') {
$this->logger->logger(\danog\MadelineProto\Logger::VERBOSE, ['DH configuration not modified']); $this->logger->logger(\danog\MadelineProto\Logger::VERBOSE, ['DH configuration not modified']);
@ -524,7 +524,7 @@ trait AuthKeyHandler
} }
$dh_config['p'] = new \phpseclib\Math\BigInteger((string) $dh_config['p'], 256); $dh_config['p'] = new \phpseclib\Math\BigInteger((string) $dh_config['p'], 256);
$dh_config['g'] = new \phpseclib\Math\BigInteger($dh_config['g']); $dh_config['g'] = new \phpseclib\Math\BigInteger($dh_config['g']);
$this->check_p_g($dh_config['p'], $dh_config['g']); $this->checkPG($dh_config['p'], $dh_config['g']);
return $this->dh_config = $dh_config; return $this->dh_config = $dh_config;
} }
@ -537,7 +537,7 @@ trait AuthKeyHandler
* *
* @return \Generator<bool> * @return \Generator<bool>
*/ */
public function bind_temp_auth_key_async(int $expires_in, string $datacenter): \Generator public function bindTempAuthKey(int $expires_in, string $datacenter): \Generator
{ {
$datacenterConnection = $this->datacenter->getDataCenterConnection($datacenter); $datacenterConnection = $this->datacenter->getDataCenterConnection($datacenter);
$connection = $datacenterConnection->getAuthConnection(); $connection = $datacenterConnection->getAuthConnection();
@ -550,15 +550,15 @@ trait AuthKeyHandler
$temp_auth_key_id = $datacenterConnection->getTempAuthKey()->getID(); $temp_auth_key_id = $datacenterConnection->getTempAuthKey()->getID();
$perm_auth_key_id = $datacenterConnection->getPermAuthKey()->getID(); $perm_auth_key_id = $datacenterConnection->getPermAuthKey()->getID();
$temp_session_id = $connection->session_id; $temp_session_id = $connection->session_id;
$message_data = yield $this->serialize_object_async(['type' => 'bind_auth_key_inner'], ['nonce' => $nonce, 'temp_auth_key_id' => $temp_auth_key_id, 'perm_auth_key_id' => $perm_auth_key_id, 'temp_session_id' => $temp_session_id, 'expires_at' => $expires_at], 'bind_temp_auth_key_inner'); $message_data = yield $this->serializeObject(['type' => 'bind_auth_key_inner'], ['nonce' => $nonce, 'temp_auth_key_id' => $temp_auth_key_id, 'perm_auth_key_id' => $perm_auth_key_id, 'temp_session_id' => $temp_session_id, 'expires_at' => $expires_at], 'bind_temp_auth_key_inner');
$message_id = $connection->generate_message_id(); $message_id = $connection->generateMessageId();
$seq_no = 0; $seq_no = 0;
$encrypted_data = $this->random(16).$message_id.\pack('VV', $seq_no, \strlen($message_data)).$message_data; $encrypted_data = $this->random(16).$message_id.\pack('VV', $seq_no, \strlen($message_data)).$message_data;
$message_key = \substr(\sha1($encrypted_data, true), -16); $message_key = \substr(\sha1($encrypted_data, true), -16);
$padding = $this->random($this->posmod(-\strlen($encrypted_data), 16)); $padding = $this->random($this->posmod(-\strlen($encrypted_data), 16));
list($aes_key, $aes_iv) = $this->old_aes_calculate($message_key, $datacenterConnection->getPermAuthKey()->getAuthKey()); list($aes_key, $aes_iv) = $this->oldAesCalculate($message_key, $datacenterConnection->getPermAuthKey()->getAuthKey());
$encrypted_message = $datacenterConnection->getPermAuthKey()->getID().$message_key.$this->ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv); $encrypted_message = $datacenterConnection->getPermAuthKey()->getID().$message_key.$this->igeEncrypt($encrypted_data.$padding, $aes_key, $aes_iv);
$res = yield $connection->method_call_async_read('auth.bindTempAuthKey', ['perm_auth_key_id' => $perm_auth_key_id, 'nonce' => $nonce, 'expires_at' => $expires_at, 'encrypted_message' => $encrypted_message], ['msg_id' => $message_id]); $res = yield $connection->methodCallAsyncRead('auth.bindTempAuthKey', ['perm_auth_key_id' => $perm_auth_key_id, 'nonce' => $nonce, 'expires_at' => $expires_at, 'encrypted_message' => $encrypted_message], ['msg_id' => $message_id]);
if ($res === true) { if ($res === true) {
$this->logger->logger('Bound temporary and permanent authorization keys, DC '.$datacenter, \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Bound temporary and permanent authorization keys, DC '.$datacenter, \danog\MadelineProto\Logger::NOTICE);
$datacenterConnection->bind(); $datacenterConnection->bind();
@ -585,7 +585,7 @@ trait AuthKeyHandler
* *
* @return \Generator<string|bool> * @return \Generator<string|bool>
*/ */
public function wolfram_single_async($what): \Generator public function wolframSingle($what): \Generator
{ {
$code = yield $this->datacenter->fileGetContents('http://www.wolframalpha.com/api/v1/code'); $code = yield $this->datacenter->fileGetContents('http://www.wolframalpha.com/api/v1/code');
$query = 'Do prime factorization of '.$what; $query = 'Do prime factorization of '.$what;
@ -633,7 +633,7 @@ trait AuthKeyHandler
* *
* @return \Generator * @return \Generator
*/ */
public function init_authorization_async(): \Generator public function initAuthorization(): \Generator
{ {
if ($this->pending_auth) { if ($this->pending_auth) {
$this->logger("Pending auth, not initing auth"); $this->logger("Pending auth, not initing auth");
@ -660,7 +660,7 @@ trait AuthKeyHandler
continue; continue;
} }
$dcs[$id] = function () use ($id, $socket) { $dcs[$id] = function () use ($id, $socket) {
return $this->init_authorization_socket_async($id, $socket); return $this->initAuthorizationSocket($id, $socket);
}; };
} }
if ($dcs) { if ($dcs) {
@ -674,12 +674,12 @@ trait AuthKeyHandler
yield $this->all($dcs); yield $this->all($dcs);
foreach ($postpone as $id => $socket) { foreach ($postpone as $id => $socket) {
yield $this->init_authorization_socket_async($id, $socket); yield $this->initAuthorizationSocket($id, $socket);
} }
if ($this->pending_auth && empty($this->init_auth_dcs)) { if ($this->pending_auth && empty($this->init_auth_dcs)) {
$this->pending_auth = false; $this->pending_auth = false;
yield $this->init_authorization_async(); yield $this->initAuthorization();
} }
} finally { } finally {
$this->pending_auth = false; $this->pending_auth = false;
@ -695,7 +695,7 @@ trait AuthKeyHandler
* *
* @return \Generator * @return \Generator
*/ */
public function init_authorization_socket_async(string $id, DataCenterConnection $socket): \Generator public function initAuthorizationSocket(string $id, DataCenterConnection $socket): \Generator
{ {
$this->logger("Initing authorization DC $id..."); $this->logger("Initing authorization DC $id...");
$this->init_auth_dcs[$id] = true; $this->init_auth_dcs[$id] = true;
@ -710,7 +710,7 @@ trait AuthKeyHandler
if (!$socket->hasTempAuthKey() || !$socket->hasPermAuthKey() || !$socket->isBound()) { if (!$socket->hasTempAuthKey() || !$socket->hasPermAuthKey() || !$socket->isBound()) {
if (!$socket->hasPermAuthKey() && !$cdn && !$media) { if (!$socket->hasPermAuthKey() && !$cdn && !$media) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['gen_perm_auth_key'], $id), \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['gen_perm_auth_key'], $id), \danog\MadelineProto\Logger::NOTICE);
$socket->setPermAuthKey(yield $this->create_auth_key_async(-1, $id)); $socket->setPermAuthKey(yield $this->createAuthKey(-1, $id));
//$socket->authorized(false); //$socket->authorized(false);
} }
if ($media) { if ($media) {
@ -727,28 +727,28 @@ trait AuthKeyHandler
//$socket->authorized = false; //$socket->authorized = false;
$socket->setTempAuthKey(null); $socket->setTempAuthKey(null);
$socket->setTempAuthKey(yield $this->create_auth_key_async($this->settings['authorization']['default_temp_auth_key_expires_in'], $id)); $socket->setTempAuthKey(yield $this->createAuthKey($this->settings['authorization']['default_temp_auth_key_expires_in'], $id));
yield $this->bind_temp_auth_key_async($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); yield $this->bindTempAuthKey($this->settings['authorization']['default_temp_auth_key_expires_in'], $id);
$this->config = yield $connection->method_call_async_read('help.getConfig', []); $this->config = yield $connection->methodCallAsyncRead('help.getConfig', []);
yield $this->sync_authorization_async($id); yield $this->syncAuthorization($id);
} elseif (!$socket->hasTempAuthKey()) { } elseif (!$socket->hasTempAuthKey()) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id), \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id), \danog\MadelineProto\Logger::NOTICE);
$socket->setTempAuthKey(yield $this->create_auth_key_async($this->settings['authorization']['default_temp_auth_key_expires_in'], $id)); $socket->setTempAuthKey(yield $this->createAuthKey($this->settings['authorization']['default_temp_auth_key_expires_in'], $id));
} }
} else { } else {
if (!$cdn) { if (!$cdn) {
$socket->bind(false); $socket->bind(false);
$this->config = yield $connection->method_call_async_read('help.getConfig', []); $this->config = yield $connection->methodCallAsyncRead('help.getConfig', []);
yield $this->sync_authorization_async($id); yield $this->syncAuthorization($id);
} elseif (!$socket->hasTempAuthKey()) { } elseif (!$socket->hasTempAuthKey()) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id), \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id), \danog\MadelineProto\Logger::NOTICE);
$socket->setTempAuthKey(yield $this->create_auth_key_async($this->settings['authorization']['default_temp_auth_key_expires_in'], $id)); $socket->setTempAuthKey(yield $this->createAuthKey($this->settings['authorization']['default_temp_auth_key_expires_in'], $id));
} }
} }
} elseif (!$cdn) { } elseif (!$cdn) {
yield $this->sync_authorization_async($id); yield $this->syncAuthorization($id);
} }
} finally { } finally {
$this->logger("Done initing authorization DC $id"); $this->logger("Done initing authorization DC $id");
@ -763,7 +763,7 @@ trait AuthKeyHandler
* *
* @return \Generator * @return \Generator
*/ */
public function sync_authorization_async(string $id): \Generator public function syncAuthorization(string $id): \Generator
{ {
if (!$this->datacenter->has($id)) { if (!$this->datacenter->has($id)) {
return false; return false;
@ -777,8 +777,8 @@ trait AuthKeyHandler
if ($authorized_socket->hasTempAuthKey() && $authorized_socket->hasPermAuthKey() && $authorized_socket->isAuthorized() && $this->authorized === self::LOGGED_IN && !$socket->isAuthorized() && !$authorized_socket->isCDN()) { if ($authorized_socket->hasTempAuthKey() && $authorized_socket->hasPermAuthKey() && $authorized_socket->isAuthorized() && $this->authorized === self::LOGGED_IN && !$socket->isAuthorized() && !$authorized_socket->isCDN()) {
try { try {
$this->logger->logger('Trying to copy authorization from dc '.$authorized_dc_id.' to dc '.$id); $this->logger->logger('Trying to copy authorization from dc '.$authorized_dc_id.' to dc '.$id);
$exported_authorization = yield $this->method_call_async_read('auth.exportAuthorization', ['dc_id' => \preg_replace('|_.*|', '', $id)], ['datacenter' => $authorized_dc_id]); $exported_authorization = yield $this->methodCallAsyncRead('auth.exportAuthorization', ['dc_id' => \preg_replace('|_.*|', '', $id)], ['datacenter' => $authorized_dc_id]);
$authorization = yield $this->method_call_async_read('auth.importAuthorization', $exported_authorization, ['datacenter' => $id]); $authorization = yield $this->methodCallAsyncRead('auth.importAuthorization', $exported_authorization, ['datacenter' => $id]);
$socket->authorized(true); $socket->authorized(true);
break; break;
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {

View File

@ -35,9 +35,9 @@ trait CallHandler
* *
* @return array * @return array
*/ */
public function method_call(string $method, $args = [], array $aargs = ['msg_id' => null]) public function methodCall(string $method, $args = [], array $aargs = ['msg_id' => null])
{ {
return $this->wait($this->method_call_async_read($method, $args, $aargs)); return $this->wait($this->methodCallAsyncRead($method, $args, $aargs));
} }
/** /**
@ -51,9 +51,9 @@ trait CallHandler
* *
* @return Promise * @return Promise
*/ */
public function method_call_async_read(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise public function methodCallAsyncRead(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise
{ {
return $this->datacenter->getConnection($aargs['datacenter'] ?? $this->datacenter->curdc)->method_call_async_read($method, $args, $aargs); return $this->datacenter->getConnection($aargs['datacenter'] ?? $this->datacenter->curdc)->methodCallAsyncRead($method, $args, $aargs);
} }
/** /**
* Call method and make sure it is asynchronously sent. * Call method and make sure it is asynchronously sent.
@ -64,8 +64,8 @@ trait CallHandler
* *
* @return Promise * @return Promise
*/ */
public function method_call_async_write(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise public function methodCallAsyncWrite(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise
{ {
return $this->datacenter->getConnection($aargs['datacenter'] ?? $this->datacenter->curdc)->method_call_async_write($method, $args, $aargs); return $this->datacenter->getConnection($aargs['datacenter'] ?? $this->datacenter->curdc)->methodCallAsyncWrite($method, $args, $aargs);
} }
} }

View File

@ -21,7 +21,7 @@ namespace danog\MadelineProto\MTProtoTools;
trait Crypt trait Crypt
{ {
public function aes_calculate($msg_key, $auth_key, $to_server = true) public function aesCalculate($msg_key, $auth_key, $to_server = true)
{ {
$x = $to_server ? 0 : 8; $x = $to_server ? 0 : 8;
$sha256_a = \hash('sha256', $msg_key.\substr($auth_key, $x, 36), true); $sha256_a = \hash('sha256', $msg_key.\substr($auth_key, $x, 36), true);
@ -32,7 +32,7 @@ trait Crypt
return [$aes_key, $aes_iv]; return [$aes_key, $aes_iv];
} }
public function old_aes_calculate($msg_key, $auth_key, $to_server = true) public function oldAesCalculate($msg_key, $auth_key, $to_server = true)
{ {
$x = $to_server ? 0 : 8; $x = $to_server ? 0 : 8;
$sha1_a = \sha1($msg_key.\substr($auth_key, $x, 32), true); $sha1_a = \sha1($msg_key.\substr($auth_key, $x, 32), true);
@ -45,7 +45,7 @@ trait Crypt
return [$aes_key, $aes_iv]; return [$aes_key, $aes_iv];
} }
public function ctr_encrypt($message, $key, $iv) public function ctrEncrypt($message, $key, $iv)
{ {
$cipher = new \phpseclib\Crypt\AES('ctr'); $cipher = new \phpseclib\Crypt\AES('ctr');
$cipher->setKey($key); $cipher->setKey($key);
@ -54,7 +54,7 @@ trait Crypt
return @$cipher->encrypt($message); return @$cipher->encrypt($message);
} }
public function ige_encrypt($message, $key, $iv) public function igeEncrypt($message, $key, $iv)
{ {
$cipher = new \phpseclib\Crypt\AES('ige'); $cipher = new \phpseclib\Crypt\AES('ige');
$cipher->setKey($key); $cipher->setKey($key);
@ -62,7 +62,7 @@ trait Crypt
return @$cipher->encrypt($message); return @$cipher->encrypt($message);
} }
public function ige_decrypt($message, $key, $iv) public function igeDecrypt($message, $key, $iv)
{ {
$cipher = new \phpseclib\Crypt\AES('ige'); $cipher = new \phpseclib\Crypt\AES('ige');
$cipher->setKey($key); $cipher->setKey($key);

View File

@ -47,7 +47,7 @@ use function Amp\Promise\all;
*/ */
trait Files trait Files
{ {
public function upload_async($file, $file_name = '', $cb = null, $encrypted = false) public function upload($file, $file_name = '', $cb = null, $encrypted = false)
{ {
if (\is_object($file) && $file instanceof FileCallbackInterface) { if (\is_object($file) && $file instanceof FileCallbackInterface) {
$cb = $file; $cb = $file;
@ -55,10 +55,10 @@ trait Files
} }
if (\is_string($file) || (\is_object($file) && \method_exists($file, '__toString'))) { if (\is_string($file) || (\is_object($file) && \method_exists($file, '__toString'))) {
if (\filter_var($file, FILTER_VALIDATE_URL)) { if (\filter_var($file, FILTER_VALIDATE_URL)) {
return yield $this->upload_from_url_async($file); return yield $this->uploadFromUrl($file);
} }
} elseif (\is_array($file)) { } elseif (\is_array($file)) {
return yield $this->upload_from_tgfile_async($file, $cb, $encrypted); return yield $this->uploadFromTgfile($file, $cb, $encrypted);
} }
$file = \danog\MadelineProto\Absolute::absolute($file); $file = \danog\MadelineProto\Absolute::absolute($file);
@ -77,15 +77,15 @@ trait Files
} }
$stream = yield open($file, 'rb'); $stream = yield open($file, 'rb');
$mime = $this->get_mime_from_file($file); $mime = $this->getMimeFromFile($file);
try { try {
return yield $this->upload_from_stream_async($stream, $size, $mime, $file_name, $cb, $encrypted); return yield $this->uploadFromStream($stream, $size, $mime, $file_name, $cb, $encrypted);
} finally { } finally {
yield $stream->close(); yield $stream->close();
} }
} }
public function upload_from_url_async($url, int $size = 0, string $file_name = '', $cb = null, bool $encrypted = false) public function uploadFromUrl($url, int $size = 0, string $file_name = '', $cb = null, bool $encrypted = false)
{ {
if (\is_object($url) && $url instanceof FileCallbackInterface) { if (\is_object($url) && $url instanceof FileCallbackInterface) {
$cb = $url; $cb = $url;
@ -116,9 +116,9 @@ trait Files
yield $stream->seek(0); yield $stream->seek(0);
} }
return yield $this->upload_from_stream_async($stream, $size, $mime, $file_name, $cb, $encrypted); return yield $this->uploadFromStream($stream, $size, $mime, $file_name, $cb, $encrypted);
} }
public function upload_from_stream_async($stream, int $size, string $mime, string $file_name = '', $cb = null, bool $encrypted = false) public function uploadFromStream($stream, int $size, string $mime, string $file_name = '', $cb = null, bool $encrypted = false)
{ {
if (\is_object($stream) && $stream instanceof FileCallbackInterface) { if (\is_object($stream) && $stream instanceof FileCallbackInterface) {
$cb = $stream; $cb = $stream;
@ -172,13 +172,13 @@ trait Files
$seekable = false; $seekable = false;
} }
$res = yield $this->upload_from_callable_async($callable, $size, $mime, $file_name, $cb, $seekable, $encrypted); $res = yield $this->uploadFromCallable($callable, $size, $mime, $file_name, $cb, $seekable, $encrypted);
if ($created) { if ($created) {
$stream->disconnect(); $stream->disconnect();
} }
return $res; return $res;
} }
public function upload_from_callable_async($callable, int $size, string $mime, string $file_name = '', $cb = null, bool $refetchable = true, bool $encrypted = false) public function uploadFromCallable($callable, int $size, string $mime, string $file_name = '', $cb = null, bool $refetchable = true, bool $encrypted = false)
{ {
if (\is_object($callable) && $callable instanceof FileCallbackInterface) { if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
$cb = $callable; $cb = $callable;
@ -212,7 +212,7 @@ trait Files
$key = $this->random(32); $key = $this->random(32);
$iv = $this->random(32); $iv = $this->random(32);
$digest = \hash('md5', $key.$iv, true); $digest = \hash('md5', $key.$iv, true);
$fingerprint = $this->unpack_signed_int(\substr($digest, 0, 4) ^ \substr($digest, 4, 4)); $fingerprint = $this->unpackSignedInt(\substr($digest, 0, 4) ^ \substr($digest, 4, 4));
$ige = new \phpseclib\Crypt\AES('ige'); $ige = new \phpseclib\Crypt\AES('ige');
$ige->setIV($iv); $ige->setIV($iv);
$ige->setKey($key); $ige->setKey($key);
@ -230,7 +230,7 @@ trait Files
$start = \microtime(true); $start = \microtime(true);
while ($part_num < $part_total_num) { while ($part_num < $part_total_num) {
$read_deferred = yield $this->method_call_async_write( $read_deferred = yield $this->methodCallAsyncWrite(
$method, $method,
new AsyncParameters( new AsyncParameters(
static function () use ($file_id, $part_num, $part_total_num, $part_size, $callable, $ctx, $ige) { static function () use ($file_id, $part_num, $part_total_num, $part_size, $callable, $ctx, $ige) {
@ -300,18 +300,18 @@ trait Files
return $constructor; return $constructor;
} }
public function upload_encrypted_async($file, $file_name = '', $cb = null) public function uploadEncrypted($file, $file_name = '', $cb = null)
{ {
return $this->upload_async($file, $file_name, $cb, true); return $this->upload($file, $file_name, $cb, true);
} }
public function upload_from_tgfile_async($media, $cb = null, $encrypted = false) public function uploadFromTgfile($media, $cb = null, $encrypted = false)
{ {
if (\is_object($media) && $media instanceof FileCallbackInterface) { if (\is_object($media) && $media instanceof FileCallbackInterface) {
$cb = $media; $cb = $media;
$media = $media->getFile(); $media = $media->getFile();
} }
$media = yield $this->get_download_info_async($media); $media = yield $this->getDownloadInfo($media);
if (!isset($media['size'], $media['mime'])) { if (!isset($media['size'], $media['mime'])) {
throw new Exception('Wrong file provided!'); throw new Exception('Wrong file provided!');
} }
@ -368,17 +368,17 @@ trait Files
$reader = [$bridge, 'read']; $reader = [$bridge, 'read'];
$writer = [$bridge, 'write']; $writer = [$bridge, 'write'];
$read = $this->upload_from_callable_async($reader, $size, $mime, '', $cb, false, $encrypted); $read = $this->uploadFromCallable($reader, $size, $mime, '', $cb, false, $encrypted);
$write = $this->download_to_callable_async($media, $writer, null, true, 0, -1, $chunk_size); $write = $this->downloadToCallable($media, $writer, null, true, 0, -1, $chunk_size);
list($res) = yield $this->all([$read, $write]); list($res) = yield $this->all([$read, $write]);
return $res; return $res;
} }
public function gen_all_file_async($media) public function genAllFile($media)
{ {
$res = [$this->constructors->find_by_predicate($media['_'])['type'] => $media]; $res = [$this->constructors->findByPredicate($media['_'])['type'] => $media];
switch ($media['_']) { switch ($media['_']) {
case 'messageMediaPoll': case 'messageMediaPoll':
$res['Poll'] = $media['poll']; $res['Poll'] = $media['poll'];
@ -469,10 +469,10 @@ trait Files
return $res; return $res;
} }
public function get_file_info_async($constructor) public function getFileInfo($constructor)
{ {
if (\is_string($constructor)) { if (\is_string($constructor)) {
$constructor = $this->unpack_file_id($constructor)['MessageMedia']; $constructor = $this->unpackFileId($constructor)['MessageMedia'];
} }
switch ($constructor['_']) { switch ($constructor['_']) {
case 'updateNewMessage': case 'updateNewMessage':
@ -486,16 +486,16 @@ trait Files
$constructor = $constructor['media']; $constructor = $constructor['media'];
} }
return yield $this->gen_all_file_async($constructor); return yield $this->genAllFile($constructor);
} }
public function get_propic_info_async($data) public function getPropicInfo($data)
{ {
return yield $this->get_download_info_async($this->chats[(yield $this->get_info_async($data))['bot_api_id']]); return yield $this->getDownloadInfo($this->chats[(yield $this->getInfo($data))['bot_api_id']]);
} }
public function get_download_info_async($message_media) public function getDownloadInfo($message_media)
{ {
if (\is_string($message_media)) { if (\is_string($message_media)) {
$message_media = $this->unpack_file_id($message_media)['MessageMedia']; $message_media = $this->unpackFileId($message_media)['MessageMedia'];
} }
if (!isset($message_media['_'])) { if (!isset($message_media['_'])) {
return $message_media; return $message_media;
@ -508,7 +508,7 @@ trait Files
$message_media = $message_media['message']; $message_media = $message_media['message'];
// no break // no break
case 'message': case 'message':
return yield $this->get_download_info_async($message_media['media']); return yield $this->getDownloadInfo($message_media['media']);
case 'updateNewEncryptedMessage': case 'updateNewEncryptedMessage':
$message_media = $message_media['message']; $message_media = $message_media['message'];
@ -516,7 +516,7 @@ trait Files
// no break // no break
case 'encryptedMessage': case 'encryptedMessage':
if ($message_media['decrypted_message']['media']['_'] === 'decryptedMessageMediaExternalDocument') { if ($message_media['decrypted_message']['media']['_'] === 'decryptedMessageMediaExternalDocument') {
return yield $this->get_download_info_async($message_media['decrypted_message']['media']); return yield $this->getDownloadInfo($message_media['decrypted_message']['media']);
} }
$res['InputFileLocation'] = ['_' => 'inputEncryptedFileLocation', 'id' => $message_media['file']['id'], 'access_hash' => $message_media['file']['access_hash'], 'dc_id' => $message_media['file']['dc_id']]; $res['InputFileLocation'] = ['_' => 'inputEncryptedFileLocation', 'id' => $message_media['file']['id'], 'access_hash' => $message_media['file']['access_hash'], 'dc_id' => $message_media['file']['dc_id']];
$res['size'] = $message_media['decrypted_message']['media']['size']; $res['size'] = $message_media['decrypted_message']['media']['size'];
@ -558,19 +558,19 @@ trait Files
} }
} }
if (!isset($res['ext']) || $res['ext'] === '') { if (!isset($res['ext']) || $res['ext'] === '') {
$res['ext'] = $this->get_extension_from_location($res['InputFileLocation'], $this->get_extension_from_mime($res['mime'] ?? 'image/jpeg')); $res['ext'] = $this->getExtensionFromLocation($res['InputFileLocation'], $this->getExtensionFromMime($res['mime'] ?? 'image/jpeg'));
} }
if (!isset($res['mime']) || $res['mime'] === '') { if (!isset($res['mime']) || $res['mime'] === '') {
$res['mime'] = $this->get_mime_from_extension($res['ext'], 'image/jpeg'); $res['mime'] = $this->getMimeFromExtension($res['ext'], 'image/jpeg');
} }
if (!isset($res['name']) || $res['name'] === '') { if (!isset($res['name']) || $res['name'] === '') {
$res['name'] = Tools::unpack_signed_long_string($message_media['file']['access_hash']); $res['name'] = Tools::unpackSignedLongString($message_media['file']['access_hash']);
} }
return $res; return $res;
// Wallpapers // Wallpapers
case 'wallPaper': case 'wallPaper':
return $this->get_download_info_async($res['document']); return $this->getDownloadInfo($res['document']);
// Photos // Photos
case 'photo': case 'photo':
case 'messageMediaPhoto': case 'messageMediaPhoto':
@ -581,7 +581,7 @@ trait Files
$message_media = $message_media['photo']; $message_media = $message_media['photo'];
$size = \end($message_media['sizes']); $size = \end($message_media['sizes']);
$res = \array_merge($res, yield $this->get_download_info_async($size)); $res = \array_merge($res, yield $this->getDownloadInfo($size));
$res['InputFileLocation'] = [ $res['InputFileLocation'] = [
'_' => 'inputPhotoFileLocation', '_' => 'inputPhotoFileLocation',
@ -601,13 +601,13 @@ trait Files
case 'channel': case 'channel':
case 'chat': case 'chat':
case 'updateUserPhoto': case 'updateUserPhoto':
$res = yield $this->get_download_info_async($message_media['photo']); $res = yield $this->getDownloadInfo($message_media['photo']);
$res['InputFileLocation'] = [ $res['InputFileLocation'] = [
'_' => 'inputPeerPhotoFileLocation', '_' => 'inputPeerPhotoFileLocation',
'big' => true, 'big' => true,
'dc_id' => $res['InputFileLocation']['dc_id'], 'dc_id' => $res['InputFileLocation']['dc_id'],
'peer' => (yield $this->get_info_async($message_media))['InputPeer'], 'peer' => (yield $this->getInfo($message_media))['InputPeer'],
'volume_id' => $res['InputFileLocation']['volume_id'], 'volume_id' => $res['InputFileLocation']['volume_id'],
'local_id' => $res['InputFileLocation']['local_id'], 'local_id' => $res['InputFileLocation']['local_id'],
// The peer field will be added later // The peer field will be added later
@ -618,7 +618,7 @@ trait Files
case 'chatPhoto': case 'chatPhoto':
$size = $message_media['photo_big']; $size = $message_media['photo_big'];
$res = yield $this->get_download_info_async($size); $res = yield $this->getDownloadInfo($size);
$res['InputFileLocation']['dc_id'] = $message_media['dc_id']; $res['InputFileLocation']['dc_id'] = $message_media['dc_id'];
return $res; return $res;
case 'photoStrippedSize': case 'photoStrippedSize':
@ -634,16 +634,16 @@ trait Files
$res['thumb_size'] = $message_media['type']; $res['thumb_size'] = $message_media['type'];
if ($message_media['location']['_'] === 'fileLocationUnavailable') { if ($message_media['location']['_'] === 'fileLocationUnavailable') {
$res['name'] = Tools::unpack_signed_long_string($message_media['volume_id']).'_'.$message_media['local_id']; $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']).'_'.$message_media['local_id'];
$res['mime'] = $this->get_mime_from_buffer($res['data']); $res['mime'] = $this->getMimeFromBuffer($res['data']);
$res['ext'] = $this->get_extension_from_mime($res['mime']); $res['ext'] = $this->getExtensionFromMime($res['mime']);
} else { } else {
$res = \array_merge($res, yield $this->get_download_info_async($message_media['location'])); $res = \array_merge($res, yield $this->getDownloadInfo($message_media['location']));
} }
return $res; return $res;
case 'photoSize': case 'photoSize':
$res = yield $this->get_download_info_async($message_media['location']); $res = yield $this->getDownloadInfo($message_media['location']);
$res['thumb_size'] = $message_media['type']; $res['thumb_size'] = $message_media['type'];
//$res['thumb_size'] = $size; //$res['thumb_size'] = $size;
@ -656,7 +656,7 @@ trait Files
case 'fileLocationUnavailable': case 'fileLocationUnavailable':
throw new \danog\MadelineProto\Exception('File location unavailable'); throw new \danog\MadelineProto\Exception('File location unavailable');
case 'fileLocation': case 'fileLocation':
$res['name'] = Tools::unpack_signed_long_string($message_media['volume_id']).'_'.$message_media['local_id']; $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']).'_'.$message_media['local_id'];
$res['InputFileLocation'] = [ $res['InputFileLocation'] = [
'_' => 'inputFileLocation', '_' => 'inputFileLocation',
'volume_id' => $message_media['volume_id'], 'volume_id' => $message_media['volume_id'],
@ -668,14 +668,14 @@ trait Files
$message_media $message_media
), ),
]; ];
$res['ext'] = $this->get_extension_from_location($res['InputFileLocation'], '.jpg'); $res['ext'] = $this->getExtensionFromLocation($res['InputFileLocation'], '.jpg');
$res['mime'] = $this->get_mime_from_extension($res['ext'], 'image/jpeg'); $res['mime'] = $this->getMimeFromExtension($res['ext'], 'image/jpeg');
return $res; return $res;
case 'fileLocationToBeDeprecated': case 'fileLocationToBeDeprecated':
$res['name'] = Tools::unpack_signed_long_string($message_media['volume_id']).'_'.$message_media['local_id']; $res['name'] = Tools::unpackSignedLongString($message_media['volume_id']).'_'.$message_media['local_id'];
$res['ext'] = '.jpg'; $res['ext'] = '.jpg';
$res['mime'] = $this->get_mime_from_extension($res['ext'], 'image/jpeg'); $res['mime'] = $this->getMimeFromExtension($res['ext'], 'image/jpeg');
$res['InputFileLocation'] = [ $res['InputFileLocation'] = [
'_' => 'inputFileLocationTemp', // Will be overwritten '_' => 'inputFileLocationTemp', // Will be overwritten
'volume_id' => $message_media['volume_id'], 'volume_id' => $message_media['volume_id'],
@ -726,10 +726,10 @@ trait Files
]; ];
if (!isset($res['ext']) || $res['ext'] === '') { if (!isset($res['ext']) || $res['ext'] === '') {
$res['ext'] = $this->get_extension_from_location($res['InputFileLocation'], $this->get_extension_from_mime($message_media['document']['mime_type'])); $res['ext'] = $this->getExtensionFromLocation($res['InputFileLocation'], $this->getExtensionFromMime($message_media['document']['mime_type']));
} }
if (!isset($res['name']) || $res['name'] === '') { if (!isset($res['name']) || $res['name'] === '') {
$res['name'] = Tools::unpack_signed_long_string($message_media['document']['access_hash']); $res['name'] = Tools::unpackSignedLongString($message_media['document']['access_hash']);
} }
if (isset($message_media['document']['size'])) { if (isset($message_media['document']['size'])) {
$res['size'] = $message_media['document']['size']; $res['size'] = $message_media['document']['size'];
@ -757,7 +757,7 @@ trait Files
$message_media = $message_media->getFile(); $message_media = $message_media->getFile();
} }
$message_media = yield $this->get_download_info_async($message_media); $message_media = yield $this->getDownloadInfo($message_media);
$servefile = $_SERVER['REQUEST_METHOD'] !== 'HEAD'; $servefile = $_SERVER['REQUEST_METHOD'] !== 'HEAD';
@ -814,7 +814,7 @@ trait Files
}, $seek_start, $seek_end + 1); }, $seek_start, $seek_end + 1);
//analytics(true, $file_path, $MadelineProto->get_self()['id'], $dbuser, $dbpassword); //analytics(true, $file_path, $MadelineProto->get_self()['id'], $dbuser, $dbpassword);
$MadelineProto->API->getting_state = false; $MadelineProto->API->getting_state = false;
$MadelineProto->API->store_db([], true); $MadelineProto->API->storeDb([], true);
$MadelineProto->API->reset_session(); $MadelineProto->API->reset_session();
} else { } else {
if ($seek_start > 0 || $seek_end < $select['file_size'] - 1) { if ($seek_start > 0 || $seek_end < $select['file_size'] - 1) {
@ -835,22 +835,22 @@ trait Files
header('Content-Length: '.$info['size']); header('Content-Length: '.$info['size']);
header('Content-Type: '.$info['mime']); header('Content-Type: '.$info['mime']);
}*/ }*/
public function extract_photosize($photo) public function extractPhotosize($photo)
{ {
} }
public function download_to_dir_async($message_media, $dir, $cb = null) public function downloadToDir($message_media, $dir, $cb = null)
{ {
if (\is_object($dir) && $dir instanceof FileCallbackInterface) { if (\is_object($dir) && $dir instanceof FileCallbackInterface) {
$cb = $dir; $cb = $dir;
$dir = $dir->getFile(); $dir = $dir->getFile();
} }
$message_media = yield $this->get_download_info_async($message_media); $message_media = yield $this->getDownloadInfo($message_media);
return yield $this->download_to_file_async($message_media, $dir.'/'.$message_media['name'].$message_media['ext'], $cb); return yield $this->downloadToFile($message_media, $dir.'/'.$message_media['name'].$message_media['ext'], $cb);
} }
public function download_to_file_async($message_media, $file, $cb = null) public function downloadToFile($message_media, $file, $cb = null)
{ {
if (\is_object($file) && $file instanceof FileCallbackInterface) { if (\is_object($file) && $file instanceof FileCallbackInterface) {
$cb = $file; $cb = $file;
@ -861,7 +861,7 @@ trait Files
yield \touch($file); yield \touch($file);
} }
$file = \realpath($file); $file = \realpath($file);
$message_media = yield $this->get_download_info_async($message_media); $message_media = yield $this->getDownloadInfo($message_media);
StatCache::clear($file); StatCache::clear($file);
@ -872,7 +872,7 @@ trait Files
$unlock = yield $this->flock($file, LOCK_EX); $unlock = yield $this->flock($file, LOCK_EX);
try { try {
yield $this->download_to_stream_async($message_media, $stream, $cb, $size, -1); yield $this->downloadToStream($message_media, $stream, $cb, $size, -1);
} finally { } finally {
$unlock(); $unlock();
yield $stream->close(); yield $stream->close();
@ -881,9 +881,9 @@ trait Files
return $file; return $file;
} }
public function download_to_stream_async($message_media, $stream, $cb = null, $offset = 0, $end = -1) public function downloadToStream($message_media, $stream, $cb = null, $offset = 0, $end = -1)
{ {
$message_media = yield $this->get_download_info_async($message_media); $message_media = yield $this->getDownloadInfo($message_media);
if (\is_object($stream) && $stream instanceof FileCallbackInterface) { if (\is_object($stream) && $stream instanceof FileCallbackInterface) {
$cb = $stream; $cb = $stream;
@ -914,11 +914,11 @@ trait Files
return yield $stream->write($payload); return yield $stream->write($payload);
}; };
return yield $this->download_to_callable_async($message_media, $callable, $cb, $seekable, $offset, $end); return yield $this->downloadToCallable($message_media, $callable, $cb, $seekable, $offset, $end);
} }
public function download_to_callable_async($message_media, $callable, $cb = null, $parallelize = true, $offset = 0, $end = -1, int $part_size = null) public function downloadToCallable($message_media, $callable, $cb = null, $parallelize = true, $offset = 0, $end = -1, int $part_size = null)
{ {
$message_media = yield $this->get_download_info_async($message_media); $message_media = yield $this->getDownloadInfo($message_media);
if (\is_object($callable) && $callable instanceof FileCallbackInterface) { if (\is_object($callable) && $callable instanceof FileCallbackInterface) {
$cb = $callable; $cb = $callable;
@ -948,7 +948,7 @@ trait Files
if (isset($message_media['key'])) { if (isset($message_media['key'])) {
$digest = \hash('md5', $message_media['key'].$message_media['iv'], true); $digest = \hash('md5', $message_media['key'].$message_media['iv'], true);
$fingerprint = $this->unpack_signed_int(\substr($digest, 0, 4) ^ \substr($digest, 4, 4)); $fingerprint = $this->unpackSignedInt(\substr($digest, 0, 4) ^ \substr($digest, 4, 4));
if ($fingerprint !== $message_media['key_fingerprint']) { if ($fingerprint !== $message_media['key_fingerprint']) {
throw new \danog\MadelineProto\Exception('Fingerprint mismatch!'); throw new \danog\MadelineProto\Exception('Fingerprint mismatch!');
} }
@ -1006,7 +1006,7 @@ trait Files
$params[0]['previous_promise'] = new Success(true); $params[0]['previous_promise'] = new Success(true);
$start = \microtime(true); $start = \microtime(true);
$size = yield $this->download_part($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, \array_shift($params), $callable, $parallelize); $size = yield $this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, \array_shift($params), $callable, $parallelize);
if ($params) { if ($params) {
$previous_promise = new Success(true); $previous_promise = new Success(true);
@ -1014,7 +1014,7 @@ trait Files
$promises = []; $promises = [];
foreach ($params as $key => $param) { foreach ($params as $key => $param) {
$param['previous_promise'] = $previous_promise; $param['previous_promise'] = $previous_promise;
$previous_promise = $this->call($this->download_part($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $parallelize)); $previous_promise = $this->call($this->downloadPart($message_media, $cdn, $datacenter, $old_dc, $ige, $cb, $param, $callable, $parallelize));
$previous_promise->onResolve(static function ($e, $res) use (&$size) { $previous_promise->onResolve(static function ($e, $res) use (&$size) {
if ($res) { if ($res) {
$size += $res; $size += $res;
@ -1043,13 +1043,13 @@ trait Files
$this->logger->logger("Total download speed: $speed mbps"); $this->logger->logger("Total download speed: $speed mbps");
if ($cdn) { if ($cdn) {
$this->clear_cdn_hashes($message_media['file_token']); $this->clearCdnHashes($message_media['file_token']);
} }
return true; return true;
} }
private function download_part(&$message_media, &$cdn, &$datacenter, &$old_dc, &$ige, $cb, $offset, $callable, $seekable, $postpone = false) private function downloadPart(&$message_media, &$cdn, &$datacenter, &$old_dc, &$ige, $cb, $offset, $callable, $seekable, $postpone = false)
{ {
static $method = [ static $method = [
false => 'upload.getFile', // non-cdn false => 'upload.getFile', // non-cdn
@ -1067,7 +1067,7 @@ trait Files
} }
try { try {
$res = yield $this->method_call_async_read( $res = yield $this->methodCallAsyncRead(
$method[$cdn], $method[$cdn],
$basic_param + $offset, $basic_param + $offset,
[ [
@ -1082,7 +1082,7 @@ trait Files
if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0) { if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0) {
if (isset($message_media['MessageMedia']) && !$this->authorization['user']['bot'] && $this->settings['download']['report_broken_media']) { if (isset($message_media['MessageMedia']) && !$this->authorization['user']['bot'] && $this->settings['download']['report_broken_media']) {
try { try {
yield $this->method_call_async_read('messages.sendMedia', ['peer' => 'support', 'media' => $message_media['MessageMedia'], 'message' => "I can't download this file, could you please help?"], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendMedia', ['peer' => 'support', 'media' => $message_media['MessageMedia'], 'message' => "I can't download this file, could you please help?"], ['datacenter' => $this->datacenter->curdc]);
} catch (RPCErrorException $e) { } catch (RPCErrorException $e) {
$this->logger->logger('An error occurred while reporting the broken file: '.$e->rpc, Logger::FATAL_ERROR); $this->logger->logger('An error occurred while reporting the broken file: '.$e->rpc, Logger::FATAL_ERROR);
} catch (Exception $e) { } catch (Exception $e) {
@ -1110,15 +1110,15 @@ trait Files
$datacenter = $res['dc_id'].'_cdn'; $datacenter = $res['dc_id'].'_cdn';
if (!$this->datacenter->has($datacenter)) { if (!$this->datacenter->has($datacenter)) {
$this->config['expires'] = -1; $this->config['expires'] = -1;
yield $this->get_config_async([], ['datacenter' => $this->datacenter->curdc]); yield $this->getConfig([], ['datacenter' => $this->datacenter->curdc]);
} }
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['stored_on_cdn'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['stored_on_cdn'], \danog\MadelineProto\Logger::NOTICE);
} elseif ($res['_'] === 'upload.cdnFileReuploadNeeded') { } elseif ($res['_'] === 'upload.cdnFileReuploadNeeded') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['cdn_reupload'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['cdn_reupload'], \danog\MadelineProto\Logger::NOTICE);
yield $this->get_config_async([], ['datacenter' => $this->datacenter->curdc]); yield $this->getConfig([], ['datacenter' => $this->datacenter->curdc]);
try { try {
$this->add_cdn_hashes($message_media['file_token'], yield $this->method_call_async_read('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc])); $this->addCdnHashes($message_media['file_token'], yield $this->methodCallAsyncRead('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc]));
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
switch ($e->rpc) { switch ($e->rpc) {
case 'FILE_TOKEN_INVALID': case 'FILE_TOKEN_INVALID':
@ -1139,13 +1139,13 @@ trait Files
$res['bytes'] === '' && $res['bytes'] === '' &&
$this->datacenter->has(++$datacenter) $this->datacenter->has(++$datacenter)
) { ) {
$res = yield $this->method_call_async_read('upload.getFile', $basic_param + $offset, ['heavy' => true, 'file' => true, 'FloodWaitLimit' => 0, 'datacenter' => $datacenter]); $res = yield $this->methodCallAsyncRead('upload.getFile', $basic_param + $offset, ['heavy' => true, 'file' => true, 'FloodWaitLimit' => 0, 'datacenter' => $datacenter]);
} }
if (isset($message_media['cdn_key'])) { if (isset($message_media['cdn_key'])) {
$ivec = \substr($message_media['cdn_iv'], 0, 12).\pack('N', $offset['offset'] >> 4); $ivec = \substr($message_media['cdn_iv'], 0, 12).\pack('N', $offset['offset'] >> 4);
$res['bytes'] = $this->ctr_encrypt($res['bytes'], $message_media['cdn_key'], $ivec); $res['bytes'] = $this->ctrEncrypt($res['bytes'], $message_media['cdn_key'], $ivec);
$this->check_cdn_hash($message_media['file_token'], $offset['offset'], $res['bytes'], $old_dc); $this->checkCdnHash($message_media['file_token'], $offset['offset'], $res['bytes'], $old_dc);
} }
if (isset($message_media['key'])) { if (isset($message_media['key'])) {
$res['bytes'] = $ige->decrypt($res['bytes']); $res['bytes'] = $ige->decrypt($res['bytes']);
@ -1165,7 +1165,7 @@ trait Files
private $cdn_hashes = []; private $cdn_hashes = [];
private function add_cdn_hashes($file, $hashes) private function addCdnHashes($file, $hashes)
{ {
if (!isset($this->cdn_hashes[$file])) { if (!isset($this->cdn_hashes[$file])) {
$this->cdn_hashes = []; $this->cdn_hashes = [];
@ -1175,11 +1175,11 @@ trait Files
} }
} }
private function check_cdn_hash($file, $offset, $data, &$datacenter) private function checkCdnHash($file, $offset, $data, &$datacenter)
{ {
while (\strlen($data)) { while (\strlen($data)) {
if (!isset($this->cdn_hashes[$file][$offset])) { if (!isset($this->cdn_hashes[$file][$offset])) {
$this->add_cdn_hashes($file, yield $this->method_call_async_read('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter])); $this->addCdnHashes($file, yield $this->methodCallAsyncRead('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter]));
} }
if (!isset($this->cdn_hashes[$file][$offset])) { if (!isset($this->cdn_hashes[$file][$offset])) {
throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset '.$offset); throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset '.$offset);
@ -1194,7 +1194,7 @@ trait Files
return true; return true;
} }
private function clear_cdn_hashes($file) private function clearCdnHashes($file)
{ {
unset($this->cdn_hashes[$file]); unset($this->cdn_hashes[$file]);

View File

@ -181,7 +181,7 @@ class MinDatabase implements TLCallback
$peers[$location['from_id']] = true; $peers[$location['from_id']] = true;
} }
if (isset($location['channel_id'])) { if (isset($location['channel_id'])) {
$peers[$this->API->to_supergroup($location['channel_id'])] = true; $peers[$this->API->toSupergroup($location['channel_id'])] = true;
} }
break; break;
case 'messageActionChatCreate': case 'messageActionChatCreate':
@ -191,13 +191,13 @@ class MinDatabase implements TLCallback
} }
break; break;
case 'message': case 'message':
$peers[$this->API->get_id($location['to_id'])] = true; $peers[$this->API->getId($location['to_id'])] = true;
if (isset($location['from_id'])) { if (isset($location['from_id'])) {
$peers[$location['from_id']] = true; $peers[$location['from_id']] = true;
} }
break; break;
default: default:
$peers[$this->API->get_id($location)] = true; $peers[$this->API->getId($location)] = true;
} }
$this->API->logger->logger("Caching peer location info from location from {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $this->API->logger->logger("Caching peer location info from location from {$location['_']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$key = \count($this->cache) - 1; $key = \count($this->cache) - 1;
@ -224,7 +224,7 @@ class MinDatabase implements TLCallback
switch ($data['_']) { switch ($data['_']) {
case 'message': case 'message':
case 'messageService': case 'messageService':
$origin['peer'] = $this->API->get_id($data); $origin['peer'] = $this->API->getId($data);
$origin['msg_id'] = $data['id']; $origin['msg_id'] = $data['id'];
break; break;
default: default:
@ -244,11 +244,11 @@ class MinDatabase implements TLCallback
if (!($object['min'] ?? false)) { if (!($object['min'] ?? false)) {
return $object; return $object;
} }
$id = $this->API->get_id($object); $id = $this->API->getId($object);
if (isset($this->db[$id])) { if (isset($this->db[$id])) {
$new = \array_merge($object, $this->db[$id]); $new = \array_merge($object, $this->db[$id]);
$new['_'] .= 'FromMessage'; $new['_'] .= 'FromMessage';
$new['peer'] = (yield $this->API->get_info_async($new['peer']))['InputPeer']; $new['peer'] = (yield $this->API->getInfo($new['peer']))['InputPeer'];
if ($new['peer']['min']) { if ($new['peer']['min']) {
$this->API->logger->logger("Don't have origin peer subinfo with min peer $id, this may fail"); $this->API->logger->logger("Don't have origin peer subinfo with min peer $id, this may fail");
return $object; return $object;

View File

@ -111,7 +111,7 @@ class PasswordCalculator
case 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow': case 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow':
$object['current_algo']['g'] = new BigInteger($object['current_algo']['g']); $object['current_algo']['g'] = new BigInteger($object['current_algo']['g']);
$object['current_algo']['p'] = new BigInteger((string) $object['current_algo']['p'], 256); $object['current_algo']['p'] = new BigInteger((string) $object['current_algo']['p'], 256);
$this->check_p_g($object['current_algo']['p'], $object['current_algo']['g']); $this->checkPG($object['current_algo']['p'], $object['current_algo']['g']);
$object['current_algo']['gForHash'] = \str_pad($object['current_algo']['g']->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $object['current_algo']['gForHash'] = \str_pad($object['current_algo']['g']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
$object['current_algo']['pForHash'] = \str_pad($object['current_algo']['p']->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $object['current_algo']['pForHash'] = \str_pad($object['current_algo']['p']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
@ -142,7 +142,7 @@ class PasswordCalculator
case 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow': case 'passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow':
$object['new_algo']['g'] = new BigInteger($object['new_algo']['g']); $object['new_algo']['g'] = new BigInteger($object['new_algo']['g']);
$object['new_algo']['p'] = new BigInteger((string) $object['new_algo']['p'], 256); $object['new_algo']['p'] = new BigInteger((string) $object['new_algo']['p'], 256);
$this->check_p_g($object['new_algo']['p'], $object['new_algo']['g']); $this->checkPG($object['new_algo']['p'], $object['new_algo']['g']);
$object['new_algo']['gForHash'] = \str_pad($object['new_algo']['g']->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $object['new_algo']['gForHash'] = \str_pad($object['new_algo']['g']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
$object['new_algo']['pForHash'] = \str_pad($object['new_algo']['p']->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $object['new_algo']['pForHash'] = \str_pad($object['new_algo']['p']->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
@ -226,7 +226,7 @@ class PasswordCalculator
$a = new BigInteger($this->random(2048 / 8), 256); $a = new BigInteger($this->random(2048 / 8), 256);
$A = $g->powMod($a, $p); $A = $g->powMod($a, $p);
$this->check_G($A, $p); $this->checkG($A, $p);
$AForHash = \str_pad($A->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $AForHash = \str_pad($A->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
$b_kg_x = $B->powMod(Magic::$one, $p)->subtract($kg_x); $b_kg_x = $B->powMod(Magic::$one, $p)->subtract($kg_x);

View File

@ -32,29 +32,29 @@ trait PeerHandler
public $caching_full_info = []; public $caching_full_info = [];
public function to_supergroup($id) public function toSupergroup($id)
{ {
return -($id + \pow(10, (int) \floor(\log($id, 10) + 3))); return -($id + \pow(10, (int) \floor(\log($id, 10) + 3)));
} }
public function from_supergroup($id) public function fromSupergroup($id)
{ {
return -$id - \pow(10, (int) \floor(\log(-$id, 10))); return -$id - \pow(10, (int) \floor(\log(-$id, 10)));
} }
public function is_supergroup($id) public function isSupergroup($id)
{ {
$log = \log(-$id, 10); $log = \log(-$id, 10);
return ($log - \intval($log)) * 1000 < 10; return ($log - \intval($log)) * 1000 < 10;
} }
public function add_support($support) public function addSupport($support)
{ {
$this->supportUser = $support['user']['id']; $this->supportUser = $support['user']['id'];
} }
public function add_user($user) public function addUser($user)
{ {
if (!isset($user['access_hash']) && !($user['min'] ?? false)) { if (!isset($user['access_hash']) && !($user['min'] ?? false)) {
if (isset($this->chats[$user['id']]['access_hash']) && $this->chats[$user['id']]['access_hash']) { if (isset($this->chats[$user['id']]['access_hash']) && $this->chats[$user['id']]['access_hash']) {
@ -65,10 +65,10 @@ trait PeerHandler
if (isset($user['username']) && !isset($this->caching_simple_username[$user['username']])) { if (isset($user['username']) && !isset($this->caching_simple_username[$user['username']])) {
$this->caching_possible_username[$user['id']] = $user['username']; $this->caching_possible_username[$user['id']] = $user['username'];
} }
$this->cache_pwr_chat($user['id'], false, true); $this->cachePwrChat($user['id'], false, true);
} elseif (isset($user['username']) && !isset($this->chats[$user['id']]) && !isset($this->caching_simple_username[$user['username']])) { } elseif (isset($user['username']) && !isset($this->chats[$user['id']]) && !isset($this->caching_simple_username[$user['username']])) {
$this->logger->logger("No access hash with user {$user['id']}, trying to fetch by username..."); $this->logger->logger("No access hash with user {$user['id']}, trying to fetch by username...");
$this->cache_pwr_chat($user['username'], false, true); $this->cachePwrChat($user['username'], false, true);
} else { } else {
$this->logger->logger("No access hash with user {$user['id']}, tried and failed to fetch data..."); $this->logger->logger("No access hash with user {$user['id']}, tried and failed to fetch data...");
} }
@ -89,7 +89,7 @@ trait PeerHandler
} }
$this->chats[$user['id']] = $user; $this->chats[$user['id']] = $user;
$this->cache_pwr_chat($user['id'], false, true); $this->cachePwrChat($user['id'], false, true);
} }
break; break;
case 'userEmpty': case 'userEmpty':
@ -100,7 +100,7 @@ trait PeerHandler
} }
} }
public function add_chat_async($chat) public function addChat($chat)
{ {
switch ($chat['_']) { switch ($chat['_']) {
case 'chat': case 'chat':
@ -109,14 +109,14 @@ trait PeerHandler
if (!isset($this->chats[-$chat['id']]) || $this->chats[-$chat['id']] !== $chat) { if (!isset($this->chats[-$chat['id']]) || $this->chats[-$chat['id']] !== $chat) {
$this->logger->logger("Updated chat -{$chat['id']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $this->logger->logger("Updated chat -{$chat['id']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE);
$this->chats[-$chat['id']] = $chat; $this->chats[-$chat['id']] = $chat;
$this->cache_pwr_chat(-$chat['id'], $this->settings['peer']['full_fetch'], true); $this->cachePwrChat(-$chat['id'], $this->settings['peer']['full_fetch'], true);
} }
break; break;
case 'channelEmpty': case 'channelEmpty':
break; break;
case 'channel': case 'channel':
case 'channelForbidden': case 'channelForbidden':
$bot_api_id = $this->to_supergroup($chat['id']); $bot_api_id = $this->toSupergroup($chat['id']);
if (!isset($chat['access_hash'])) { if (!isset($chat['access_hash'])) {
if (!isset($this->caching_simple[$bot_api_id]) && !(isset($chat['username']) && isset($this->caching_simple_username[$chat['username']]))) { if (!isset($this->caching_simple[$bot_api_id]) && !(isset($chat['username']) && isset($this->caching_simple_username[$chat['username']]))) {
$this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, trying to fetch by ID..."); $this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, trying to fetch by ID...");
@ -124,10 +124,10 @@ trait PeerHandler
$this->caching_possible_username[$bot_api_id] = $chat['username']; $this->caching_possible_username[$bot_api_id] = $chat['username'];
} }
$this->cache_pwr_chat($bot_api_id, false, true); $this->cachePwrChat($bot_api_id, false, true);
} elseif (isset($chat['username']) && !isset($this->chats[$bot_api_id]) && !isset($this->caching_simple_username[$chat['username']])) { } elseif (isset($chat['username']) && !isset($this->chats[$bot_api_id]) && !isset($this->caching_simple_username[$chat['username']])) {
$this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, trying to fetch by username..."); $this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, trying to fetch by username...");
$this->cache_pwr_chat($chat['username'], false, true); $this->cachePwrChat($chat['username'], false, true);
} else { } else {
$this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, tried and failed to fetch data..."); $this->logger->logger("No access hash with {$chat['_']} {$bot_api_id}, tried and failed to fetch data...");
} }
@ -150,8 +150,8 @@ trait PeerHandler
$this->chats[$bot_api_id] = $chat; $this->chats[$bot_api_id] = $chat;
if ($this->settings['peer']['full_fetch'] && (!isset($this->full_chats[$bot_api_id]) || $this->full_chats[$bot_api_id]['full']['participants_count'] !== (yield $this->get_full_info_async($bot_api_id))['full']['participants_count'])) { if ($this->settings['peer']['full_fetch'] && (!isset($this->full_chats[$bot_api_id]) || $this->full_chats[$bot_api_id]['full']['participants_count'] !== (yield $this->getFullInfo($bot_api_id))['full']['participants_count'])) {
$this->cache_pwr_chat($bot_api_id, $this->settings['peer']['full_fetch'], true); $this->cachePwrChat($bot_api_id, $this->settings['peer']['full_fetch'], true);
} }
} }
break; break;
@ -161,11 +161,11 @@ trait PeerHandler
} }
} }
public function cache_pwr_chat($id, $full_fetch, $send) public function cachePwrChat($id, $full_fetch, $send)
{ {
$this->callFork((function () use ($id, $full_fetch, $send) { $this->callFork((function () use ($id, $full_fetch, $send) {
try { try {
yield $this->get_pwr_chat_async($id, $full_fetch, $send); yield $this->getPwrChat($id, $full_fetch, $send);
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger('While caching: '.$e->getMessage(), \danog\MadelineProto\Logger::WARNING); $this->logger->logger('While caching: '.$e->getMessage(), \danog\MadelineProto\Logger::WARNING);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
@ -174,10 +174,10 @@ trait PeerHandler
})()); })());
} }
public function peer_isset_async($id) public function peerIsset($id)
{ {
try { try {
return isset($this->chats[(yield $this->get_info_async($id))['bot_api_id']]); return isset($this->chats[(yield $this->getInfo($id))['bot_api_id']]);
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
return false; return false;
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
@ -192,12 +192,12 @@ trait PeerHandler
} }
} }
public function entities_peer_isset_async($entities) public function entitiesPeerIsset($entities)
{ {
try { try {
foreach ($entities as $entity) { foreach ($entities as $entity) {
if ($entity['_'] === 'messageEntityMentionName' || $entity['_'] === 'inputMessageEntityMentionName') { if ($entity['_'] === 'messageEntityMentionName' || $entity['_'] === 'inputMessageEntityMentionName') {
if (!yield $this->peer_isset_async($entity['user_id'])) { if (!yield $this->peerIsset($entity['user_id'])) {
return false; return false;
} }
} }
@ -209,13 +209,13 @@ trait PeerHandler
return true; return true;
} }
public function fwd_peer_isset_async($fwd) public function fwdPeerIsset($fwd)
{ {
try { try {
if (isset($fwd['user_id']) && !yield $this->peer_isset_async($fwd['user_id'])) { if (isset($fwd['user_id']) && !yield $this->peerIsset($fwd['user_id'])) {
return false; return false;
} }
if (isset($fwd['channel_id']) && !yield $this->peer_isset_async($this->to_supergroup($fwd['channel_id']))) { if (isset($fwd['channel_id']) && !yield $this->peerIsset($this->toSupergroup($fwd['channel_id']))) {
return false; return false;
} }
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
@ -225,7 +225,7 @@ trait PeerHandler
return true; return true;
} }
public function get_folder_id($id) public function getFolderId($id)
{ {
if (!\is_array($id)) { if (!\is_array($id)) {
return null; return null;
@ -235,7 +235,7 @@ trait PeerHandler
} }
return $id['folder_id']; return $id['folder_id'];
} }
public function get_id($id) public function getId($id)
{ {
if (\is_array($id)) { if (\is_array($id)) {
switch ($id['_']) { switch ($id['_']) {
@ -254,7 +254,7 @@ trait PeerHandler
case 'updateChatDefaultBannedRights': case 'updateChatDefaultBannedRights':
case 'folderPeer': case 'folderPeer':
case 'inputFolderPeer': case 'inputFolderPeer':
return $this->get_id($id['peer']); return $this->getId($id['peer']);
case 'inputUserFromMessage': case 'inputUserFromMessage':
case 'inputPeerUserFromMessage': case 'inputPeerUserFromMessage':
@ -262,7 +262,7 @@ trait PeerHandler
case 'inputChannelFromMessage': case 'inputChannelFromMessage':
case 'inputPeerChannelFromMessage': case 'inputPeerChannelFromMessage':
return $this->to_supergroup($id['channel_id']); return $this->toSupergroup($id['channel_id']);
case 'inputUserSelf': case 'inputUserSelf':
case 'inputPeerSelf': case 'inputPeerSelf':
@ -289,15 +289,15 @@ trait PeerHandler
case 'channelForbidden': case 'channelForbidden':
case 'channel': case 'channel':
case 'channelFull': case 'channelFull':
return $this->to_supergroup($id['id']); return $this->toSupergroup($id['id']);
case 'inputPeerChannel': case 'inputPeerChannel':
case 'inputChannel': case 'inputChannel':
case 'peerChannel': case 'peerChannel':
return $this->to_supergroup($id['channel_id']); return $this->toSupergroup($id['channel_id']);
case 'message': case 'message':
case 'messageService': case 'messageService':
if (!isset($id['from_id']) || $id['to_id']['_'] !== 'peerUser' || $id['to_id']['user_id'] !== $this->authorization['user']['id']) { if (!isset($id['from_id']) || $id['to_id']['_'] !== 'peerUser' || $id['to_id']['user_id'] !== $this->authorization['user']['id']) {
return $this->get_id($id['to_id']); return $this->getId($id['to_id']);
} }
return $id['from_id']; return $id['from_id'];
@ -312,7 +312,7 @@ trait PeerHandler
case 'updateDeleteChannelMessages': case 'updateDeleteChannelMessages':
case 'updateChannelPinnedMessage': case 'updateChannelPinnedMessage':
case 'updateChannelTooLong': case 'updateChannelTooLong':
return $this->to_supergroup($id['channel_id']); return $this->toSupergroup($id['channel_id']);
case 'updateChatParticipants': case 'updateChatParticipants':
$id = $id['participants']; $id = $id['participants'];
// no break // no break
@ -343,12 +343,12 @@ trait PeerHandler
return $id->getOtherID(); return $id->getOtherID();
case 'updateReadHistoryInbox': case 'updateReadHistoryInbox':
case 'updateReadHistoryOutbox': case 'updateReadHistoryOutbox':
return $this->get_id($id['peer']); return $this->getId($id['peer']);
case 'updateNewMessage': case 'updateNewMessage':
case 'updateNewChannelMessage': case 'updateNewChannelMessage':
case 'updateEditMessage': case 'updateEditMessage':
case 'updateEditChannelMessage': case 'updateEditChannelMessage':
return $this->get_id($id['message']); return $this->getId($id['message']);
default: default:
throw new \danog\MadelineProto\Exception('Invalid constructor given '.\var_export($id, true)); throw new \danog\MadelineProto\Exception('Invalid constructor given '.\var_export($id, true));
} }
@ -356,7 +356,7 @@ trait PeerHandler
if (\is_string($id)) { if (\is_string($id)) {
if (\strpos($id, '#') !== false) { if (\strpos($id, '#') !== false) {
if (\preg_match('/^channel#(\d*)/', $id, $matches)) { if (\preg_match('/^channel#(\d*)/', $id, $matches)) {
return $this->to_supergroup($matches[1]); return $this->toSupergroup($matches[1]);
} }
if (\preg_match('/^chat#(\d*)/', $id, $matches)) { if (\preg_match('/^chat#(\d*)/', $id, $matches)) {
$id = '-'.$matches[1]; $id = '-'.$matches[1];
@ -377,16 +377,16 @@ trait PeerHandler
return false; return false;
} }
public function get_info_async($id, $recursive = true) public function getInfo($id, $recursive = true)
{ {
if (\is_array($id)) { if (\is_array($id)) {
switch ($id['_']) { switch ($id['_']) {
case 'updateEncryption': case 'updateEncryption':
return $this->get_secret_chat($id['chat']['id']); return $this->getSecretChat($id['chat']['id']);
case 'inputEncryptedChat': case 'inputEncryptedChat':
case 'updateEncryptedChatTyping': case 'updateEncryptedChatTyping':
case 'updateEncryptedMessagesRead': case 'updateEncryptedMessagesRead':
return $this->get_secret_chat($id['chat_id']); return $this->getSecretChat($id['chat_id']);
case 'updateNewEncryptedMessage': case 'updateNewEncryptedMessage':
$id = $id['message']; $id = $id['message'];
// no break // no break
@ -400,8 +400,8 @@ trait PeerHandler
return $this->secret_chats[$id]; return $this->secret_chats[$id];
} }
} }
$folder_id = $this->get_folder_id($id); $folder_id = $this->getFolderId($id);
$try_id = $this->get_id($id); $try_id = $this->getId($id);
if ($try_id !== false) { if ($try_id !== false) {
$id = $try_id; $id = $try_id;
} }
@ -414,13 +414,13 @@ trait PeerHandler
$this->logger->logger("Try fetching $id with access hash 0"); $this->logger->logger("Try fetching $id with access hash 0");
$this->caching_simple[$id] = true; $this->caching_simple[$id] = true;
if ($id < 0) { if ($id < 0) {
if ($this->is_supergroup($id)) { if ($this->isSupergroup($id)) {
yield $this->method_call_async_read('channels.getChannels', ['id' => [['access_hash' => 0, 'channel_id' => $this->from_supergroup($id), '_' => 'inputChannel']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('channels.getChannels', ['id' => [['access_hash' => 0, 'channel_id' => $this->fromSupergroup($id), '_' => 'inputChannel']]], ['datacenter' => $this->datacenter->curdc]);
} else { } else {
yield $this->method_call_async_read('messages.getFullChat', ['chat_id' => -$id], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.getFullChat', ['chat_id' => -$id], ['datacenter' => $this->datacenter->curdc]);
} }
} else { } else {
yield $this->method_call_async_read('users.getUsers', ['id' => [['access_hash' => 0, 'user_id' => $id, '_' => 'inputUser']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('users.getUsers', ['id' => [['access_hash' => 0, 'user_id' => $id, '_' => 'inputUser']]], ['datacenter' => $this->datacenter->curdc]);
} }
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING); $this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
@ -439,9 +439,9 @@ trait PeerHandler
$this->logger->logger("Only have min peer for $id in database, trying to fetch full info"); $this->logger->logger("Only have min peer for $id in database, trying to fetch full info");
try { try {
if ($id < 0) { if ($id < 0) {
yield $this->method_call_async_read('channels.getChannels', ['id' => [$this->gen_all($this->chats[$id], $folder_id)['InputChannel']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('channels.getChannels', ['id' => [$this->genAll($this->chats[$id], $folder_id)['InputChannel']]], ['datacenter' => $this->datacenter->curdc]);
} else { } else {
yield $this->method_call_async_read('users.getUsers', ['id' => [$this->gen_all($this->chats[$id], $folder_id)['InputUser']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('users.getUsers', ['id' => [$this->genAll($this->chats[$id], $folder_id)['InputUser']]], ['datacenter' => $this->datacenter->curdc]);
} }
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING); $this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
@ -453,7 +453,7 @@ trait PeerHandler
} }
try { try {
return $this->gen_all($this->chats[$id], $folder_id); return $this->genAll($this->chats[$id], $folder_id);
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
if ($e->getMessage() === 'This peer is not present in the internal peer database') { if ($e->getMessage() === 'This peer is not present in the internal peer database') {
unset($this->chats[$id]); unset($this->chats[$id]);
@ -471,9 +471,9 @@ trait PeerHandler
$this->logger->logger($e); $this->logger->logger($e);
} }
if (isset($dbres['ok']) && $dbres['ok']) { if (isset($dbres['ok']) && $dbres['ok']) {
yield $this->resolve_username_async('@'.$dbres['result']); yield $this->resolveUsername('@'.$dbres['result']);
return yield $this->get_info_async($id, false); return yield $this->getInfo($id, false);
} }
} }
if ($tried_simple && isset($this->caching_possible_username[$id])) { if ($tried_simple && isset($this->caching_possible_username[$id])) {
@ -482,7 +482,7 @@ trait PeerHandler
$user = $this->caching_possible_username[$id]; $user = $this->caching_possible_username[$id];
unset($this->caching_possible_username[$id]); unset($this->caching_possible_username[$id]);
return yield $this->get_info_async($user); return yield $this->getInfo($user);
} }
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database'); throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
@ -491,23 +491,23 @@ trait PeerHandler
if ($matches[1] === '') { if ($matches[1] === '') {
$id = $matches[2]; $id = $matches[2];
} else { } else {
$invite = yield $this->method_call_async_read('messages.checkChatInvite', ['hash' => $matches[2]], ['datacenter' => $this->datacenter->curdc]); $invite = yield $this->methodCallAsyncRead('messages.checkChatInvite', ['hash' => $matches[2]], ['datacenter' => $this->datacenter->curdc]);
if (isset($invite['chat'])) { if (isset($invite['chat'])) {
return yield $this->get_info_async($invite['chat']); return yield $this->getInfo($invite['chat']);
} }
throw new \danog\MadelineProto\Exception('You have not joined this chat'); throw new \danog\MadelineProto\Exception('You have not joined this chat');
} }
} }
$id = \strtolower(\str_replace('@', '', $id)); $id = \strtolower(\str_replace('@', '', $id));
if ($id === 'me') { if ($id === 'me') {
return yield $this->get_info_async($this->authorization['user']['id']); return yield $this->getInfo($this->authorization['user']['id']);
} }
if ($id === 'support') { if ($id === 'support') {
if (!$this->supportUser) { if (!$this->supportUser) {
yield $this->method_call_async_read('help.getSupport', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); yield $this->methodCallAsyncRead('help.getSupport', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]);
} }
return yield $this->get_info_async($this->supportUser); return yield $this->getInfo($this->supportUser);
} }
foreach ($this->chats as $bot_api_id => $chat) { foreach ($this->chats as $bot_api_id => $chat) {
if (isset($chat['username']) && \strtolower($chat['username']) === $id) { if (isset($chat['username']) && \strtolower($chat['username']) === $id) {
@ -516,9 +516,9 @@ trait PeerHandler
$this->logger->logger("Only have min peer for $bot_api_id in database, trying to fetch full info"); $this->logger->logger("Only have min peer for $bot_api_id in database, trying to fetch full info");
try { try {
if ($bot_api_id < 0) { if ($bot_api_id < 0) {
yield $this->method_call_async_read('channels.getChannels', ['id' => [$this->gen_all($this->chats[$bot_api_id], $folder_id)['InputChannel']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('channels.getChannels', ['id' => [$this->genAll($this->chats[$bot_api_id], $folder_id)['InputChannel']]], ['datacenter' => $this->datacenter->curdc]);
} else { } else {
yield $this->method_call_async_read('users.getUsers', ['id' => [$this->gen_all($this->chats[$bot_api_id], $folder_id)['InputUser']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('users.getUsers', ['id' => [$this->genAll($this->chats[$bot_api_id], $folder_id)['InputUser']]], ['datacenter' => $this->datacenter->curdc]);
} }
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING); $this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING);
@ -529,21 +529,21 @@ trait PeerHandler
} }
} }
return $this->gen_all($this->chats[$bot_api_id], $folder_id); return $this->genAll($this->chats[$bot_api_id], $folder_id);
} }
} }
if ($recursive) { if ($recursive) {
yield $this->resolve_username_async($id); yield $this->resolveUsername($id);
return yield $this->get_info_async($id, false); return yield $this->getInfo($id, false);
} }
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database'); throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
} }
public function gen_all($constructor, $folder_id = null) public function genAll($constructor, $folder_id = null)
{ {
$res = [$this->constructors->find_by_predicate($constructor['_'])['type'] => $constructor]; $res = [$this->constructors->findByPredicate($constructor['_'])['type'] => $constructor];
switch ($constructor['_']) { switch ($constructor['_']) {
case 'user': case 'user':
if ($constructor['self']) { if ($constructor['self']) {
@ -588,7 +588,7 @@ trait PeerHandler
$res['InputNotifyPeer'] = ['_' => 'inputNotifyPeer', 'peer' => $res['InputPeer']]; $res['InputNotifyPeer'] = ['_' => 'inputNotifyPeer', 'peer' => $res['InputPeer']];
$res['InputChannel'] = ['_' => 'inputChannel', 'channel_id' => $constructor['id'], 'access_hash' => $constructor['access_hash'], 'min' => $constructor['min']]; $res['InputChannel'] = ['_' => 'inputChannel', 'channel_id' => $constructor['id'], 'access_hash' => $constructor['access_hash'], 'min' => $constructor['min']];
$res['channel_id'] = $constructor['id']; $res['channel_id'] = $constructor['id'];
$res['bot_api_id'] = $this->to_supergroup($constructor['id']); $res['bot_api_id'] = $this->toSupergroup($constructor['id']);
$res['type'] = $constructor['megagroup'] ? 'supergroup' : 'channel'; $res['type'] = $constructor['megagroup'] ? 'supergroup' : 'channel';
break; break;
case 'channelForbidden': case 'channelForbidden':
@ -603,28 +603,28 @@ trait PeerHandler
return $res; return $res;
} }
public function full_chat_last_updated($id) public function fullChatLastUpdated($id)
{ {
return isset($this->full_chats[$id]['last_update']) ? $this->full_chats[$id]['last_update'] : 0; return isset($this->full_chats[$id]['last_update']) ? $this->full_chats[$id]['last_update'] : 0;
} }
public function get_full_info_async($id) public function getFullInfo($id)
{ {
$partial = yield $this->get_info_async($id); $partial = yield $this->getInfo($id);
if (\time() - $this->full_chat_last_updated($partial['bot_api_id']) < (isset($this->settings['peer']['full_info_cache_time']) ? $this->settings['peer']['full_info_cache_time'] : 0)) { if (\time() - $this->fullChatLastUpdated($partial['bot_api_id']) < (isset($this->settings['peer']['full_info_cache_time']) ? $this->settings['peer']['full_info_cache_time'] : 0)) {
return \array_merge($partial, $this->full_chats[$partial['bot_api_id']]); return \array_merge($partial, $this->full_chats[$partial['bot_api_id']]);
} }
switch ($partial['type']) { switch ($partial['type']) {
case 'user': case 'user':
case 'bot': case 'bot':
$full = yield $this->method_call_async_read('users.getFullUser', ['id' => $partial['InputUser']], ['datacenter' => $this->datacenter->curdc]); $full = yield $this->methodCallAsyncRead('users.getFullUser', ['id' => $partial['InputUser']], ['datacenter' => $this->datacenter->curdc]);
break; break;
case 'chat': case 'chat':
$full = (yield $this->method_call_async_read('messages.getFullChat', $partial, ['datacenter' => $this->datacenter->curdc]))['full_chat']; $full = (yield $this->methodCallAsyncRead('messages.getFullChat', $partial, ['datacenter' => $this->datacenter->curdc]))['full_chat'];
break; break;
case 'channel': case 'channel':
case 'supergroup': case 'supergroup':
$full = (yield $this->method_call_async_read('channels.getFullChannel', ['channel' => $partial['InputChannel']], ['datacenter' => $this->datacenter->curdc]))['full_chat']; $full = (yield $this->methodCallAsyncRead('channels.getFullChannel', ['channel' => $partial['InputChannel']], ['datacenter' => $this->datacenter->curdc]))['full_chat'];
break; break;
} }
@ -633,14 +633,14 @@ trait PeerHandler
$res['last_update'] = \time(); $res['last_update'] = \time();
$this->full_chats[$partial['bot_api_id']] = $res; $this->full_chats[$partial['bot_api_id']] = $res;
$partial = yield $this->get_info_async($id); $partial = yield $this->getInfo($id);
return \array_merge($partial, $res); return \array_merge($partial, $res);
} }
public function get_pwr_chat_async($id, $fullfetch = true, $send = true) public function getPwrChat($id, $fullfetch = true, $send = true)
{ {
$full = $fullfetch ? yield $this->get_full_info_async($id) : yield $this->get_info_async($id); $full = $fullfetch ? yield $this->getFullInfo($id) : yield $this->getInfo($id);
$res = ['id' => $full['bot_api_id'], 'type' => $full['type']]; $res = ['id' => $full['bot_api_id'], 'type' => $full['type']];
switch ($full['type']) { switch ($full['type']) {
case 'user': case 'user':
@ -656,7 +656,7 @@ trait PeerHandler
} }
} }
if (isset($full['full']['profile_photo']['sizes'])) { if (isset($full['full']['profile_photo']['sizes'])) {
$res['photo'] = yield $this->photosize_to_botapi_async(\end($full['full']['profile_photo']['sizes']), $full['full']['profile_photo']); $res['photo'] = yield $this->photosizeToBotAPI(\end($full['full']['profile_photo']['sizes']), $full['full']['profile_photo']);
} }
break; break;
case 'chat': case 'chat':
@ -674,7 +674,7 @@ trait PeerHandler
$res['all_members_are_administrators'] = !$res['admins_enabled']; $res['all_members_are_administrators'] = !$res['admins_enabled'];
} }
if (isset($full['full']['chat_photo']['sizes'])) { if (isset($full['full']['chat_photo']['sizes'])) {
$res['photo'] = yield $this->photosize_to_botapi_async(\end($full['full']['chat_photo']['sizes']), $full['full']['chat_photo']); $res['photo'] = yield $this->photosizeToBotAPI(\end($full['full']['chat_photo']['sizes']), $full['full']['chat_photo']);
} }
if (isset($full['full']['exported_invite']['link'])) { if (isset($full['full']['exported_invite']['link'])) {
$res['invite'] = $full['full']['exported_invite']['link']; $res['invite'] = $full['full']['exported_invite']['link'];
@ -696,7 +696,7 @@ trait PeerHandler
} }
} }
if (isset($full['full']['chat_photo']['sizes'])) { if (isset($full['full']['chat_photo']['sizes'])) {
$res['photo'] = yield $this->photosize_to_botapi_async(\end($full['full']['chat_photo']['sizes']), $full['full']['chat_photo']); $res['photo'] = yield $this->photosizeToBotAPI(\end($full['full']['chat_photo']['sizes']), $full['full']['chat_photo']);
} }
if (isset($full['full']['exported_invite']['link'])) { if (isset($full['full']['exported_invite']['link'])) {
$res['invite'] = $full['full']['exported_invite']['link']; $res['invite'] = $full['full']['exported_invite']['link'];
@ -709,15 +709,15 @@ trait PeerHandler
if (isset($res['participants']) && $fullfetch) { if (isset($res['participants']) && $fullfetch) {
foreach ($res['participants'] as $key => $participant) { foreach ($res['participants'] as $key => $participant) {
$newres = []; $newres = [];
$newres['user'] = yield $this->get_pwr_chat_async($participant['user_id'], false, true); $newres['user'] = yield $this->getPwrChat($participant['user_id'], false, true);
if (isset($participant['inviter_id'])) { if (isset($participant['inviter_id'])) {
$newres['inviter'] = yield $this->get_pwr_chat_async($participant['inviter_id'], false, true); $newres['inviter'] = yield $this->getPwrChat($participant['inviter_id'], false, true);
} }
if (isset($participant['promoted_by'])) { if (isset($participant['promoted_by'])) {
$newres['promoted_by'] = yield $this->get_pwr_chat_async($participant['promoted_by'], false, true); $newres['promoted_by'] = yield $this->getPwrChat($participant['promoted_by'], false, true);
} }
if (isset($participant['kicked_by'])) { if (isset($participant['kicked_by'])) {
$newres['kicked_by'] = yield $this->get_pwr_chat_async($participant['kicked_by'], false, true); $newres['kicked_by'] = yield $this->getPwrChat($participant['kicked_by'], false, true);
} }
if (isset($participant['date'])) { if (isset($participant['date'])) {
$newres['date'] = $participant['date']; $newres['date'] = $participant['date'];
@ -754,13 +754,13 @@ trait PeerHandler
$limit = 200; $limit = 200;
$filters = ['channelParticipantsAdmins', 'channelParticipantsBots']; $filters = ['channelParticipantsAdmins', 'channelParticipantsBots'];
foreach ($filters as $filter) { foreach ($filters as $filter) {
yield $this->fetch_participants_async($full['InputChannel'], $filter, '', $total_count, $res); yield $this->fetchParticipants($full['InputChannel'], $filter, '', $total_count, $res);
} }
$q = ''; $q = '';
$filters = ['channelParticipantsSearch', 'channelParticipantsKicked', 'channelParticipantsBanned']; $filters = ['channelParticipantsSearch', 'channelParticipantsKicked', 'channelParticipantsBanned'];
foreach ($filters as $filter) { foreach ($filters as $filter) {
yield $this->recurse_alphabet_search_participants_async($full['InputChannel'], $filter, $q, $total_count, $res); yield $this->recurseAlphabetSearchParticipants($full['InputChannel'], $filter, $q, $total_count, $res);
} }
$this->logger->logger('Fetched '.\count($res['participants'])." out of $total_count"); $this->logger->logger('Fetched '.\count($res['participants'])." out of $total_count");
$res['participants'] = \array_values($res['participants']); $res['participants'] = \array_values($res['participants']);
@ -769,24 +769,24 @@ trait PeerHandler
unset($res['participants']); unset($res['participants']);
} }
if ($fullfetch || $send) { if ($fullfetch || $send) {
$this->store_db($res); $this->storeDb($res);
} }
return $res; return $res;
} }
public function recurse_alphabet_search_participants_async($channel, $filter, $q, $total_count, &$res) public function recurseAlphabetSearchParticipants($channel, $filter, $q, $total_count, &$res)
{ {
if (!yield $this->fetch_participants_async($channel, $filter, $q, $total_count, $res)) { if (!yield $this->fetchParticipants($channel, $filter, $q, $total_count, $res)) {
return false; return false;
} }
for ($x = 'a'; $x !== 'aa' && $total_count > \count($res['participants']); $x++) { for ($x = 'a'; $x !== 'aa' && $total_count > \count($res['participants']); $x++) {
yield $this->recurse_alphabet_search_participants_async($channel, $filter, $q.$x, $total_count, $res); yield $this->recurseAlphabetSearchParticipants($channel, $filter, $q.$x, $total_count, $res);
} }
} }
public function fetch_participants_async($channel, $filter, $q, $total_count, &$res) public function fetchParticipants($channel, $filter, $q, $total_count, &$res)
{ {
$offset = 0; $offset = 0;
$limit = 200; $limit = 200;
@ -796,7 +796,7 @@ trait PeerHandler
do { do {
try { try {
$gres = yield $this->method_call_async_read('channels.getParticipants', ['channel' => $channel, 'filter' => ['_' => $filter, 'q' => $q], 'offset' => $offset, 'limit' => $limit, 'hash' => $hash = $this->get_participants_hash($channel, $filter, $q, $offset, $limit)], ['datacenter' => $this->datacenter->curdc, 'heavy' => true]); $gres = yield $this->methodCallAsyncRead('channels.getParticipants', ['channel' => $channel, 'filter' => ['_' => $filter, 'q' => $q], 'offset' => $offset, 'limit' => $limit, 'hash' => $hash = $this->getParticipantsHash($channel, $filter, $q, $offset, $limit)], ['datacenter' => $this->datacenter->curdc, 'heavy' => true]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'CHAT_ADMIN_REQUIRED') { if ($e->rpc === 'CHAT_ADMIN_REQUIRED') {
$this->logger->logger($e->rpc); $this->logger->logger($e->rpc);
@ -807,9 +807,9 @@ trait PeerHandler
} }
if ($cached = $gres['_'] === 'channels.channelParticipantsNotModified') { if ($cached = $gres['_'] === 'channels.channelParticipantsNotModified') {
$gres = $this->fetch_participants_cache($channel, $filter, $q, $offset, $limit); $gres = $this->fetchParticipantsCache($channel, $filter, $q, $offset, $limit);
} else { } else {
$this->store_participants_cache($gres, $channel, $filter, $q, $offset, $limit); $this->storeParticipantsCache($gres, $channel, $filter, $q, $offset, $limit);
} }
if ($last_count !== -1 && $last_count !== $gres['count']) { if ($last_count !== -1 && $last_count !== $gres['count']) {
@ -820,15 +820,15 @@ trait PeerHandler
foreach ($gres['participants'] as $participant) { foreach ($gres['participants'] as $participant) {
$newres = []; $newres = [];
$newres['user'] = yield $this->get_pwr_chat_async($participant['user_id'], false, true); $newres['user'] = yield $this->getPwrChat($participant['user_id'], false, true);
if (isset($participant['inviter_id'])) { if (isset($participant['inviter_id'])) {
$newres['inviter'] = yield $this->get_pwr_chat_async($participant['inviter_id'], false, true); $newres['inviter'] = yield $this->getPwrChat($participant['inviter_id'], false, true);
} }
if (isset($participant['kicked_by'])) { if (isset($participant['kicked_by'])) {
$newres['kicked_by'] = yield $this->get_pwr_chat_async($participant['kicked_by'], false, true); $newres['kicked_by'] = yield $this->getPwrChat($participant['kicked_by'], false, true);
} }
if (isset($participant['promoted_by'])) { if (isset($participant['promoted_by'])) {
$newres['promoted_by'] = yield $this->get_pwr_chat_async($participant['promoted_by'], false, true); $newres['promoted_by'] = yield $this->getPwrChat($participant['promoted_by'], false, true);
} }
if (isset($participant['date'])) { if (isset($participant['date'])) {
$newres['date'] = $participant['date']; $newres['date'] = $participant['date'];
@ -872,12 +872,12 @@ trait PeerHandler
return $has_more; return $has_more;
} }
public function fetch_participants_cache($channel, $filter, $q, $offset, $limit) public function fetchParticipantsCache($channel, $filter, $q, $offset, $limit)
{ {
return $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]; return $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit];
} }
public function store_participants_cache($gres, $channel, $filter, $q, $offset, $limit) public function storeParticipantsCache($gres, $channel, $filter, $q, $offset, $limit)
{ {
//return; //return;
unset($gres['users']); unset($gres['users']);
@ -886,16 +886,16 @@ trait PeerHandler
$ids[] = $participant['user_id']; $ids[] = $participant['user_id'];
} }
\sort($ids, SORT_NUMERIC); \sort($ids, SORT_NUMERIC);
$gres['hash'] = $this->gen_vector_hash($ids); $gres['hash'] = $this->genVectorHash($ids);
$this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit] = $gres; $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit] = $gres;
} }
public function get_participants_hash($channel, $filter, $q, $offset, $limit) public function getParticipantsHash($channel, $filter, $q, $offset, $limit)
{ {
return isset($this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]) ? $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]['hash'] : 0; return isset($this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]) ? $this->channel_participants[$channel['channel_id']][$filter][$q][$offset][$limit]['hash'] : 0;
} }
public function store_db($res, $force = false) public function storeDb($res, $force = false)
{ {
$settings = isset($this->settings['connection_settings'][$this->datacenter->curdc]) ? $this->settings['connection_settings'][$this->datacenter->curdc] : $this->settings['connection_settings']['all']; $settings = isset($this->settings['connection_settings'][$this->datacenter->curdc]) ? $this->settings['connection_settings'][$this->datacenter->curdc] : $this->settings['connection_settings']['all'];
if (!isset($this->settings['pwr']) || $this->settings['pwr']['pwr'] === false || $settings['test_mode']) { if (!isset($this->settings['pwr']) || $this->settings['pwr']['pwr'] === false || $settings['test_mode']) {
@ -933,11 +933,11 @@ trait PeerHandler
} }
} }
public function resolve_username_async($username) public function resolveUsername($username)
{ {
try { try {
$this->caching_simple_username[$username] = true; $this->caching_simple_username[$username] = true;
$res = yield $this->method_call_async_read('contacts.resolveUsername', ['username' => \str_replace('@', '', $username)], ['datacenter' => $this->datacenter->curdc]); $res = yield $this->methodCallAsyncRead('contacts.resolveUsername', ['username' => \str_replace('@', '', $username)], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
$this->logger->logger('Username resolution failed with error '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR); $this->logger->logger('Username resolution failed with error '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR);
if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0 || $e->rpc === 'AUTH_KEY_UNREGISTERED' || $e->rpc === 'USERNAME_INVALID') { if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0 || $e->rpc === 'AUTH_KEY_UNREGISTERED' || $e->rpc === 'USERNAME_INVALID') {

View File

@ -271,7 +271,7 @@ class ReferenceDatabase implements TLCallback
switch ($data['_']) { switch ($data['_']) {
case 'message': case 'message':
case 'messageService': case 'messageService':
$origin['peer'] = $this->API->get_id($data); $origin['peer'] = $this->API->getId($data);
$origin['msg_id'] = $data['id']; $origin['msg_id'] = $data['id'];
break; break;
case 'messages.savedGifs': case 'messages.savedGifs':
@ -303,7 +303,7 @@ class ReferenceDatabase implements TLCallback
break; break;
case 'channelFull': case 'channelFull':
case 'channel': case 'channel':
$origin['peer'] = $this->API->to_supergroup($data['id']); $origin['peer'] = $this->API->toSupergroup($data['id']);
break; break;
case 'document': case 'document':
foreach ($data['attributes'] as $attribute) { foreach ($data['attributes'] as $attribute) {
@ -483,13 +483,13 @@ class ReferenceDatabase implements TLCallback
// Peer + msg ID // Peer + msg ID
case self::MESSAGE_ORIGIN: case self::MESSAGE_ORIGIN:
if (\is_array($origin['peer'])) { if (\is_array($origin['peer'])) {
$origin['peer'] = $this->API->get_id($origin['peer']); $origin['peer'] = $this->API->getId($origin['peer']);
} }
if ($origin['peer'] < 0) { if ($origin['peer'] < 0) {
yield $this->API->method_call_async_read('channels.getMessages', ['channel' => $origin['peer'], 'id' => [$origin['msg_id']]], ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('channels.getMessages', ['channel' => $origin['peer'], 'id' => [$origin['msg_id']]], ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
} }
yield $this->API->method_call_async_read('messages.getMessages', ['id' => [$origin['msg_id']]], ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('messages.getMessages', ['id' => [$origin['msg_id']]], ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
// Peer + photo ID // Peer + photo ID
case self::PEER_PHOTO_ORIGIN: case self::PEER_PHOTO_ORIGIN:
@ -500,25 +500,25 @@ class ReferenceDatabase implements TLCallback
break; break;
// Peer (default photo ID) // Peer (default photo ID)
case self::USER_PHOTO_ORIGIN: case self::USER_PHOTO_ORIGIN:
yield $this->API->method_call_async_read('photos.getUserPhotos', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('photos.getUserPhotos', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
case self::SAVED_GIFS_ORIGIN: case self::SAVED_GIFS_ORIGIN:
yield $this->API->method_call_async_read('messages.getSavedGifs', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('messages.getSavedGifs', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
case self::STICKER_SET_ID_ORIGIN: case self::STICKER_SET_ID_ORIGIN:
yield $this->API->method_call_async_read('messages.getStickerSet', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('messages.getStickerSet', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
case self::STICKER_SET_RECENT_ORIGIN: case self::STICKER_SET_RECENT_ORIGIN:
yield $this->API->method_call_async_read('messages.getRecentStickers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('messages.getRecentStickers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
case self::STICKER_SET_FAVED_ORIGIN: case self::STICKER_SET_FAVED_ORIGIN:
yield $this->API->method_call_async_read('messages.getFavedStickers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('messages.getFavedStickers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
case self::STICKER_SET_EMOTICON_ORIGIN: case self::STICKER_SET_EMOTICON_ORIGIN:
yield $this->API->method_call_async_read('messages.getStickers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('messages.getStickers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
case self::WALLPAPER_ORIGIN: case self::WALLPAPER_ORIGIN:
yield $this->API->method_call_async_read('account.getWallPapers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); yield $this->API->methodCallAsyncRead('account.getWallPapers', $origin, ['datacenter' => $this->API->settings['connection_settings']['default_dc']]);
break; break;
default: default:
throw new \danog\MadelineProto\Exception("Unknown origin type $originType"); throw new \danog\MadelineProto\Exception("Unknown origin type $originType");
@ -570,11 +570,11 @@ class ReferenceDatabase implements TLCallback
switch ($locationType) { switch ($locationType) {
case self::DOCUMENT_LOCATION: case self::DOCUMENT_LOCATION:
case self::PHOTO_LOCATION: case self::PHOTO_LOCATION:
return $locationType.(\is_int($location['id']) ? $this->pack_signed_long($location['id']) : $location['id']); return $locationType.(\is_int($location['id']) ? $this->packSignedLong($location['id']) : $location['id']);
case self::PHOTO_LOCATION_LOCATION: case self::PHOTO_LOCATION_LOCATION:
$dc_id = $this->pack_signed_int($location['dc_id']); $dc_id = $this->packSignedInt($location['dc_id']);
$volume_id = \is_int($location['volume_id']) ? $this->pack_signed_long($location['volume_id']) : $location['volume_id']; $volume_id = \is_int($location['volume_id']) ? $this->packSignedLong($location['volume_id']) : $location['volume_id'];
$local_id = $this->pack_signed_int($location['local_id']); $local_id = $this->packSignedInt($location['local_id']);
return $locationType.$dc_id.$volume_id.$local_id; return $locationType.$dc_id.$volume_id.$local_id;
} }

View File

@ -33,7 +33,7 @@ trait UpdateHandler
public $updates = []; public $updates = [];
public $updates_key = 0; public $updates_key = 0;
public function pwr_update_handler($update) public function pwrUpdateHandler($update)
{ {
if (isset($this->settings['pwr']['update_handler'])) { if (isset($this->settings['pwr']['update_handler'])) {
if (\is_array($this->settings['pwr']['update_handler']) && $this->settings['pwr']['update_handler'][0] === false) { if (\is_array($this->settings['pwr']['update_handler']) && $this->settings['pwr']['update_handler'][0] === false) {
@ -42,11 +42,11 @@ trait UpdateHandler
if (\is_string($this->settings['pwr']['update_handler'])) { if (\is_string($this->settings['pwr']['update_handler'])) {
return $this->{$this->settings['pwr']['update_handler']}($update); return $this->{$this->settings['pwr']['update_handler']}($update);
} }
\in_array($this->settings['pwr']['update_handler'], [['danog\\MadelineProto\\API', 'get_updates_update_handler'], 'get_updates_update_handler']) ? $this->get_updates_update_handler($update) : $this->settings['pwr']['update_handler']($update); \in_array($this->settings['pwr']['update_handler'], [['danog\\MadelineProto\\API', 'get_updates_update_handler'], 'get_updates_update_handler']) ? $this->getUpdatesUpdateHandler($update) : $this->settings['pwr']['update_handler']($update);
} }
} }
public function get_updates_update_handler($update) public function getUpdatesUpdateHandler($update)
{ {
if (!$this->settings['updates']['handle_updates']) { if (!$this->settings['updates']['handle_updates']) {
return; return;
@ -54,7 +54,7 @@ trait UpdateHandler
$this->updates[$this->updates_key++] = $update; $this->updates[$this->updates_key++] = $update;
} }
public function get_updates_async($params = []) public function getUpdates($params = [])
{ {
if (!$this->settings['updates']['handle_updates']) { if (!$this->settings['updates']['handle_updates']) {
$this->settings['updates']['handle_updates'] = true; $this->settings['updates']['handle_updates'] = true;
@ -119,14 +119,14 @@ trait UpdateHandler
}); });
} }
public function check_msg_id($message) public function checkMsgId($message)
{ {
if (!isset($message['to_id'])) { if (!isset($message['to_id'])) {
return true; return true;
} }
try { try {
$peer_id = $this->get_id($message['to_id']); $peer_id = $this->getId($message['to_id']);
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
return true; return true;
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
@ -142,11 +142,11 @@ trait UpdateHandler
return false; return false;
} }
public function load_update_state_async() public function loadUpdateState()
{ {
if (!$this->got_state) { if (!$this->got_state) {
$this->got_state = true; $this->got_state = true;
$this->channels_state->get(false, yield $this->get_updates_state_async()); $this->channels_state->get(false, yield $this->getUpdatesState());
} }
return $this->channels_state->get(false); return $this->channels_state->get(false);
@ -162,16 +162,16 @@ trait UpdateHandler
return $this->channels_state; return $this->channels_state;
} }
public function get_updates_state_async() public function getUpdatesState()
{ {
$data = yield $this->method_call_async_read('updates.getState', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); $data = yield $this->methodCallAsyncRead('updates.getState', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]);
yield $this->get_cdn_config_async($this->settings['connection_settings']['default_dc']); yield $this->getCdnConfig($this->settings['connection_settings']['default_dc']);
return $data; return $data;
} }
public function handle_updates_async($updates, $actual_updates = null) public function handleUpdates($updates, $actual_updates = null)
{ {
if (!$this->settings['updates']['handle_updates']) { if (!$this->settings['updates']['handle_updates']) {
return; return;
@ -211,7 +211,7 @@ trait UpdateHandler
if (!isset($updates['request']['body'])) { if (!isset($updates['request']['body'])) {
break; break;
} }
$updates['user_id'] = (yield $this->get_info_async($updates['request']['body']['peer']))['bot_api_id']; $updates['user_id'] = (yield $this->getInfo($updates['request']['body']['peer']))['bot_api_id'];
$updates['message'] = $updates['request']['body']['message']; $updates['message'] = $updates['request']['body']['message'];
unset($updates['request']); unset($updates['request']);
// no break // no break
@ -219,7 +219,7 @@ trait UpdateHandler
case 'updateShortChatMessage': case 'updateShortChatMessage':
$from_id = isset($updates['from_id']) ? $updates['from_id'] : ($updates['out'] ? $this->authorization['user']['id'] : $updates['user_id']); $from_id = isset($updates['from_id']) ? $updates['from_id'] : ($updates['out'] ? $this->authorization['user']['id'] : $updates['user_id']);
$to_id = isset($updates['chat_id']) ? -$updates['chat_id'] : ($updates['out'] ? $updates['user_id'] : $this->authorization['user']['id']); $to_id = isset($updates['chat_id']) ? -$updates['chat_id'] : ($updates['out'] ? $updates['user_id'] : $this->authorization['user']['id']);
if (!yield $this->peer_isset_async($from_id) || !yield $this->peer_isset_async($to_id) || isset($updates['via_bot_id']) && !yield $this->peer_isset_async($updates['via_bot_id']) || isset($updates['entities']) && !yield $this->entities_peer_isset_async($updates['entities']) || isset($updates['fwd_from']) && !yield $this->fwd_peer_isset_async($updates['fwd_from'])) { if (!yield $this->peerIsset($from_id) || !yield $this->peerIsset($to_id) || isset($updates['via_bot_id']) && !yield $this->peerIsset($updates['via_bot_id']) || isset($updates['entities']) && !yield $this->entitiesPeerIsset($updates['entities']) || isset($updates['fwd_from']) && !yield $this->fwdPeerIsset($updates['fwd_from'])) {
yield $this->updaters[false]->resume(); yield $this->updaters[false]->resume();
return; return;
@ -229,7 +229,7 @@ trait UpdateHandler
$message['from_id'] = $from_id; $message['from_id'] = $from_id;
try { try {
$message['to_id'] = (yield $this->get_info_async($to_id))['Peer']; $message['to_id'] = (yield $this->getInfo($to_id))['Peer'];
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
$this->logger->logger('Still did not get user in database, postponing update', \danog\MadelineProto\Logger::ERROR); $this->logger->logger('Still did not get user in database, postponing update', \danog\MadelineProto\Logger::ERROR);
//$this->pending_updates[] = $updates; //$this->pending_updates[] = $updates;
@ -250,21 +250,21 @@ trait UpdateHandler
break; break;
} }
} }
public function save_update_async($update) public function saveUpdate($update)
{ {
if ($update['_'] === 'updateConfig') { if ($update['_'] === 'updateConfig') {
$this->config['expires'] = 0; $this->config['expires'] = 0;
yield $this->get_config_async(); yield $this->getConfig();
} }
if (\in_array($update['_'], ['updateUserName', 'updateUserPhone', 'updateUserBlocked', 'updateUserPhoto', 'updateContactRegistered', 'updateContactLink'])) { if (\in_array($update['_'], ['updateUserName', 'updateUserPhone', 'updateUserBlocked', 'updateUserPhoto', 'updateContactRegistered', 'updateContactLink'])) {
$id = $this->get_id($update); $id = $this->getId($update);
$this->full_chats[$id]['last_update'] = 0; $this->full_chats[$id]['last_update'] = 0;
yield $this->get_full_info_async($id); yield $this->getFullInfo($id);
} }
if ($update['_'] === 'updateDcOptions') { if ($update['_'] === 'updateDcOptions') {
$this->logger->logger('Got new dc options', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Got new dc options', \danog\MadelineProto\Logger::VERBOSE);
$this->config['dc_options'] = $update['dc_options']; $this->config['dc_options'] = $update['dc_options'];
yield $this->parse_config_async(); yield $this->parseConfig();
return; return;
} }
@ -285,13 +285,13 @@ trait UpdateHandler
$update['phone_call'] = $this->calls[$update['phone_call']['id']] = $controller; $update['phone_call'] = $this->calls[$update['phone_call']['id']] = $controller;
break; break;
case 'phoneCallAccepted': case 'phoneCallAccepted':
if (!yield $this->confirm_call_async($update['phone_call'])) { if (!yield $this->confirmCall($update['phone_call'])) {
return; return;
} }
$update['phone_call'] = $this->calls[$update['phone_call']['id']]; $update['phone_call'] = $this->calls[$update['phone_call']['id']];
break; break;
case 'phoneCall': case 'phoneCall':
if (!yield $this->complete_call_async($update['phone_call'])) { if (!yield $this->completeCall($update['phone_call'])) {
return; return;
} }
$update['phone_call'] = $this->calls[$update['phone_call']['id']]; $update['phone_call'] = $this->calls[$update['phone_call']['id']];
@ -306,7 +306,7 @@ trait UpdateHandler
} }
if ($update['_'] === 'updateNewEncryptedMessage' && !isset($update['message']['decrypted_message'])) { if ($update['_'] === 'updateNewEncryptedMessage' && !isset($update['message']['decrypted_message'])) {
if (isset($update['qts'])) { if (isset($update['qts'])) {
$cur_state = yield $this->load_update_state_async(); $cur_state = yield $this->loadUpdateState();
if ($cur_state->qts() === -1) { if ($cur_state->qts() === -1) {
$cur_state->qts($update['qts']); $cur_state->qts($update['qts']);
} }
@ -322,9 +322,9 @@ trait UpdateHandler
return false; return false;
} }
$this->logger->logger('Applying qts: '.$update['qts'].' over current qts '.$cur_state->qts().', chat id: '.$update['message']['chat_id'], \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Applying qts: '.$update['qts'].' over current qts '.$cur_state->qts().', chat id: '.$update['message']['chat_id'], \danog\MadelineProto\Logger::VERBOSE);
yield $this->method_call_async_read('messages.receivedQueue', ['max_qts' => $cur_state->qts($update['qts'])], ['datacenter' => $this->settings['connection_settings']['default_dc']]); yield $this->methodCallAsyncRead('messages.receivedQueue', ['max_qts' => $cur_state->qts($update['qts'])], ['datacenter' => $this->settings['connection_settings']['default_dc']]);
} }
yield $this->handle_encrypted_update_async($update); yield $this->handleEncryptedUpdate($update);
return; return;
} }
@ -340,7 +340,7 @@ trait UpdateHandler
return; return;
} }
$this->logger->logger('Accepting secret chat '.$update['chat']['id'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Accepting secret chat '.$update['chat']['id'], \danog\MadelineProto\Logger::NOTICE);
yield $this->accept_secret_chat_async($update['chat']); yield $this->acceptSecretChat($update['chat']);
break; break;
case 'encryptedChatDiscarded': case 'encryptedChatDiscarded':
$this->logger->logger('Deleting secret chat '.$update['chat']['id'].' because it was revoked by the other user', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Deleting secret chat '.$update['chat']['id'].' because it was revoked by the other user', \danog\MadelineProto\Logger::NOTICE);
@ -357,7 +357,7 @@ trait UpdateHandler
break; break;
case 'encryptedChat': case 'encryptedChat':
$this->logger->logger('Completing creation of secret chat '.$update['chat']['id'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Completing creation of secret chat '.$update['chat']['id'], \danog\MadelineProto\Logger::NOTICE);
yield $this->complete_secret_chat_async($update['chat']); yield $this->completeSecretChat($update['chat']);
break; break;
} }
//$this->logger->logger($update, \danog\MadelineProto\Logger::NOTICE); //$this->logger->logger($update, \danog\MadelineProto\Logger::NOTICE);
@ -376,13 +376,13 @@ trait UpdateHandler
} }
//$this->logger->logger('Saving an update of type '.$update['_'].'...', \danog\MadelineProto\Logger::ULTRA_VERBOSE); //$this->logger->logger('Saving an update of type '.$update['_'].'...', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict'] && isset($this->settings['pwr']['update_handler'])) { if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict'] && isset($this->settings['pwr']['update_handler'])) {
$this->pwr_update_handler($update); $this->pwrUpdateHandler($update);
} elseif ($this->settings['updates']['run_callback']) { } elseif ($this->settings['updates']['run_callback']) {
$this->get_updates_update_handler($update); $this->getUpdatesUpdateHandler($update);
} }
} }
public function pwr_webhook($update) public function pwrWebhook($update)
{ {
$payload = \json_encode($update); $payload = \json_encode($update);
//$this->logger->logger($update, $payload, json_last_error()); //$this->logger->logger($update, $payload, json_last_error());
@ -400,7 +400,7 @@ trait UpdateHandler
$result = \json_decode($result, true); $result = \json_decode($result, true);
if (\is_array($result) && isset($result['method']) && $result['method'] != '' && \is_string($result['method'])) { if (\is_array($result) && isset($result['method']) && $result['method'] != '' && \is_string($result['method'])) {
try { try {
$this->logger->logger('Reverse webhook command returned', yield $this->method_call_async_read($result['method'], $result, ['datacenter' => $this->datacenter->curdc])); $this->logger->logger('Reverse webhook command returned', yield $this->methodCallAsyncRead($result['method'], $result, ['datacenter' => $this->datacenter->curdc]));
} catch (\Throwable $e) { } catch (\Throwable $e) {
$this->logger->logger("Reverse webhook command returned: $e"); $this->logger->logger("Reverse webhook command returned: $e");
} }

File diff suppressed because one or more lines are too long

View File

@ -71,7 +71,7 @@ class MyTelegramOrgWrapper
); );
} }
public function login_async($number) public function login($number)
{ {
$this->number = $number; $this->number = $number;
$request = new Request(self::MY_TELEGRAM_URL.'/auth/send_password', 'POST'); $request = new Request(self::MY_TELEGRAM_URL.'/auth/send_password', 'POST');
@ -87,7 +87,7 @@ class MyTelegramOrgWrapper
$this->hash = $resulta['random_hash']; $this->hash = $resulta['random_hash'];
} }
public function complete_login_async($password) public function completeLogin($password)
{ {
if ($this->logged) { if ($this->logged) {
throw new Exception('Already logged in!'); throw new Exception('Already logged in!');
@ -112,12 +112,12 @@ class MyTelegramOrgWrapper
return $this->logged = true; return $this->logged = true;
} }
public function logged_in_async() public function loggedIn()
{ {
return $this->logged; return $this->logged;
} }
public function has_app_async() public function hasApp()
{ {
if (!$this->logged) { if (!$this->logged) {
throw new Exception('Not logged in!'); throw new Exception('Not logged in!');
@ -143,7 +143,7 @@ class MyTelegramOrgWrapper
throw new Exception($title); throw new Exception($title);
} }
public function get_app_async() public function getApp()
{ {
if (!$this->logged) { if (!$this->logged) {
throw new Exception('Not logged in!'); throw new Exception('Not logged in!');
@ -168,12 +168,12 @@ class MyTelegramOrgWrapper
return ['api_id' => (int) $api_id, 'api_hash' => $api_hash]; return ['api_id' => (int) $api_id, 'api_hash' => $api_hash];
} }
public function create_app_async($settings) public function createApp($settings)
{ {
if (!$this->logged) { if (!$this->logged) {
throw new Exception('Not logged in!'); throw new Exception('Not logged in!');
} }
if (yield $this->has_app_async()) { if (yield $this->hasApp()) {
throw new Exception('The app was already created!'); throw new Exception('The app was already created!');
} }

View File

@ -31,6 +31,6 @@ class PTSException extends \Exception
public function __construct($message, $file = '') public function __construct($message, $file = '')
{ {
parent::__construct($message); parent::__construct($message);
$this->prettify_tl($file); $this->prettifyTl($file);
} }
} }

View File

@ -116,7 +116,7 @@ class RPCErrorException extends \Exception
{ {
$this->rpc = $message; $this->rpc = $message;
parent::__construct($message, $code, $previous); parent::__construct($message, $code, $previous);
$this->prettify_tl($caller); $this->prettifyTl($caller);
$this->caller = $caller; $this->caller = $caller;
$additional = []; $additional = [];

View File

@ -35,7 +35,7 @@ class RSA
$this->n = self::getVar($key, 'modulus'); $this->n = self::getVar($key, 'modulus');
$this->e = self::getVar($key, 'exponent'); $this->e = self::getVar($key, 'exponent');
\danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['computing_fingerprint'], Logger::ULTRA_VERBOSE); \danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['computing_fingerprint'], Logger::ULTRA_VERBOSE);
$this->fp = \substr(\sha1((yield $this->serialize_object_async(['type' => 'bytes'], $this->n->toBytes(), 'key')).(yield $this->serialize_object_async(['type' => 'bytes'], $this->e->toBytes(), 'key')), true), -8); $this->fp = \substr(\sha1((yield $this->serializeObject(['type' => 'bytes'], $this->n->toBytes(), 'key')).(yield $this->serializeObject(['type' => 'bytes'], $this->e->toBytes(), 'key')), true), -8);
return $this; return $this;
} }

View File

@ -29,20 +29,20 @@ trait AuthKeyHandler
protected $temp_requested_secret_chats = []; protected $temp_requested_secret_chats = [];
protected $secret_chats = []; protected $secret_chats = [];
public function accept_secret_chat_async($params) public function acceptSecretChat($params)
{ {
//$this->logger->logger($params['id'],$this->secret_chat_status($params['id'])); //$this->logger->logger($params['id'],$this->secretChatStatus($params['id']));
if ($this->secret_chat_status($params['id']) !== 0) { if ($this->secretChatStatus($params['id']) !== 0) {
//$this->logger->logger($this->secret_chat_status($params['id'])); //$this->logger->logger($this->secretChatStatus($params['id']));
$this->logger->logger("I've already accepted secret chat ".$params['id']); $this->logger->logger("I've already accepted secret chat ".$params['id']);
return false; return false;
} }
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE);
$b = new \phpseclib\Math\BigInteger($this->random(256), 256); $b = new \phpseclib\Math\BigInteger($this->random(256), 256);
$params['g_a'] = new \phpseclib\Math\BigInteger((string) $params['g_a'], 256); $params['g_a'] = new \phpseclib\Math\BigInteger((string) $params['g_a'], 256);
$this->check_G($params['g_a'], $dh_config['p']); $this->checkG($params['g_a'], $dh_config['p']);
$key = ['auth_key' => \str_pad($params['g_a']->powMod($b, $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)]; $key = ['auth_key' => \str_pad($params['g_a']->powMod($b, $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)];
//$this->logger->logger($key); //$this->logger->logger($key);
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8); $key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
@ -50,27 +50,27 @@ trait AuthKeyHandler
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20); $key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
$this->secret_chats[$params['id']] = ['key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputEncryptedChat' => ['_' => 'inputEncryptedChat', 'chat_id' => $params['id'], 'access_hash' => $params['access_hash']], 'in_seq_no_x' => 1, 'out_seq_no_x' => 0, 'in_seq_no' => 0, 'out_seq_no' => 0, 'layer' => 8, 'ttl' => 0, 'ttr' => 100, 'updated' => \time(), 'incoming' => [], 'outgoing' => [], 'created' => \time(), 'rekeying' => [0], 'key_x' => 'from server', 'mtproto' => 1]; $this->secret_chats[$params['id']] = ['key' => $key, 'admin' => false, 'user_id' => $params['admin_id'], 'InputEncryptedChat' => ['_' => 'inputEncryptedChat', 'chat_id' => $params['id'], 'access_hash' => $params['access_hash']], 'in_seq_no_x' => 1, 'out_seq_no_x' => 0, 'in_seq_no' => 0, 'out_seq_no' => 0, 'layer' => 8, 'ttl' => 0, 'ttr' => 100, 'updated' => \time(), 'incoming' => [], 'outgoing' => [], 'created' => \time(), 'rekeying' => [0], 'key_x' => 'from server', 'mtproto' => 1];
$g_b = $dh_config['g']->powMod($b, $dh_config['p']); $g_b = $dh_config['g']->powMod($b, $dh_config['p']);
$this->check_G($g_b, $dh_config['p']); $this->checkG($g_b, $dh_config['p']);
yield $this->method_call_async_read('messages.acceptEncryption', ['peer' => $params['id'], 'g_b' => $g_b->toBytes(), 'key_fingerprint' => $key['fingerprint']], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.acceptEncryption', ['peer' => $params['id'], 'g_b' => $g_b->toBytes(), 'key_fingerprint' => $key['fingerprint']], ['datacenter' => $this->datacenter->curdc]);
yield $this->notify_layer_async($params['id']); yield $this->notifyLayer($params['id']);
$this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', \danog\MadelineProto\Logger::NOTICE);
} }
public function request_secret_chat_async($user) public function requestSecretChat($user)
{ {
$user = yield $this->get_info_async($user); $user = yield $this->getInfo($user);
if (!isset($user['InputUser'])) { if (!isset($user['InputUser'])) {
throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database'); throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database');
} }
$user = $user['InputUser']; $user = $user['InputUser'];
$this->logger->logger('Creating secret chat with '.$user['user_id'].'...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Creating secret chat with '.$user['user_id'].'...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE);
$a = new \phpseclib\Math\BigInteger($this->random(256), 256); $a = new \phpseclib\Math\BigInteger($this->random(256), 256);
$this->logger->logger('Generating g_a...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating g_a...', \danog\MadelineProto\Logger::VERBOSE);
$g_a = $dh_config['g']->powMod($a, $dh_config['p']); $g_a = $dh_config['g']->powMod($a, $dh_config['p']);
$this->check_G($g_a, $dh_config['p']); $this->checkG($g_a, $dh_config['p']);
$res = yield $this->method_call_async_read('messages.requestEncryption', ['user_id' => $user, 'g_a' => $g_a->toBytes()], ['datacenter' => $this->datacenter->curdc]); $res = yield $this->methodCallAsyncRead('messages.requestEncryption', ['user_id' => $user, 'g_a' => $g_a->toBytes()], ['datacenter' => $this->datacenter->curdc]);
$this->temp_requested_secret_chats[$res['id']] = $a; $this->temp_requested_secret_chats[$res['id']] = $a;
$this->updaters[false]->resume(); $this->updaters[false]->resume();
$this->logger->logger('Secret chat '.$res['id'].' requested successfully!', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Secret chat '.$res['id'].' requested successfully!', \danog\MadelineProto\Logger::NOTICE);
@ -78,62 +78,62 @@ trait AuthKeyHandler
return $res['id']; return $res['id'];
} }
public function complete_secret_chat_async($params) public function completeSecretChat($params)
{ {
if ($this->secret_chat_status($params['id']) !== 1) { if ($this->secretChatStatus($params['id']) !== 1) {
//$this->logger->logger($this->secret_chat_status($params['id'])); //$this->logger->logger($this->secretChatStatus($params['id']));
$this->logger->logger('Could not find and complete secret chat '.$params['id']); $this->logger->logger('Could not find and complete secret chat '.$params['id']);
return false; return false;
} }
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$params['g_a_or_b'] = new \phpseclib\Math\BigInteger((string) $params['g_a_or_b'], 256); $params['g_a_or_b'] = new \phpseclib\Math\BigInteger((string) $params['g_a_or_b'], 256);
$this->check_G($params['g_a_or_b'], $dh_config['p']); $this->checkG($params['g_a_or_b'], $dh_config['p']);
$key = ['auth_key' => \str_pad($params['g_a_or_b']->powMod($this->temp_requested_secret_chats[$params['id']], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)]; $key = ['auth_key' => \str_pad($params['g_a_or_b']->powMod($this->temp_requested_secret_chats[$params['id']], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)];
unset($this->temp_requested_secret_chats[$params['id']]); unset($this->temp_requested_secret_chats[$params['id']]);
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8); $key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
//$this->logger->logger($key); //$this->logger->logger($key);
if ($key['fingerprint'] !== $params['key_fingerprint']) { if ($key['fingerprint'] !== $params['key_fingerprint']) {
yield $this->discard_secret_chat_async($params['id']); yield $this->discardSecretChat($params['id']);
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!'); throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
} }
$key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16); $key['visualization_orig'] = \substr(\sha1($key['auth_key'], true), 16);
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20); $key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
$this->secret_chats[$params['id']] = ['key' => $key, 'admin' => true, 'user_id' => $params['participant_id'], 'InputEncryptedChat' => ['chat_id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputEncryptedChat'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'in_seq_no' => 0, 'out_seq_no' => 0, 'layer' => 8, 'ttl' => 0, 'ttr' => 100, 'updated' => \time(), 'incoming' => [], 'outgoing' => [], 'created' => \time(), 'rekeying' => [0], 'key_x' => 'to server', 'mtproto' => 1]; $this->secret_chats[$params['id']] = ['key' => $key, 'admin' => true, 'user_id' => $params['participant_id'], 'InputEncryptedChat' => ['chat_id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputEncryptedChat'], 'in_seq_no_x' => 0, 'out_seq_no_x' => 1, 'in_seq_no' => 0, 'out_seq_no' => 0, 'layer' => 8, 'ttl' => 0, 'ttr' => 100, 'updated' => \time(), 'incoming' => [], 'outgoing' => [], 'created' => \time(), 'rekeying' => [0], 'key_x' => 'to server', 'mtproto' => 1];
yield $this->notify_layer_async($params['id']); yield $this->notifyLayer($params['id']);
$this->logger->logger('Secret chat '.$params['id'].' completed successfully!', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Secret chat '.$params['id'].' completed successfully!', \danog\MadelineProto\Logger::NOTICE);
} }
public function notify_layer_async($chat) public function notifyLayer($chat)
{ {
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->encrypted_layer]]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->encrypted_layer]]], ['datacenter' => $this->datacenter->curdc]);
} }
protected $temp_rekeyed_secret_chats = []; protected $temp_rekeyed_secret_chats = [];
public function rekey_async($chat) public function rekey($chat)
{ {
if ($this->secret_chats[$chat]['rekeying'][0] !== 0) { if ($this->secret_chats[$chat]['rekeying'][0] !== 0) {
return; return;
} }
$this->logger->logger('Rekeying secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Rekeying secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE);
$a = new \phpseclib\Math\BigInteger($this->random(256), 256); $a = new \phpseclib\Math\BigInteger($this->random(256), 256);
$this->logger->logger('Generating g_a...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating g_a...', \danog\MadelineProto\Logger::VERBOSE);
$g_a = $dh_config['g']->powMod($a, $dh_config['p']); $g_a = $dh_config['g']->powMod($a, $dh_config['p']);
$this->check_G($g_a, $dh_config['p']); $this->checkG($g_a, $dh_config['p']);
$e = $this->random(8); $e = $this->random(8);
$this->temp_rekeyed_secret_chats[$e] = $a; $this->temp_rekeyed_secret_chats[$e] = $a;
$this->secret_chats[$chat]['rekeying'] = [1, $e]; $this->secret_chats[$chat]['rekeying'] = [1, $e];
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $e]]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $e]]], ['datacenter' => $this->datacenter->curdc]);
$this->updaters[false]->resume(); $this->updaters[false]->resume();
return $e; return $e;
} }
public function accept_rekey_async($chat, $params) public function acceptRekey($chat, $params)
{ {
if ($this->secret_chats[$chat]['rekeying'][0] !== 0) { if ($this->secret_chats[$chat]['rekeying'][0] !== 0) {
$my_exchange_id = new \phpseclib\Math\BigInteger($this->secret_chats[$chat]['rekeying'][1], -256); $my_exchange_id = new \phpseclib\Math\BigInteger($this->secret_chats[$chat]['rekeying'][1], -256);
@ -149,11 +149,11 @@ trait AuthKeyHandler
} }
} }
$this->logger->logger('Accepting rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Accepting rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE);
$b = new \phpseclib\Math\BigInteger($this->random(256), 256); $b = new \phpseclib\Math\BigInteger($this->random(256), 256);
$params['g_a'] = new \phpseclib\Math\BigInteger((string) $params['g_a'], 256); $params['g_a'] = new \phpseclib\Math\BigInteger((string) $params['g_a'], 256);
$this->check_G($params['g_a'], $dh_config['p']); $this->checkG($params['g_a'], $dh_config['p']);
$key = ['auth_key' => \str_pad($params['g_a']->powMod($b, $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)]; $key = ['auth_key' => \str_pad($params['g_a']->powMod($b, $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)];
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8); $key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
$key['visualization_orig'] = $this->secret_chats[$chat]['key']['visualization_orig']; $key['visualization_orig'] = $this->secret_chats[$chat]['key']['visualization_orig'];
@ -161,12 +161,12 @@ trait AuthKeyHandler
$this->temp_rekeyed_secret_chats[$params['exchange_id']] = $key; $this->temp_rekeyed_secret_chats[$params['exchange_id']] = $key;
$this->secret_chats[$chat]['rekeying'] = [2, $params['exchange_id']]; $this->secret_chats[$chat]['rekeying'] = [2, $params['exchange_id']];
$g_b = $dh_config['g']->powMod($b, $dh_config['p']); $g_b = $dh_config['g']->powMod($b, $dh_config['p']);
$this->check_G($g_b, $dh_config['p']); $this->checkG($g_b, $dh_config['p']);
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAcceptKey', 'g_b' => $g_b->toBytes(), 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAcceptKey', 'g_b' => $g_b->toBytes(), 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]);
$this->updaters[false]->resume(); $this->updaters[false]->resume();
} }
public function commit_rekey_async($chat, $params) public function commitRekey($chat, $params)
{ {
if ($this->secret_chats[$chat]['rekeying'][0] !== 1 || !isset($this->temp_rekeyed_secret_chats[$params['exchange_id']])) { if ($this->secret_chats[$chat]['rekeying'][0] !== 1 || !isset($this->temp_rekeyed_secret_chats[$params['exchange_id']])) {
$this->secret_chats[$chat]['rekeying'] = [0]; $this->secret_chats[$chat]['rekeying'] = [0];
@ -174,19 +174,19 @@ trait AuthKeyHandler
return; return;
} }
$this->logger->logger('Committing rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Committing rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$params['g_b'] = new \phpseclib\Math\BigInteger((string) $params['g_b'], 256); $params['g_b'] = new \phpseclib\Math\BigInteger((string) $params['g_b'], 256);
$this->check_G($params['g_b'], $dh_config['p']); $this->checkG($params['g_b'], $dh_config['p']);
$key = ['auth_key' => \str_pad($params['g_b']->powMod($this->temp_rekeyed_secret_chats[$params['exchange_id']], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)]; $key = ['auth_key' => \str_pad($params['g_b']->powMod($this->temp_rekeyed_secret_chats[$params['exchange_id']], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT)];
$key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8); $key['fingerprint'] = \substr(\sha1($key['auth_key'], true), -8);
$key['visualization_orig'] = $this->secret_chats[$chat]['key']['visualization_orig']; $key['visualization_orig'] = $this->secret_chats[$chat]['key']['visualization_orig'];
$key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20); $key['visualization_46'] = \substr(\hash('sha256', $key['auth_key'], true), 20);
if ($key['fingerprint'] !== $params['key_fingerprint']) { if ($key['fingerprint'] !== $params['key_fingerprint']) {
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]);
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!'); throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
} }
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionCommitKey', 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionCommitKey', 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]);
unset($this->temp_rekeyed_secret_chats[$chat]); unset($this->temp_rekeyed_secret_chats[$chat]);
$this->secret_chats[$chat]['rekeying'] = [0]; $this->secret_chats[$chat]['rekeying'] = [0];
$this->secret_chats[$chat]['old_key'] = $this->secret_chats[$chat]['key']; $this->secret_chats[$chat]['old_key'] = $this->secret_chats[$chat]['key'];
@ -196,13 +196,13 @@ trait AuthKeyHandler
$this->updaters[false]->resume(); $this->updaters[false]->resume();
} }
public function complete_rekey_async($chat, $params) public function completeRekey($chat, $params)
{ {
if ($this->secret_chats[$chat]['rekeying'][0] !== 2 || !isset($this->temp_rekeyed_secret_chats['fingerprint'])) { if ($this->secret_chats[$chat]['rekeying'][0] !== 2 || !isset($this->temp_rekeyed_secret_chats['fingerprint'])) {
return; return;
} }
if ($this->temp_rekeyed_secret_chats['fingerprint'] !== $params['key_fingerprint']) { if ($this->temp_rekeyed_secret_chats['fingerprint'] !== $params['key_fingerprint']) {
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]);
throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!'); throw new \danog\MadelineProto\SecurityException('Invalid key fingerprint!');
} }
@ -213,13 +213,13 @@ trait AuthKeyHandler
$this->secret_chats[$chat]['ttr'] = 100; $this->secret_chats[$chat]['ttr'] = 100;
$this->secret_chats[$chat]['updated'] = \time(); $this->secret_chats[$chat]['updated'] = \time();
unset($this->temp_rekeyed_secret_chats[$params['exchange_id']]); unset($this->temp_rekeyed_secret_chats[$params['exchange_id']]);
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNoop']]], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNoop']]], ['datacenter' => $this->datacenter->curdc]);
$this->logger->logger('Secret chat '.$chat.' rekeyed successfully!', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Secret chat '.$chat.' rekeyed successfully!', \danog\MadelineProto\Logger::VERBOSE);
return true; return true;
} }
public function secret_chat_status($chat) public function secretChatStatus($chat)
{ {
if (isset($this->secret_chats[$chat])) { if (isset($this->secret_chats[$chat])) {
return 2; return 2;
@ -231,12 +231,12 @@ trait AuthKeyHandler
return 0; return 0;
} }
public function get_secret_chat($chat) public function getSecretChat($chat)
{ {
return $this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat]; return $this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat];
} }
public function discard_secret_chat_async($chat) public function discardSecretChat($chat)
{ {
$this->logger->logger('Discarding secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger('Discarding secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
//$this->logger->logger(debug_backtrace(0)[0]); //$this->logger->logger(debug_backtrace(0)[0]);
@ -251,7 +251,7 @@ trait AuthKeyHandler
} }
try { try {
yield $this->method_call_async_read('messages.discardEncryption', ['chat_id' => $chat], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.discardEncryption', ['chat_id' => $chat], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc !== 'ENCRYPTION_ALREADY_DECLINED') { if ($e->rpc !== 'ENCRYPTION_ALREADY_DECLINED') {
throw $e; throw $e;

View File

@ -24,7 +24,7 @@ namespace danog\MadelineProto\SecretChats;
*/ */
trait MessageHandler trait MessageHandler
{ {
public function encrypt_secret_message_async($chat_id, $message) public function encryptSecretMessage($chat_id, $message)
{ {
if (!isset($this->secret_chats[$chat_id])) { if (!isset($this->secret_chats[$chat_id])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $chat_id)); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $chat_id));
@ -35,14 +35,14 @@ trait MessageHandler
$this->secret_chats[$chat_id]['ttr']--; $this->secret_chats[$chat_id]['ttr']--;
if ($this->secret_chats[$chat_id]['layer'] > 8) { if ($this->secret_chats[$chat_id]['layer'] > 8) {
if (($this->secret_chats[$chat_id]['ttr'] <= 0 || \time() - $this->secret_chats[$chat_id]['updated'] > 7 * 24 * 60 * 60) && $this->secret_chats[$chat_id]['rekeying'][0] === 0) { if (($this->secret_chats[$chat_id]['ttr'] <= 0 || \time() - $this->secret_chats[$chat_id]['updated'] > 7 * 24 * 60 * 60) && $this->secret_chats[$chat_id]['rekeying'][0] === 0) {
yield $this->rekey_async($chat_id); yield $this->rekey($chat_id);
} }
$message = ['_' => 'decryptedMessageLayer', 'layer' => $this->secret_chats[$chat_id]['layer'], 'in_seq_no' => $this->generate_secret_in_seq_no($chat_id), 'out_seq_no' => $this->generate_secret_out_seq_no($chat_id), 'message' => $message]; $message = ['_' => 'decryptedMessageLayer', 'layer' => $this->secret_chats[$chat_id]['layer'], 'in_seq_no' => $this->generateSecretInSeqNo($chat_id), 'out_seq_no' => $this->generateSecretOutSeqNo($chat_id), 'message' => $message];
$this->secret_chats[$chat_id]['out_seq_no']++; $this->secret_chats[$chat_id]['out_seq_no']++;
} }
$this->secret_chats[$chat_id]['outgoing'][$this->secret_chats[$chat_id]['out_seq_no']] = $message; $this->secret_chats[$chat_id]['outgoing'][$this->secret_chats[$chat_id]['out_seq_no']] = $message;
$message = yield $this->serialize_object_async(['type' => $constructor = $this->secret_chats[$chat_id]['layer'] === 8 ? 'DecryptedMessage' : 'DecryptedMessageLayer'], $message, $constructor, $this->secret_chats[$chat_id]['layer']); $message = yield $this->serializeObject(['type' => $constructor = $this->secret_chats[$chat_id]['layer'] === 8 ? 'DecryptedMessage' : 'DecryptedMessageLayer'], $message, $constructor, $this->secret_chats[$chat_id]['layer']);
$message = $this->pack_unsigned_int(\strlen($message)).$message; $message = $this->packUnsignedInt(\strlen($message)).$message;
if ($this->secret_chats[$chat_id]['mtproto'] === 2) { if ($this->secret_chats[$chat_id]['mtproto'] === 2) {
$padding = $this->posmod(-\strlen($message), 16); $padding = $this->posmod(-\strlen($message), 16);
if ($padding < 12) { if ($padding < 12) {
@ -50,18 +50,18 @@ trait MessageHandler
} }
$message .= $this->random($padding); $message .= $this->random($padding);
$message_key = \substr(\hash('sha256', \substr($this->secret_chats[$chat_id]['key']['auth_key'], 88 + ($this->secret_chats[$chat_id]['admin'] ? 0 : 8), 32).$message, true), 8, 16); $message_key = \substr(\hash('sha256', \substr($this->secret_chats[$chat_id]['key']['auth_key'], 88 + ($this->secret_chats[$chat_id]['admin'] ? 0 : 8), 32).$message, true), 8, 16);
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, $this->secret_chats[$chat_id]['key']['auth_key'], $this->secret_chats[$chat_id]['admin']); list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $this->secret_chats[$chat_id]['key']['auth_key'], $this->secret_chats[$chat_id]['admin']);
} else { } else {
$message_key = \substr(\sha1($message, true), -16); $message_key = \substr(\sha1($message, true), -16);
list($aes_key, $aes_iv) = $this->old_aes_calculate($message_key, $this->secret_chats[$chat_id]['key']['auth_key'], true); list($aes_key, $aes_iv) = $this->oldAesCalculate($message_key, $this->secret_chats[$chat_id]['key']['auth_key'], true);
$message .= $this->random($this->posmod(-\strlen($message), 16)); $message .= $this->random($this->posmod(-\strlen($message), 16));
} }
$message = $this->secret_chats[$chat_id]['key']['fingerprint'].$message_key.$this->ige_encrypt($message, $aes_key, $aes_iv); $message = $this->secret_chats[$chat_id]['key']['fingerprint'].$message_key.$this->igeEncrypt($message, $aes_key, $aes_iv);
return $message; return $message;
} }
public function handle_encrypted_update_async($message, $test = false) public function handleEncryptedUpdate($message, $test = false)
{ {
if (!isset($this->secret_chats[$message['message']['chat_id']])) { if (!isset($this->secret_chats[$message['message']['chat_id']])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $message['message']['chat_id'])); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $message['message']['chat_id']));
@ -73,13 +73,13 @@ trait MessageHandler
if ($auth_key_id !== $this->secret_chats[$message['message']['chat_id']]['key']['fingerprint']) { if ($auth_key_id !== $this->secret_chats[$message['message']['chat_id']]['key']['fingerprint']) {
if (isset($this->secret_chats[$message['message']['chat_id']]['old_key']['fingerprint'])) { if (isset($this->secret_chats[$message['message']['chat_id']]['old_key']['fingerprint'])) {
if ($auth_key_id !== $this->secret_chats[$message['message']['chat_id']]['old_key']['fingerprint']) { if ($auth_key_id !== $this->secret_chats[$message['message']['chat_id']]['old_key']['fingerprint']) {
yield $this->discard_secret_chat_async($message['message']['chat_id']); yield $this->discardSecretChat($message['message']['chat_id']);
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_mismatch']); throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_mismatch']);
} }
$old = true; $old = true;
} else { } else {
yield $this->discard_secret_chat_async($message['message']['chat_id']); yield $this->discardSecretChat($message['message']['chat_id']);
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_mismatch']); throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_mismatch']);
} }
@ -90,11 +90,11 @@ trait MessageHandler
$this->logger->logger('Trying MTProto v2 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Trying MTProto v2 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
try { try {
$message_data = $this->try_mtproto_v2_decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data); $message_data = $this->tryMTProtoV2Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
$this->logger->logger('MTProto v2 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('MTProto v2 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
} catch (\danog\MadelineProto\SecurityException $e) { } catch (\danog\MadelineProto\SecurityException $e) {
$this->logger->logger('MTProto v2 decryption failed with message '.$e->getMessage().', trying MTProto v1 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('MTProto v2 decryption failed with message '.$e->getMessage().', trying MTProto v1 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
$message_data = $this->try_mtproto_v1_decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data); $message_data = $this->tryMTProtoV1Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
$this->logger->logger('MTProto v1 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('MTProto v1 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
$this->secret_chats[$message['message']['chat_id']]['mtproto'] = 1; $this->secret_chats[$message['message']['chat_id']]['mtproto'] = 1;
} }
@ -102,11 +102,11 @@ trait MessageHandler
$this->logger->logger('Trying MTProto v1 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('Trying MTProto v1 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
try { try {
$message_data = $this->try_mtproto_v1_decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data); $message_data = $this->tryMTProtoV1Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
$this->logger->logger('MTProto v1 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('MTProto v1 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
} catch (\danog\MadelineProto\SecurityException $e) { } catch (\danog\MadelineProto\SecurityException $e) {
$this->logger->logger('MTProto v1 decryption failed with message '.$e->getMessage().', trying MTProto v2 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('MTProto v1 decryption failed with message '.$e->getMessage().', trying MTProto v2 decryption for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
$message_data = $this->try_mtproto_v2_decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data); $message_data = $this->tryMTProtoV2Decrypt($message_key, $message['message']['chat_id'], $old, $encrypted_data);
$this->logger->logger('MTProto v2 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE); $this->logger->logger('MTProto v2 decryption OK for chat '.$message['message']['chat_id'].'...', \danog\MadelineProto\Logger::NOTICE);
$this->secret_chats[$message['message']['chat_id']]['mtproto'] = 2; $this->secret_chats[$message['message']['chat_id']]['mtproto'] = 2;
} }
@ -114,18 +114,18 @@ trait MessageHandler
$deserialized = $this->deserialize($message_data, ['type' => '']); $deserialized = $this->deserialize($message_data, ['type' => '']);
$this->secret_chats[$message['message']['chat_id']]['ttr']--; $this->secret_chats[$message['message']['chat_id']]['ttr']--;
if (($this->secret_chats[$message['message']['chat_id']]['ttr'] <= 0 || \time() - $this->secret_chats[$message['message']['chat_id']]['updated'] > 7 * 24 * 60 * 60) && $this->secret_chats[$message['message']['chat_id']]['rekeying'][0] === 0) { if (($this->secret_chats[$message['message']['chat_id']]['ttr'] <= 0 || \time() - $this->secret_chats[$message['message']['chat_id']]['updated'] > 7 * 24 * 60 * 60) && $this->secret_chats[$message['message']['chat_id']]['rekeying'][0] === 0) {
yield $this->rekey_async($message['message']['chat_id']); yield $this->rekey($message['message']['chat_id']);
} }
unset($message['message']['bytes']); unset($message['message']['bytes']);
$message['message']['decrypted_message'] = $deserialized; $message['message']['decrypted_message'] = $deserialized;
$this->secret_chats[$message['message']['chat_id']]['incoming'][$this->secret_chats[$message['message']['chat_id']]['in_seq_no']] = $message['message']; $this->secret_chats[$message['message']['chat_id']]['incoming'][$this->secret_chats[$message['message']['chat_id']]['in_seq_no']] = $message['message'];
yield $this->handle_decrypted_update_async($message); yield $this->handleDecryptedUpdate($message);
} }
public function try_mtproto_v1_decrypt($message_key, $chat_id, $old, $encrypted_data) public function tryMTProtoV1Decrypt($message_key, $chat_id, $old, $encrypted_data)
{ {
list($aes_key, $aes_iv) = $this->old_aes_calculate($message_key, $this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], true); list($aes_key, $aes_iv) = $this->oldAesCalculate($message_key, $this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], true);
$decrypted_data = $this->ige_decrypt($encrypted_data, $aes_key, $aes_iv); $decrypted_data = $this->igeDecrypt($encrypted_data, $aes_key, $aes_iv);
$message_data_length = \unpack('V', \substr($decrypted_data, 0, 4))[1]; $message_data_length = \unpack('V', \substr($decrypted_data, 0, 4))[1];
$message_data = \substr($decrypted_data, 4, $message_data_length); $message_data = \substr($decrypted_data, 4, $message_data_length);
if ($message_data_length > \strlen($decrypted_data)) { if ($message_data_length > \strlen($decrypted_data)) {
@ -144,10 +144,10 @@ trait MessageHandler
return $message_data; return $message_data;
} }
public function try_mtproto_v2_decrypt($message_key, $chat_id, $old, $encrypted_data) public function tryMTProtoV2Decrypt($message_key, $chat_id, $old, $encrypted_data)
{ {
list($aes_key, $aes_iv) = $this->aes_calculate($message_key, $this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], !$this->secret_chats[$chat_id]['admin']); list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $this->secret_chats[$chat_id][$old ? 'old_key' : 'key']['auth_key'], !$this->secret_chats[$chat_id]['admin']);
$decrypted_data = $this->ige_decrypt($encrypted_data, $aes_key, $aes_iv); $decrypted_data = $this->igeDecrypt($encrypted_data, $aes_key, $aes_iv);
$message_data_length = \unpack('V', \substr($decrypted_data, 0, 4))[1]; $message_data_length = \unpack('V', \substr($decrypted_data, 0, 4))[1];
$message_data = \substr($decrypted_data, 4, $message_data_length); $message_data = \substr($decrypted_data, 4, $message_data_length);
if ($message_data_length > \strlen($decrypted_data)) { if ($message_data_length > \strlen($decrypted_data)) {

View File

@ -24,7 +24,7 @@ namespace danog\MadelineProto\SecretChats;
*/ */
trait ResponseHandler trait ResponseHandler
{ {
public function handle_decrypted_update_async($update) public function handleDecryptedUpdate($update)
{ {
/*if (isset($update['message']['decrypted_message']['random_bytes']) && strlen($update['message']['decrypted_message']['random_bytes']) < 15) { /*if (isset($update['message']['decrypted_message']['random_bytes']) && strlen($update['message']['decrypted_message']['random_bytes']) < 15) {
throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['rand_bytes_too_short']); throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['rand_bytes_too_short']);
@ -34,21 +34,21 @@ trait ResponseHandler
case 'decryptedMessageService': case 'decryptedMessageService':
switch ($update['message']['decrypted_message']['action']['_']) { switch ($update['message']['decrypted_message']['action']['_']) {
case 'decryptedMessageActionRequestKey': case 'decryptedMessageActionRequestKey':
yield $this->accept_rekey_async($update['message']['chat_id'], $update['message']['decrypted_message']['action']); yield $this->acceptRekey($update['message']['chat_id'], $update['message']['decrypted_message']['action']);
return; return;
case 'decryptedMessageActionAcceptKey': case 'decryptedMessageActionAcceptKey':
yield $this->commit_rekey_async($update['message']['chat_id'], $update['message']['decrypted_message']['action']); yield $this->commitRekey($update['message']['chat_id'], $update['message']['decrypted_message']['action']);
return; return;
case 'decryptedMessageActionCommitKey': case 'decryptedMessageActionCommitKey':
yield $this->complete_rekey_async($update['message']['chat_id'], $update['message']['decrypted_message']['action']); yield $this->completeRekey($update['message']['chat_id'], $update['message']['decrypted_message']['action']);
return; return;
case 'decryptedMessageActionNotifyLayer': case 'decryptedMessageActionNotifyLayer':
$this->secret_chats[$update['message']['chat_id']]['layer'] = $update['message']['decrypted_message']['action']['layer']; $this->secret_chats[$update['message']['chat_id']]['layer'] = $update['message']['decrypted_message']['action']['layer'];
if ($update['message']['decrypted_message']['action']['layer'] >= 17 && \time() - $this->secret_chats[$update['message']['chat_id']]['created'] > 15) { if ($update['message']['decrypted_message']['action']['layer'] >= 17 && \time() - $this->secret_chats[$update['message']['chat_id']]['created'] > 15) {
yield $this->notify_layer_async($update['message']['chat_id']); yield $this->notifyLayer($update['message']['chat_id']);
} }
if ($update['message']['decrypted_message']['action']['layer'] >= 73) { if ($update['message']['decrypted_message']['action']['layer'] >= 73) {
$this->secret_chats[$update['message']['chat_id']]['mtproto'] = 2; $this->secret_chats[$update['message']['chat_id']]['mtproto'] = 2;
@ -58,7 +58,7 @@ trait ResponseHandler
case 'decryptedMessageActionSetMessageTTL': case 'decryptedMessageActionSetMessageTTL':
$this->secret_chats[$update['message']['chat_id']]['ttl'] = $update['message']['decrypted_message']['action']['ttl_seconds']; $this->secret_chats[$update['message']['chat_id']]['ttl'] = $update['message']['decrypted_message']['action']['ttl_seconds'];
yield $this->save_update_async($update); yield $this->saveUpdate($update);
return; return;
case 'decryptedMessageActionNoop': case 'decryptedMessageActionNoop':
@ -72,30 +72,30 @@ trait ResponseHandler
foreach ($this->secret_chats[$update['message']['chat_id']]['outgoing'] as $seq => $message) { foreach ($this->secret_chats[$update['message']['chat_id']]['outgoing'] as $seq => $message) {
if ($seq >= $update['message']['decrypted_message']['action']['start_seq_no'] && $seq <= $update['message']['decrypted_message']['action']['end_seq_no']) { if ($seq >= $update['message']['decrypted_message']['action']['start_seq_no'] && $seq <= $update['message']['decrypted_message']['action']['end_seq_no']) {
//throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['resending_unsupported']); //throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['resending_unsupported']);
yield $this->method_call_async_read('messages.sendEncrypted', ['peer' => $update['message']['chat_id'], 'message' => $update['message']['decrypted_message']], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('messages.sendEncrypted', ['peer' => $update['message']['chat_id'], 'message' => $update['message']['decrypted_message']], ['datacenter' => $this->datacenter->curdc]);
} }
} }
return; return;
default: default:
// yield $this->save_update_async(['_' => 'updateNewDecryptedMessage', 'peer' => $this->secret_chats[$update['message']['chat_id']]['InputEncryptedChat'], 'in_seq_no' => $this->get_in_seq_no($update['message']['chat_id']), 'out_seq_no' => $this->get_out_seq_no($update['message']['chat_id']), 'message' => $update['message']['decrypted_message']]); // yield $this->saveUpdate(['_' => 'updateNewDecryptedMessage', 'peer' => $this->secret_chats[$update['message']['chat_id']]['InputEncryptedChat'], 'in_seq_no' => $this->get_in_seq_no($update['message']['chat_id']), 'out_seq_no' => $this->get_out_seq_no($update['message']['chat_id']), 'message' => $update['message']['decrypted_message']]);
yield $this->save_update_async($update); yield $this->saveUpdate($update);
} }
break; break;
case 'decryptedMessage': case 'decryptedMessage':
yield $this->save_update_async($update); yield $this->saveUpdate($update);
break; break;
case 'decryptedMessageLayer': case 'decryptedMessageLayer':
if (yield $this->check_secret_out_seq_no_async($update['message']['chat_id'], $update['message']['decrypted_message']['out_seq_no']) && yield $this->check_secret_in_seq_no_async($update['message']['chat_id'], $update['message']['decrypted_message']['in_seq_no'])) { if (yield $this->checkSecretOutSeqNo($update['message']['chat_id'], $update['message']['decrypted_message']['out_seq_no']) && yield $this->checkSecretInSeqNo($update['message']['chat_id'], $update['message']['decrypted_message']['in_seq_no'])) {
$this->secret_chats[$update['message']['chat_id']]['in_seq_no']++; $this->secret_chats[$update['message']['chat_id']]['in_seq_no']++;
if ($update['message']['decrypted_message']['layer'] >= 17) { if ($update['message']['decrypted_message']['layer'] >= 17) {
$this->secret_chats[$update['message']['chat_id']]['layer'] = $update['message']['decrypted_message']['layer']; $this->secret_chats[$update['message']['chat_id']]['layer'] = $update['message']['decrypted_message']['layer'];
if ($update['message']['decrypted_message']['layer'] >= 17 && \time() - $this->secret_chats[$update['message']['chat_id']]['created'] > 15) { if ($update['message']['decrypted_message']['layer'] >= 17 && \time() - $this->secret_chats[$update['message']['chat_id']]['created'] > 15) {
yield $this->notify_layer_async($update['message']['chat_id']); yield $this->notifyLayer($update['message']['chat_id']);
} }
} }
$update['message']['decrypted_message'] = $update['message']['decrypted_message']['message']; $update['message']['decrypted_message'] = $update['message']['decrypted_message']['message'];
yield $this->handle_decrypted_update_async($update); yield $this->handleDecryptedUpdate($update);
} }
break; break;
default: default:

View File

@ -24,14 +24,14 @@ namespace danog\MadelineProto\SecretChats;
*/ */
trait SeqNoHandler trait SeqNoHandler
{ {
public function check_secret_in_seq_no_async($chat_id, $seqno) public function checkSecretInSeqNo($chat_id, $seqno)
{ {
$seqno = ($seqno - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2; $seqno = ($seqno - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2;
$last = 0; $last = 0;
foreach ($this->secret_chats[$chat_id]['incoming'] as $message) { foreach ($this->secret_chats[$chat_id]['incoming'] as $message) {
if (isset($message['decrypted_message']['in_seq_no'])) { if (isset($message['decrypted_message']['in_seq_no'])) {
if (($message['decrypted_message']['in_seq_no'] - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2 < $last) { if (($message['decrypted_message']['in_seq_no'] - $this->secret_chats[$chat_id]['out_seq_no_x']) / 2 < $last) {
yield $this->discard_secret_chat_async($chat_id); yield $this->discardSecretChat($chat_id);
throw new \danog\MadelineProto\SecurityException('in_seq_no is not increasing'); throw new \danog\MadelineProto\SecurityException('in_seq_no is not increasing');
} }
@ -39,7 +39,7 @@ trait SeqNoHandler
} }
} }
if ($seqno > $this->secret_chats[$chat_id]['out_seq_no'] + 1) { if ($seqno > $this->secret_chats[$chat_id]['out_seq_no'] + 1) {
yield $this->discard_secret_chat_async($chat_id); yield $this->discardSecretChat($chat_id);
throw new \danog\MadelineProto\SecurityException('in_seq_no is too big'); throw new \danog\MadelineProto\SecurityException('in_seq_no is too big');
} }
@ -47,14 +47,14 @@ trait SeqNoHandler
return true; return true;
} }
public function check_secret_out_seq_no_async($chat_id, $seqno) public function checkSecretOutSeqNo($chat_id, $seqno)
{ {
$seqno = ($seqno - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2; $seqno = ($seqno - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2;
$C = 0; $C = 0;
foreach ($this->secret_chats[$chat_id]['incoming'] as $message) { foreach ($this->secret_chats[$chat_id]['incoming'] as $message) {
if (isset($message['decrypted_message']['out_seq_no']) && $C < $this->secret_chats[$chat_id]['in_seq_no']) { if (isset($message['decrypted_message']['out_seq_no']) && $C < $this->secret_chats[$chat_id]['in_seq_no']) {
if (($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2 !== $C) { if (($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2 !== $C) {
yield $this->discard_secret_chat_async($chat_id); yield $this->discardSecretChat($chat_id);
throw new \danog\MadelineProto\SecurityException('out_seq_no hole: should be '.$C.', is '.($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2); throw new \danog\MadelineProto\SecurityException('out_seq_no hole: should be '.$C.', is '.($message['decrypted_message']['out_seq_no'] - $this->secret_chats[$chat_id]['in_seq_no_x']) / 2);
} }
@ -70,7 +70,7 @@ trait SeqNoHandler
} }
if ($seqno > $C) { if ($seqno > $C) {
// > C+1 // > C+1
yield $this->discard_secret_chat_async($chat_id); yield $this->discardSecretChat($chat_id);
throw new \danog\MadelineProto\SecurityException('WARNING: out_seq_no gap detected ('.$seqno.' > '.$C.')!'); throw new \danog\MadelineProto\SecurityException('WARNING: out_seq_no gap detected ('.$seqno.' > '.$C.')!');
} }
@ -78,12 +78,12 @@ trait SeqNoHandler
return true; return true;
} }
public function generate_secret_in_seq_no($chat) public function generateSecretInSeqNo($chat)
{ {
return $this->secret_chats[$chat]['layer'] > 8 ? $this->secret_chats[$chat]['in_seq_no'] * 2 + $this->secret_chats[$chat]['in_seq_no_x'] : -1; return $this->secret_chats[$chat]['layer'] > 8 ? $this->secret_chats[$chat]['in_seq_no'] * 2 + $this->secret_chats[$chat]['in_seq_no_x'] : -1;
} }
public function generate_secret_out_seq_no($chat) public function generateSecretOutSeqNo($chat)
{ {
return $this->secret_chats[$chat]['layer'] > 8 ? $this->secret_chats[$chat]['out_seq_no'] * 2 + $this->secret_chats[$chat]['out_seq_no_x'] : -1; return $this->secret_chats[$chat]['layer'] > 8 ? $this->secret_chats[$chat]['out_seq_no'] * 2 + $this->secret_chats[$chat]['out_seq_no_x'] : -1;
} }

View File

@ -99,7 +99,7 @@ class Server
} }
} }
public function sig_handler($sig) public function sigHandler($sig)
{ {
switch ($sig) { switch ($sig) {
case SIGTERM: case SIGTERM:

View File

@ -49,10 +49,10 @@ class Handler extends \danog\MadelineProto\Connection
{ {
echo 'Closing socket in fork '.\getmypid().PHP_EOL; echo 'Closing socket in fork '.\getmypid().PHP_EOL;
unset($this->sock); unset($this->sock);
$this->destruct_madeline(); $this->destructMadeline();
} }
public function destruct_madeline() public function destructMadeline()
{ {
if (isset($this->madeline) && $this->madeline !== null) { if (isset($this->madeline) && $this->madeline !== null) {
$this->madeline->API->settings['logger'] = ['logger' => 0, 'logger_param' => '']; $this->madeline->API->settings['logger'] = ['logger' => 0, 'logger_param' => ''];
@ -120,24 +120,24 @@ class Handler extends \danog\MadelineProto\Connection
throw new \danog\MadelineProto\Exception('Invalid object received'); throw new \danog\MadelineProto\Exception('Invalid object received');
} }
$request_id = $message['request_id']; $request_id = $message['request_id'];
$this->send_response($request_id, $this->on_request($request_id, $message['method'], $message['args'])); $this->sendResponse($request_id, $this->onRequest($request_id, $message['method'], $message['args']));
} catch (\danog\MadelineProto\TL\Exception $e) { } catch (\danog\MadelineProto\TL\Exception $e) {
$this->send_exception($request_id, $e); $this->sendException($request_id, $e);
continue; continue;
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
$this->send_exception($request_id, $e); $this->sendException($request_id, $e);
continue; continue;
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
$this->send_exception($request_id, $e); $this->sendException($request_id, $e);
continue; continue;
} catch (\DOMException $e) { } catch (\DOMException $e) {
$this->send_exception($request_id, $e); $this->sendException($request_id, $e);
continue; continue;
} }
} }
} }
public function on_request($request_id, $method, $args) public function onRequest($request_id, $method, $args)
{ {
if (\count($method) === 0 || \count($method) > 2) { if (\count($method) === 0 || \count($method) > 2) {
throw new \danog\MadelineProto\Exception('Invalid method called'); throw new \danog\MadelineProto\Exception('Invalid method called');
@ -204,7 +204,7 @@ class Handler extends \danog\MadelineProto\Connection
} }
} }
public function send_exception($request_id, $e) public function sendException($request_id, $e)
{ {
echo $e.PHP_EOL; echo $e.PHP_EOL;
if ($e instanceof \danog\MadelineProto\RPCErrorException) { if ($e instanceof \danog\MadelineProto\RPCErrorException) {
@ -253,17 +253,17 @@ class Handler extends \danog\MadelineProto\Connection
} }
$exception['trace']['frames'][] = $tl_frame; $exception['trace']['frames'][] = $tl_frame;
} }
$this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageException', 'request_id' => $request_id, 'exception' => $exception], 'exception')); $this->sendMessageSafe(yield $this->serializeObject(['type' => ''], ['_' => 'socketMessageException', 'request_id' => $request_id, 'exception' => $exception], 'exception'));
} }
public function send_response($request_id, $response) public function sendResponse($request_id, $response)
{ {
$this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageResponse', 'request_id' => $request_id, 'data' => $response], 'exception')); $this->sendMessageSafe(yield $this->serializeObject(['type' => ''], ['_' => 'socketMessageResponse', 'request_id' => $request_id, 'data' => $response], 'exception'));
} }
public function send_data($stream_id, $data) public function sendData($stream_id, $data)
{ {
$this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageRawData', 'stream_id' => $stream_id, 'data' => $data], 'data')); $this->sendMessageSafe(yield $this->serializeObject(['type' => ''], ['_' => 'socketMessageRawData', 'stream_id' => $stream_id, 'data' => $data], 'data'));
} }
public $logging = false; public $logging = false;
@ -274,16 +274,16 @@ class Handler extends \danog\MadelineProto\Connection
try { try {
$this->logging = true; $this->logging = true;
$message = ['_' => 'socketMessageLog', 'data' => $message, 'level' => $level, 'thread' => \danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread()), 'process' => \danog\MadelineProto\Magic::is_fork(), 'file' => \basename(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['file'], '.php')]; $message = ['_' => 'socketMessageLog', 'data' => $message, 'level' => $level, 'thread' => \danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread()), 'process' => \danog\MadelineProto\Magic::isFork(), 'file' => \basename(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['file'], '.php')];
$this->send_message_safe(yield $this->serialize_object_async(['type' => ''], $message, 'log')); $this->sendMessageSafe(yield $this->serializeObject(['type' => ''], $message, 'log'));
} finally { } finally {
$this->logging = false; $this->logging = false;
} }
} }
} }
public function send_message_safe($message) public function sendMessageSafe($message)
{ {
if (!isset($this->sock)) { if (!isset($this->sock)) {
return false; return false;
@ -297,13 +297,13 @@ class Handler extends \danog\MadelineProto\Connection
} }
} }
public function update_handler($update) public function updateHandler($update)
{ {
$this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageUpdate', 'data' => $update], 'update')); $this->sendMessageSafe(yield $this->serializeObject(['type' => ''], ['_' => 'socketMessageUpdate', 'data' => $update], 'update'));
} }
public function __call($method, $args) public function __call($method, $args)
{ {
$this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageRequest', 'request_id' => 0, 'method' => [$method], 'args' => $args], 'method')); $this->sendMessageSafe(yield $this->serializeObject(['type' => ''], ['_' => 'socketMessageRequest', 'request_id' => 0, 'method' => [$method], 'args' => $args], 'method'));
} }
} }

View File

@ -39,7 +39,7 @@ class Stream
return \stream_context_create([self::WRAPPER_NAME => ['handler' => $handler, 'stream_id' => $stream_id]]); return \stream_context_create([self::WRAPPER_NAME => ['handler' => $handler, 'stream_id' => $stream_id]]);
} }
public function stream_open($path, $mode, $options, &$opened_path) public function streamOpen($path, $mode, $options, &$opened_path)
{ {
$opt = \stream_context_get_options($this->context); $opt = \stream_context_get_options($this->context);
@ -55,12 +55,12 @@ class Stream
return true; return true;
} }
public function stream_write($data) public function streamWrite($data)
{ {
$this->_handler->send_data($this->_stream_id, $data); $this->_handler->sendData($this->_stream_id, $data);
} }
public function stream_lock($mode) public function streamLock($mode)
{ {
} }
} }

View File

@ -52,7 +52,7 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$this->stream = yield $ctx->getStream($header); $this->stream = yield $ctx->getStream($header);
$this->memory_stream = \fopen('php://memory', 'r+'); $this->memory_stream = \fopen('php://memory', 'r+');
@ -169,7 +169,7 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
return new Success(\fread($this->memory_stream, $length)); return new Success(\fread($this->memory_stream, $length));
} }
return $this->call($this->bufferReadAsync($length)); return $this->call($this->bufferReadGenerator($length));
} }
/** /**
@ -179,7 +179,7 @@ class BufferedRawStream implements BufferedStreamInterface, BufferInterface, Raw
* *
* @return \Generator * @return \Generator
*/ */
public function bufferReadAsync(int $length): \Generator public function bufferReadGenerator(int $length): \Generator
{ {
$size = \fstat($this->memory_stream)['size']; $size = \fstat($this->memory_stream)['size'];
$offset = \ftell($this->memory_stream); $offset = \ftell($this->memory_stream);

View File

@ -154,7 +154,7 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
* *
* @return Generator That resolves with a string when the provided promise is resolved and the data is added to the hashing context * @return Generator That resolves with a string when the provided promise is resolved and the data is added to the hashing context
*/ */
public function bufferReadAsync(int $length): \Generator public function bufferReadGenerator(int $length): \Generator
{ {
if ($this->read_check_after && $length + $this->read_check_pos >= $this->read_check_after) { if ($this->read_check_after && $length + $this->read_check_pos >= $this->read_check_after) {
if ($length + $this->read_check_pos > $this->read_check_after) { if ($length + $this->read_check_pos > $this->read_check_after) {
@ -203,7 +203,7 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx): \Generator public function connectGenerator(ConnectionContext $ctx): \Generator
{ {
$this->write_hash = null; $this->write_hash = null;
$this->write_check_after = 0; $this->write_check_after = 0;
@ -232,7 +232,7 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
if ($this->read_hash) { if ($this->read_hash) {
$this->read_buffer = yield $this->stream->getReadBuffer($length); $this->read_buffer = yield $this->stream->getReadBuffer($length);
@ -250,7 +250,7 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
* *
* @return Generator * @return Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
if ($this->write_hash) { if ($this->write_hash) {
$this->write_buffer = yield $this->stream->getWriteBuffer($length, $append); $this->write_buffer = yield $this->stream->getWriteBuffer($length, $append);
@ -274,7 +274,7 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf
return $this->read_buffer->bufferRead($length); return $this->read_buffer->bufferRead($length);
} }
return $this->call($this->bufferReadAsync($length)); return $this->call($this->bufferReadGenerator($length));
} }
/** /**

View File

@ -36,7 +36,7 @@ class SimpleBufferedRawStream extends BufferedRawStream implements BufferedStrea
* *
* @return \Generator * @return \Generator
*/ */
public function bufferReadAsync(int $length): \Generator public function bufferReadGenerator(int $length): \Generator
{ {
$size = \fstat($this->memory_stream)['size']; $size = \fstat($this->memory_stream)['size'];
$offset = \ftell($this->memory_stream); $offset = \ftell($this->memory_stream);

View File

@ -42,7 +42,7 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$this->stream = yield $ctx->getStream(\chr(239).$header); $this->stream = yield $ctx->getStream(\chr(239).$header);
} }
@ -64,7 +64,7 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
* *
* @return \Generator * @return \Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
$length >>= 2; $length >>= 2;
if ($length < 127) { if ($length < 127) {
@ -85,7 +85,7 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
$buffer = yield $this->stream->getReadBuffer($l); $buffer = yield $this->stream->getReadBuffer($l);
$length = \ord(yield $buffer->bufferRead(1)); $length = \ord(yield $buffer->bufferRead(1));

View File

@ -73,7 +73,7 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
* *
* @return Generator * @return Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
$this->stream->startWriteHash(); $this->stream->startWriteHash();
$this->stream->checkWriteHash($length + 8); $this->stream->checkWriteHash($length + 8);
@ -91,7 +91,7 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
$this->stream->startReadHash(); $this->stream->startReadHash();
$buffer = yield $this->stream->getReadBuffer($l); $buffer = yield $this->stream->getReadBuffer($l);

View File

@ -51,7 +51,7 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$this->ctx = $ctx->getCtx(); $this->ctx = $ctx->getCtx();
$this->stream = yield $ctx->getStream($header); $this->stream = yield $ctx->getStream($header);
@ -89,7 +89,7 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
* *
* @return Generator * @return Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
$headers = 'POST '.$this->uri->getPath()." HTTP/1.1\r\nHost: ".$this->uri->getHost().':'.$this->uri->getPort()."\r\n"."Content-Type: application/x-www-form-urlencoded\r\nConnection: keep-alive\r\nKeep-Alive: timeout=100000, max=10000000\r\nContent-Length: ".$length.$this->header."\r\n\r\n"; $headers = 'POST '.$this->uri->getPath()." HTTP/1.1\r\nHost: ".$this->uri->getHost().':'.$this->uri->getPort()."\r\n"."Content-Type: application/x-www-form-urlencoded\r\nConnection: keep-alive\r\nKeep-Alive: timeout=100000, max=10000000\r\nContent-Length: ".$length.$this->header."\r\n\r\n";
$buffer = yield $this->stream->getWriteBuffer(\strlen($headers) + $length, $append); $buffer = yield $this->stream->getWriteBuffer(\strlen($headers) + $length, $append);
@ -105,7 +105,7 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
$buffer = yield $this->stream->getReadBuffer($l); $buffer = yield $this->stream->getReadBuffer($l);
$headers = ''; $headers = '';
@ -158,7 +158,7 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
\danog\MadelineProto\Logger::log($read); \danog\MadelineProto\Logger::log($read);
$this->code = $this->pack_signed_int(-$code); $this->code = $this->packSignedInt(-$code);
$length = 4; $length = 4;
return $this; return $this;

View File

@ -35,9 +35,9 @@ class HttpsStream extends HttpStream implements MTProtoBufferInterface
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
return parent::connectAsync($ctx->getCtx()->secure(true), $header); return parent::connectGenerator($ctx->getCtx()->secure(true), $header);
} }
/** /**

View File

@ -43,7 +43,7 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$this->stream = yield $ctx->getStream(\str_repeat(\chr(221), 4).$header); $this->stream = yield $ctx->getStream(\str_repeat(\chr(221), 4).$header);
} }
@ -65,9 +65,9 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
* *
* @return Generator * @return Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
$padding_length = $this->random_int($modulus = 16); $padding_length = $this->randomInt($modulus = 16);
$buffer = yield $this->stream->getWriteBuffer(4 + $length + $padding_length, $append.$this->random($padding_length)); $buffer = yield $this->stream->getWriteBuffer(4 + $length + $padding_length, $append.$this->random($padding_length));
yield $buffer->bufferWrite(\pack('V', $padding_length + $length)); yield $buffer->bufferWrite(\pack('V', $padding_length + $length));
@ -81,7 +81,7 @@ class IntermediatePaddedStream implements BufferedStreamInterface, MTProtoBuffer
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
$buffer = yield $this->stream->getReadBuffer($l); $buffer = yield $this->stream->getReadBuffer($l);
$length = \unpack('V', yield $buffer->bufferRead(4))[1]; $length = \unpack('V', yield $buffer->bufferRead(4))[1];

View File

@ -43,7 +43,7 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$this->stream = yield $ctx->getStream(\str_repeat(\chr(238), 4).$header); $this->stream = yield $ctx->getStream(\str_repeat(\chr(238), 4).$header);
} }
@ -65,7 +65,7 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
* *
* @return Generator * @return Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
$buffer = yield $this->stream->getWriteBuffer($length + 4, $append); $buffer = yield $this->stream->getWriteBuffer($length + 4, $append);
yield $buffer->bufferWrite(\pack('V', $length)); yield $buffer->bufferWrite(\pack('V', $length));
@ -80,7 +80,7 @@ class IntermediateStream implements BufferedStreamInterface, MTProtoBufferInterf
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
$buffer = yield $this->stream->getReadBuffer($l); $buffer = yield $this->stream->getReadBuffer($l);
$length = \unpack('V', yield $buffer->bufferRead(4))[1]; $length = \unpack('V', yield $buffer->bufferRead(4))[1];

View File

@ -52,7 +52,7 @@ class ObfuscatedStream implements BufferedProxyStreamInterface
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
if (isset($this->extra['address'])) { if (isset($this->extra['address'])) {
$ctx = $ctx->getCtx(); $ctx = $ctx->getCtx();
@ -111,7 +111,7 @@ class ObfuscatedStream implements BufferedProxyStreamInterface
* *
* @return Generator * @return Generator
*/ */
public function getWriteBufferAsync(int $length, string $append = ''): \Generator public function getWriteBufferGenerator(int $length, string $append = ''): \Generator
{ {
$this->write_buffer = yield $this->stream->getWriteBuffer($length); $this->write_buffer = yield $this->stream->getWriteBuffer($length);
if (\strlen($append)) { if (\strlen($append)) {
@ -129,7 +129,7 @@ class ObfuscatedStream implements BufferedProxyStreamInterface
* *
* @return Generator * @return Generator
*/ */
public function getReadBufferAsync(&$length): \Generator public function getReadBufferGenerator(&$length): \Generator
{ {
$this->read_buffer = yield $this->stream->getReadBuffer($l); $this->read_buffer = yield $this->stream->getReadBuffer($l);
@ -145,7 +145,7 @@ class ObfuscatedStream implements BufferedProxyStreamInterface
* *
* @return Generator That resolves with a string when the provided promise is resolved and the data is decrypted * @return Generator That resolves with a string when the provided promise is resolved and the data is decrypted
*/ */
public function bufferReadAsync(int $length): \Generator public function bufferReadGenerator(int $length): \Generator
{ {
return @$this->decrypt->encrypt(yield $this->read_buffer->bufferRead($length)); return @$this->decrypt->encrypt(yield $this->read_buffer->bufferRead($length));
} }

View File

@ -42,7 +42,7 @@ class HttpProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$ctx = $ctx->getCtx(); $ctx = $ctx->getCtx();
$uri = $ctx->getUri(); $uri = $ctx->getUri();

View File

@ -53,7 +53,7 @@ class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterfac
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$ctx = $ctx->getCtx(); $ctx = $ctx->getCtx();
$uri = $ctx->getUri(); $uri = $ctx->getUri();

View File

@ -53,7 +53,7 @@ class DefaultStream extends Socket implements RawStreamInterface, ProxyStreamInt
return $this->stream; return $this->stream;
} }
public function connectAsync(\danog\MadelineProto\Stream\ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(\danog\MadelineProto\Stream\ConnectionContext $ctx, string $header = ''): \Generator
{ {
if ($ctx->isSecure()) { if ($ctx->isSecure()) {
$this->stream = yield ($this->cryptoConnector)($ctx->getStringUri(), $ctx->getSocketContext(), null, $ctx->getCancellationToken()); $this->stream = yield ($this->cryptoConnector)($ctx->getStringUri(), $ctx->getSocketContext(), null, $ctx->getCancellationToken());

View File

@ -52,7 +52,7 @@ class PremadeStream extends Socket implements RawStreamInterface, ProxyStreamInt
return $this->stream; return $this->stream;
} }
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
if ($header !== '') { if ($header !== '') {
yield $this->stream->write($header); yield $this->stream->write($header);

View File

@ -63,7 +63,7 @@ class WsStream implements RawStreamInterface
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
$this->dc = $ctx->getIntDc(); $this->dc = $ctx->getIntDc();
$stream = yield $ctx->getStream(); $stream = yield $ctx->getStream();
@ -112,7 +112,7 @@ class WsStream implements RawStreamInterface
} }
} }
public function readAsync(): \Generator public function readGenerator(): \Generator
{ {
try { try {
if (!$this->message || ($data = yield $this->message->buffer()) === null) { if (!$this->message || ($data = yield $this->message->buffer()) === null) {

View File

@ -34,9 +34,9 @@ class WssStream extends WsStream
* *
* @return \Generator * @return \Generator
*/ */
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator public function connectGenerator(ConnectionContext $ctx, string $header = ''): \Generator
{ {
return parent::connectAsync($ctx->getCtx()->secure(true), $header); return parent::connectGenerator($ctx->getCtx()->secure(true), $header);
} }
public static function getName(): string public static function getName(): string

View File

@ -23,12 +23,12 @@ use danog\MadelineProto\Logger;
trait BotAPI trait BotAPI
{ {
public function html_entity_decode($stuff) public function htmlEntityDecode($stuff)
{ {
return \html_entity_decode(\preg_replace('#< *br */? *>#', "\n", $stuff)); return \html_entity_decode(\preg_replace('#< *br */? *>#', "\n", $stuff));
} }
public function mb_strlen($text) public function mbStrlen($text)
{ {
$length = 0; $length = 0;
$textlength = \strlen($text); $textlength = \strlen($text);
@ -42,9 +42,9 @@ trait BotAPI
return $length; return $length;
} }
public function mb_substr($text, $offset, $length = null) public function mbSubstr($text, $offset, $length = null)
{ {
$mb_text_length = $this->mb_strlen($text); $mb_text_length = $this->mbStrlen($text);
if ($offset < 0) { if ($offset < 0) {
$offset = $mb_text_length + $offset; $offset = $mb_text_length + $offset;
} }
@ -75,7 +75,7 @@ trait BotAPI
return $new_text; return $new_text;
} }
public function mb_str_split($text, $length) public function mbStrSplit($text, $length)
{ {
$tlength = \mb_strlen($text, 'UTF-8'); $tlength = \mb_strlen($text, 'UTF-8');
$result = []; $result = [];
@ -86,7 +86,7 @@ trait BotAPI
return $result; return $result;
} }
public function parse_buttons($rows) public function parseButtons($rows)
{ {
$newrows = []; $newrows = [];
$key = 0; $key = 0;
@ -125,7 +125,7 @@ trait BotAPI
return $newrows; return $newrows;
} }
public function parse_reply_markup($markup) public function parseReplyMarkup($markup)
{ {
if (isset($markup['force_reply']) && $markup['force_reply']) { if (isset($markup['force_reply']) && $markup['force_reply']) {
$markup['_'] = 'replyKeyboardForceReply'; $markup['_'] = 'replyKeyboardForceReply';
@ -145,24 +145,24 @@ trait BotAPI
$markup['single_use'] = $markup['one_time_keyboard']; $markup['single_use'] = $markup['one_time_keyboard'];
unset($markup['one_time_keyboard']); unset($markup['one_time_keyboard']);
} }
$markup['rows'] = $this->parse_buttons($markup['keyboard']); $markup['rows'] = $this->parseButtons($markup['keyboard']);
unset($markup['keyboard']); unset($markup['keyboard']);
} }
if (isset($markup['inline_keyboard'])) { if (isset($markup['inline_keyboard'])) {
$markup['_'] = 'replyInlineMarkup'; $markup['_'] = 'replyInlineMarkup';
$markup['rows'] = $this->parse_buttons($markup['inline_keyboard']); $markup['rows'] = $this->parseButtons($markup['inline_keyboard']);
unset($markup['inline_keyboard']); unset($markup['inline_keyboard']);
} }
return $markup; return $markup;
} }
public function MTProto_to_botAPI_async($data, $sent_arguments = []) public function MTProtoToBotAPI($data, $sent_arguments = [])
{ {
$newd = []; $newd = [];
if (!isset($data['_'])) { if (!isset($data['_'])) {
foreach ($data as $key => $element) { foreach ($data as $key => $element) {
$newd[$key] = yield $this->MTProto_to_botAPI_async($element, $sent_arguments); $newd[$key] = yield $this->MTProtoToBotAPI($element, $sent_arguments);
} }
return $newd; return $newd;
@ -173,20 +173,20 @@ trait BotAPI
$newd['date'] = $data['date']; $newd['date'] = $data['date'];
$newd['text'] = $sent_arguments['message']; $newd['text'] = $sent_arguments['message'];
if ($data['out']) { if ($data['out']) {
$newd['from'] = yield $this->get_pwr_chat_async($this->authorization['user']); $newd['from'] = yield $this->getPwrChat($this->authorization['user']);
} }
$newd['chat'] = yield $this->get_pwr_chat_async($sent_arguments['peer']); $newd['chat'] = yield $this->getPwrChat($sent_arguments['peer']);
if (isset($data['entities'])) { if (isset($data['entities'])) {
$newd['entities'] = yield $this->MTProto_to_botAPI_async($data['entities'], $sent_arguments); $newd['entities'] = yield $this->MTProtoToBotAPI($data['entities'], $sent_arguments);
} }
if (isset($data['media'])) { if (isset($data['media'])) {
$newd = \array_merge($newd, yield $this->MTProto_to_botAPI_async($data['media'], $sent_arguments)); $newd = \array_merge($newd, yield $this->MTProtoToBotAPI($data['media'], $sent_arguments));
} }
return $newd; return $newd;
case 'updateNewChannelMessage': case 'updateNewChannelMessage':
case 'updateNewMessage': case 'updateNewMessage':
return yield $this->MTProto_to_botAPI_async($data['message']); return yield $this->MTProtoToBotAPI($data['message']);
case 'message': case 'message':
$newd['message_id'] = $data['id']; $newd['message_id'] = $data['id'];
$newd['date'] = $data['date']; $newd['date'] = $data['date'];
@ -194,11 +194,11 @@ trait BotAPI
$newd['post'] = $data['post']; $newd['post'] = $data['post'];
$newd['silent'] = $data['silent']; $newd['silent'] = $data['silent'];
if (isset($data['from_id'])) { if (isset($data['from_id'])) {
$newd['from'] = yield $this->get_pwr_chat_async($data['from_id']); $newd['from'] = yield $this->getPwrChat($data['from_id']);
} }
$newd['chat'] = yield $this->get_pwr_chat_async($data['to_id']); $newd['chat'] = yield $this->getPwrChat($data['to_id']);
if (isset($data['entities'])) { if (isset($data['entities'])) {
$newd['entities'] = yield $this->MTProto_to_botAPI_async($data['entities'], $sent_arguments); $newd['entities'] = yield $this->MTProtoToBotAPI($data['entities'], $sent_arguments);
} }
if (isset($data['views'])) { if (isset($data['views'])) {
$newd['views'] = $data['views']; $newd['views'] = $data['views'];
@ -207,13 +207,13 @@ trait BotAPI
$newd['edit_date'] = $data['edit_date']; $newd['edit_date'] = $data['edit_date'];
} }
if (isset($data['via_bot_id'])) { if (isset($data['via_bot_id'])) {
$newd['via_bot'] = yield $this->get_pwr_chat_async($data['via_bot_id']); $newd['via_bot'] = yield $this->getPwrChat($data['via_bot_id']);
} }
if (isset($data['fwd_from']['from_id'])) { if (isset($data['fwd_from']['from_id'])) {
$newd['forward_from'] = yield $this->get_pwr_chat_async($data['fwd_from']['from_id']); $newd['forward_from'] = yield $this->getPwrChat($data['fwd_from']['from_id']);
} }
if (isset($data['fwd_from']['channel_id'])) { if (isset($data['fwd_from']['channel_id'])) {
$newd['forward_from_chat'] = yield $this->get_pwr_chat_async($data['fwd_from']['channel_id']); $newd['forward_from_chat'] = yield $this->getPwrChat($data['fwd_from']['channel_id']);
} }
if (isset($data['fwd_from']['date'])) { if (isset($data['fwd_from']['date'])) {
$newd['forward_date'] = $data['fwd_from']['date']; $newd['forward_date'] = $data['fwd_from']['date'];
@ -222,7 +222,7 @@ trait BotAPI
$newd['forward_from_message_id'] = $data['fwd_from']['channel_post']; $newd['forward_from_message_id'] = $data['fwd_from']['channel_post'];
} }
if (isset($data['media'])) { if (isset($data['media'])) {
$newd = \array_merge($newd, yield $this->MTProto_to_botAPI_async($data['media'], $sent_arguments)); $newd = \array_merge($newd, yield $this->MTProtoToBotAPI($data['media'], $sent_arguments));
} }
return $newd; return $newd;
@ -279,7 +279,7 @@ trait BotAPI
case 'messageEntityMentionName': case 'messageEntityMentionName':
unset($data['_']); unset($data['_']);
$data['type'] = 'text_mention'; $data['type'] = 'text_mention';
$data['user'] = yield $this->get_pwr_chat_async($data['user_id']); $data['user'] = yield $this->getPwrChat($data['user_id']);
unset($data['user_id']); unset($data['user_id']);
return $data; return $data;
@ -290,7 +290,7 @@ trait BotAPI
$res['photo'] = []; $res['photo'] = [];
foreach ($data['photo']['sizes'] as $key => $photo) { foreach ($data['photo']['sizes'] as $key => $photo) {
if (\in_array($photo['_'], ['photoCachedSize', 'photoSize'])) { if (\in_array($photo['_'], ['photoCachedSize', 'photoSize'])) {
$res['photo'][$key] = yield $this->photosize_to_botapi_async($photo, $data['photo']); $res['photo'][$key] = yield $this->photosizeToBotAPI($photo, $data['photo']);
} }
} }
@ -301,7 +301,7 @@ trait BotAPI
$type_name = 'document'; $type_name = 'document';
$res = []; $res = [];
if (isset($data['document']['thumbs']) && $data['document']['thumbs'] && \in_array(\end($data['document']['thumbs'])['_'], ['photoCachedSize', 'photoSize'])) { if (isset($data['document']['thumbs']) && $data['document']['thumbs'] && \in_array(\end($data['document']['thumbs'])['_'], ['photoCachedSize', 'photoSize'])) {
$res['thumb'] = yield $this->photosize_to_botapi_async(\end($data['document']['thumbs']), [], true); $res['thumb'] = yield $this->photosizeToBotAPI(\end($data['document']['thumbs']), [], true);
} }
foreach ($data['document']['attributes'] as $attribute) { foreach ($data['document']['attributes'] as $attribute) {
switch ($attribute['_']) { switch ($attribute['_']) {
@ -369,12 +369,12 @@ trait BotAPI
$res['file_name'] .= $res['ext']; $res['file_name'] .= $res['ext'];
unset($res['ext']); unset($res['ext']);
} else { } else {
$res['file_name'] .= $this->get_extension_from_mime($data['document']['mime_type']); $res['file_name'] .= $this->getExtensionFromMime($data['document']['mime_type']);
} }
$data['document']['_'] = 'bot_'.$type_name; $data['document']['_'] = 'bot_'.$type_name;
$res['file_size'] = $data['document']['size']; $res['file_size'] = $data['document']['size'];
$res['mime_type'] = $data['document']['mime_type']; $res['mime_type'] = $data['document']['mime_type'];
$res['file_id'] = $this->base64url_encode($this->rle_encode((yield $this->serialize_object_async(['type' => 'File'], $data['document'], 'File')).\chr(2))); $res['file_id'] = $this->base64urlEncode($this->rleEncode((yield $this->serializeObject(['type' => 'File'], $data['document'], 'File')).\chr(2)));
return [$type_name => $res, 'caption' => isset($data['caption']) ? $data['caption'] : '']; return [$type_name => $res, 'caption' => isset($data['caption']) ? $data['caption'] : ''];
default: default:
@ -382,7 +382,7 @@ trait BotAPI
} }
} }
public function botAPI_to_MTProto_async($arguments) public function botAPIToMTProto($arguments)
{ {
foreach (self::BOTAPI_PARAMS_CONVERSION as $bot => $mtproto) { foreach (self::BOTAPI_PARAMS_CONVERSION as $bot => $mtproto) {
if (isset($arguments[$bot]) && !isset($arguments[$mtproto])) { if (isset($arguments[$bot]) && !isset($arguments[$mtproto])) {
@ -391,16 +391,16 @@ trait BotAPI
} }
} }
if (isset($arguments['reply_markup'])) { if (isset($arguments['reply_markup'])) {
$arguments['reply_markup'] = $this->parse_reply_markup($arguments['reply_markup']); $arguments['reply_markup'] = $this->parseReplyMarkup($arguments['reply_markup']);
} }
if (isset($arguments['parse_mode'])) { if (isset($arguments['parse_mode'])) {
$arguments = yield $this->parse_mode_async($arguments); $arguments = yield $this->parseMode($arguments);
} }
return $arguments; return $arguments;
} }
public function parse_node_async($node, &$entities, &$new_message, &$offset) public function parseNode($node, &$entities, &$new_message, &$offset)
{ {
switch ($node->nodeName) { switch ($node->nodeName) {
case 'br': case 'br':
@ -410,27 +410,27 @@ trait BotAPI
case 's': case 's':
case 'strike': case 'strike':
case 'del': case 'del':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityStrike', 'offset' => $offset, 'length' => $length]; $entities[] = ['_' => 'messageEntityStrike', 'offset' => $offset, 'length' => $length];
$new_message .= $text; $new_message .= $text;
$offset += $length; $offset += $length;
break; break;
case 'u': case 'u':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityUnderline', 'offset' => $offset, 'length' => $length]; $entities[] = ['_' => 'messageEntityUnderline', 'offset' => $offset, 'length' => $length];
$new_message .= $text; $new_message .= $text;
$offset += $length; $offset += $length;
break; break;
case 'blockquote': case 'blockquote':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityBlockquote', 'offset' => $offset, 'length' => $length]; $entities[] = ['_' => 'messageEntityBlockquote', 'offset' => $offset, 'length' => $length];
$new_message .= $text; $new_message .= $text;
@ -438,9 +438,9 @@ trait BotAPI
break; break;
case 'b': case 'b':
case 'strong': case 'strong':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityBold', 'offset' => $offset, 'length' => $length]; $entities[] = ['_' => 'messageEntityBold', 'offset' => $offset, 'length' => $length];
$new_message .= $text; $new_message .= $text;
@ -448,27 +448,27 @@ trait BotAPI
break; break;
case 'i': case 'i':
case 'em': case 'em':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityItalic', 'offset' => $offset, 'length' => $length]; $entities[] = ['_' => 'messageEntityItalic', 'offset' => $offset, 'length' => $length];
$new_message .= $text; $new_message .= $text;
$offset += $length; $offset += $length;
break; break;
case 'code': case 'code':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$entities[] = ['_' => 'messageEntityCode', 'offset' => $offset, 'length' => $length]; $entities[] = ['_' => 'messageEntityCode', 'offset' => $offset, 'length' => $length];
$new_message .= $text; $new_message .= $text;
$offset += $length; $offset += $length;
break; break;
case 'pre': case 'pre':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$language = $node->getAttribute('language'); $language = $node->getAttribute('language');
if ($language === null) { if ($language === null) {
@ -480,15 +480,15 @@ trait BotAPI
break; break;
case 'p': case 'p':
foreach ($node->childNodes as $node) { foreach ($node->childNodes as $node) {
yield $this->parse_node_async($node, $entities, $new_message, $offset); yield $this->parseNode($node, $entities, $new_message, $offset);
} }
break; break;
case 'a': case 'a':
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$href = $node->getAttribute('href'); $href = $node->getAttribute('href');
if (\preg_match('|mention:(.*)|', $href, $matches) || \preg_match('|tg://user\?id=(.*)|', $href, $matches)) { if (\preg_match('|mention:(.*)|', $href, $matches) || \preg_match('|tg://user\?id=(.*)|', $href, $matches)) {
$mention = yield $this->get_info_async($matches[1]); $mention = yield $this->getInfo($matches[1]);
if (!isset($mention['InputUser'])) { if (!isset($mention['InputUser'])) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['peer_not_in_db']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['peer_not_in_db']);
} }
@ -510,15 +510,15 @@ trait BotAPI
$offset += $length; $offset += $length;
break; break;
default: default:
$text = $this->html_entity_decode($node->textContent); $text = $this->htmlEntityDecode($node->textContent);
$length = $this->mb_strlen($text); $length = $this->mbStrlen($text);
$new_message .= $text; $new_message .= $text;
$offset += $length; $offset += $length;
break; break;
} }
} }
public function parse_mode_async($arguments) public function parseMode($arguments)
{ {
if ($arguments['message'] === '' || !isset($arguments['message']) || !isset($arguments['parse_mode'])) { if ($arguments['message'] === '' || !isset($arguments['message']) || !isset($arguments['parse_mode'])) {
return $arguments; return $arguments;
@ -533,7 +533,7 @@ trait BotAPI
if (\stripos($arguments['parse_mode'], 'html') !== false) { if (\stripos($arguments['parse_mode'], 'html') !== false) {
$new_message = ''; $new_message = '';
$arguments['message'] = \trim($this->html_fixtags($arguments['message'])); $arguments['message'] = \trim($this->htmlFixtags($arguments['message']));
$dom = new \DOMDocument(); $dom = new \DOMDocument();
$dom->loadHTML(\mb_convert_encoding($arguments['message'], 'HTML-ENTITIES', 'UTF-8')); $dom->loadHTML(\mb_convert_encoding($arguments['message'], 'HTML-ENTITIES', 'UTF-8'));
@ -542,10 +542,10 @@ trait BotAPI
} }
$offset = 0; $offset = 0;
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $node) { foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $node) {
yield $this->parse_node_async($node, $arguments['entities'], $new_message, $offset); yield $this->parseNode($node, $arguments['entities'], $new_message, $offset);
} }
if (isset($arguments['entities']['buttons'])) { if (isset($arguments['entities']['buttons'])) {
$arguments['reply_markup'] = $this->build_rows($arguments['entities']['buttons']); $arguments['reply_markup'] = $this->buildRows($arguments['entities']['buttons']);
unset($arguments['entities']['buttons']); unset($arguments['entities']['buttons']);
} }
unset($arguments['parse_mode']); unset($arguments['parse_mode']);
@ -555,9 +555,9 @@ trait BotAPI
return $arguments; return $arguments;
} }
public function split_to_chunks_async($args) public function splitToChunks($args)
{ {
$args = yield $this->parse_mode_async($args); $args = yield $this->parseMode($args);
if (!isset($args['entities'])) { if (!isset($args['entities'])) {
$args['entities'] = []; $args['entities'] = [];
} }
@ -569,7 +569,7 @@ trait BotAPI
$text_arr = []; $text_arr = [];
foreach ($this->multipleExplodeKeepDelimiters(["\n"], $args['message']) as $word) { foreach ($this->multipleExplodeKeepDelimiters(["\n"], $args['message']) as $word) {
if (\mb_strlen($word, 'UTF-8') > $max_length) { if (\mb_strlen($word, 'UTF-8') > $max_length) {
foreach ($this->mb_str_split($word, $max_length) as $vv) { foreach ($this->mbStrSplit($word, $max_length) as $vv) {
$text_arr[] = $vv; $text_arr[] = $vv;
} }
} else { } else {
@ -581,7 +581,7 @@ trait BotAPI
$multiple_args = [$multiple_args_base]; $multiple_args = [$multiple_args_base];
$i = 0; $i = 0;
foreach ($text_arr as $word) { foreach ($text_arr as $word) {
if ($this->mb_strlen($multiple_args[$i]['message'].$word) <= $max_length) { if ($this->mbStrlen($multiple_args[$i]['message'].$word) <= $max_length) {
$multiple_args[$i]['message'] .= $word; $multiple_args[$i]['message'] .= $word;
} else { } else {
$i++; $i++;
@ -595,23 +595,23 @@ trait BotAPI
for ($k = 0; $k < \count($args['entities']); $k++) { for ($k = 0; $k < \count($args['entities']); $k++) {
$entity = $args['entities'][$k]; $entity = $args['entities'][$k];
do { do {
while ($entity['offset'] > $offset + $this->mb_strlen($multiple_args[$i]['message'])) { while ($entity['offset'] > $offset + $this->mbStrlen($multiple_args[$i]['message'])) {
$offset += $this->mb_strlen($multiple_args[$i]['message']); $offset += $this->mbStrlen($multiple_args[$i]['message']);
$i++; $i++;
} }
$entity['offset'] -= $offset; $entity['offset'] -= $offset;
if ($entity['offset'] + $entity['length'] > $this->mb_strlen($multiple_args[$i]['message'])) { if ($entity['offset'] + $entity['length'] > $this->mbStrlen($multiple_args[$i]['message'])) {
$newentity = $entity; $newentity = $entity;
$newentity['length'] = $entity['length'] - ($this->mb_strlen($multiple_args[$i]['message']) - $entity['offset']); $newentity['length'] = $entity['length'] - ($this->mbStrlen($multiple_args[$i]['message']) - $entity['offset']);
$entity['length'] = $this->mb_strlen($multiple_args[$i]['message']) - $entity['offset']; $entity['length'] = $this->mbStrlen($multiple_args[$i]['message']) - $entity['offset'];
$offset += $entity['length']; //$this->mb_strlen($multiple_args[$i]['message']); $offset += $entity['length']; //$this->mbStrlen($multiple_args[$i]['message']);
$newentity['offset'] = $offset; $newentity['offset'] = $offset;
$prev_length = $this->mb_strlen($multiple_args[$i]['message']); $prev_length = $this->mbStrlen($multiple_args[$i]['message']);
$multiple_args[$i]['message'] = \rtrim($multiple_args[$i]['message']); $multiple_args[$i]['message'] = \rtrim($multiple_args[$i]['message']);
$diff = $prev_length - $this->mb_strlen($multiple_args[$i]['message']); $diff = $prev_length - $this->mbStrlen($multiple_args[$i]['message']);
if ($diff) { if ($diff) {
$entity['length'] -= $diff; $entity['length'] -= $diff;
@ -628,9 +628,9 @@ trait BotAPI
continue; continue;
} }
$prev_length = $this->mb_strlen($multiple_args[$i]['message']); $prev_length = $this->mbStrlen($multiple_args[$i]['message']);
$multiple_args[$i]['message'] = \rtrim($multiple_args[$i]['message']); $multiple_args[$i]['message'] = \rtrim($multiple_args[$i]['message']);
$diff = $prev_length - $this->mb_strlen($multiple_args[$i]['message']); $diff = $prev_length - $this->mbStrlen($multiple_args[$i]['message']);
if ($diff) { if ($diff) {
$entity['length'] -= $diff; $entity['length'] -= $diff;
foreach ($args['entities'] as $key => &$eentity) { foreach ($args['entities'] as $key => &$eentity) {
@ -671,9 +671,9 @@ trait BotAPI
$finalArray = []; $finalArray = [];
$delimOffset = 0; $delimOffset = 0;
foreach ($initialArray as $item) { foreach ($initialArray as $item) {
$delimOffset += $this->mb_strlen($item); $delimOffset += $this->mbStrlen($item);
//if ($this->mb_strlen($item) > 0) { //if ($this->mbStrlen($item) > 0) {
$finalArray[] = $item.($delimOffset < $this->mb_strlen($string) ? $string[$delimOffset] : ''); $finalArray[] = $item.($delimOffset < $this->mbStrlen($string) ? $string[$delimOffset] : '');
//} //}
$delimOffset++; $delimOffset++;
} }
@ -681,7 +681,7 @@ trait BotAPI
return $finalArray; return $finalArray;
} }
public function html_fixtags($text) public function htmlFixtags($text)
{ {
$diff = 0; $diff = 0;
\preg_match_all('#(.*?)(<(\bu\b|\bs\b|\ba\b|\bb\b|\bstrong\b|\bblockquote\b|\bstrike\b|\bdel\b|\bem\b|i|\bcode\b|\bpre\b)[^>]*>)(.*?)([<]\s*/\s*\3[>])#is', $text, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); \preg_match_all('#(.*?)(<(\bu\b|\bs\b|\ba\b|\bb\b|\bstrong\b|\bblockquote\b|\bstrike\b|\bdel\b|\bem\b|i|\bcode\b|\bpre\b)[^>]*>)(.*?)([<]\s*/\s*\3[>])#is', $text, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
@ -724,7 +724,7 @@ trait BotAPI
return \htmlentities($text); return \htmlentities($text);
} }
public function build_rows($button_list) public function buildRows($button_list)
{ {
$end = false; $end = false;
$rows = []; $rows = [];

View File

@ -21,17 +21,17 @@ namespace danog\MadelineProto\TL\Conversion;
trait BotAPIFiles trait BotAPIFiles
{ {
public function base64url_decode($data) public function base64urlDecode($data)
{ {
return \base64_decode(\str_pad(\strtr($data, '-_', '+/'), \strlen($data) % 4, '=', STR_PAD_RIGHT)); return \base64_decode(\str_pad(\strtr($data, '-_', '+/'), \strlen($data) % 4, '=', STR_PAD_RIGHT));
} }
public function base64url_encode($data) public function base64urlEncode($data)
{ {
return \rtrim(\strtr(\base64_encode($data), '+/', '-_'), '='); return \rtrim(\strtr(\base64_encode($data), '+/', '-_'), '=');
} }
public function rle_decode($string) public function rleDecode($string)
{ {
$new = ''; $new = '';
$last = ''; $last = '';
@ -50,7 +50,7 @@ trait BotAPIFiles
return $string; return $string;
} }
public function rle_encode($string) public function rleEncode($string)
{ {
$new = ''; $new = '';
$count = 0; $count = 0;
@ -70,18 +70,18 @@ trait BotAPIFiles
return $new; return $new;
} }
public function photosize_to_botapi_async($photoSize, $photo, $thumbnail = false) public function photosizeToBotAPI($photoSize, $photo, $thumbnail = false)
{ {
$ext = '.jpg';//$this->get_extension_from_location(['_' => 'inputFileLocation', 'volume_id' => $photoSize['location']['volume_id'], 'local_id' => $photoSize['location']['local_id'], 'secret' => $photoSize['location']['secret'], 'dc_id' => $photoSize['location']['dc_id']], '.jpg'); $ext = '.jpg';//$this->getExtensionFromLocation(['_' => 'inputFileLocation', 'volume_id' => $photoSize['location']['volume_id'], 'local_id' => $photoSize['location']['local_id'], 'secret' => $photoSize['location']['secret'], 'dc_id' => $photoSize['location']['dc_id']], '.jpg');
$photoSize['location']['access_hash'] = $photo['access_hash'] ?? 0; $photoSize['location']['access_hash'] = $photo['access_hash'] ?? 0;
$photoSize['location']['id'] = $photo['id'] ?? 0; $photoSize['location']['id'] = $photo['id'] ?? 0;
$photoSize['location']['secret'] = $photo['location']['secret'] ?? 0; $photoSize['location']['secret'] = $photo['location']['secret'] ?? 0;
$photoSize['location']['dc_id'] = $photo['dc_id'] ?? 0; $photoSize['location']['dc_id'] = $photo['dc_id'] ?? 0;
$photoSize['location']['_'] = $thumbnail ? 'bot_thumbnail' : 'bot_photo'; $photoSize['location']['_'] = $thumbnail ? 'bot_thumbnail' : 'bot_photo';
$data = (yield $this->serialize_object_async(['type' => 'File'], $photoSize['location'], 'File')).\chr(2); $data = (yield $this->serializeObject(['type' => 'File'], $photoSize['location'], 'File')).\chr(2);
return [ return [
'file_id' => $this->base64url_encode($this->rle_encode($data)), 'file_id' => $this->base64urlEncode($this->rleEncode($data)),
'width' => $photoSize['w'], 'width' => $photoSize['w'],
'height' => $photoSize['h'], 'height' => $photoSize['h'],
'file_size' => isset($photoSize['size']) ? $photoSize['size'] : \strlen($photoSize['bytes']), 'file_size' => isset($photoSize['size']) ? $photoSize['size'] : \strlen($photoSize['bytes']),
@ -90,9 +90,9 @@ trait BotAPIFiles
]; ];
} }
public function unpack_file_id($file_id) public function unpackFileId($file_id)
{ {
$file_id = $this->rle_decode($this->base64url_decode($file_id)); $file_id = $this->rleDecode($this->base64urlDecode($file_id));
if ($file_id[\strlen($file_id) - 1] !== \chr(2)) { if ($file_id[\strlen($file_id) - 1] !== \chr(2)) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['last_byte_invalid']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['last_byte_invalid']);
} }

View File

@ -36,6 +36,6 @@ class Exception extends \Exception
public function __construct($message, $file = '') public function __construct($message, $file = '')
{ {
parent::__construct($message); parent::__construct($message);
$this->prettify_tl($file); $this->prettifyTl($file);
} }
} }

View File

@ -19,7 +19,7 @@ namespace danog\MadelineProto\TL\Conversion;
*/ */
trait Extension trait Extension
{ {
public function get_mime_from_extension($extension, $default) public function getMimeFromExtension($extension, $default)
{ {
$ext = \ltrim($extension, '.'); $ext = \ltrim($extension, '.');
if (isset(self::ALL_MIMES[$ext])) { if (isset(self::ALL_MIMES[$ext])) {
@ -29,7 +29,7 @@ trait Extension
return $default; return $default;
} }
public function get_extension_from_mime($mime) public function getExtensionFromMime($mime)
{ {
foreach (self::ALL_MIMES as $key => $value) { foreach (self::ALL_MIMES as $key => $value) {
if (\array_search($mime, $value) !== false) { if (\array_search($mime, $value) !== false) {
@ -40,7 +40,7 @@ trait Extension
return ''; return '';
} }
public function get_extension_from_location($location, $default) public function getExtensionFromLocation($location, $default)
{ {
return $default; return $default;
//('upload.getFile', ['location' => $location, 'offset' => 0, 'limit' => 2], ['heavy' => true, 'datacenter' => $location['dc_id']]); //('upload.getFile', ['location' => $location, 'offset' => 0, 'limit' => 2], ['heavy' => true, 'datacenter' => $location['dc_id']]);
@ -69,14 +69,14 @@ trait Extension
} }
} }
public function get_mime_from_file($file) public function getMimeFromFile($file)
{ {
$finfo = new \finfo(FILEINFO_MIME_TYPE); $finfo = new \finfo(FILEINFO_MIME_TYPE);
return $finfo->file($file); return $finfo->file($file);
} }
public function get_mime_from_buffer($buffer) public function getMimeFromBuffer($buffer)
{ {
$finfo = new \finfo(FILEINFO_MIME_TYPE); $finfo = new \finfo(FILEINFO_MIME_TYPE);

View File

@ -21,7 +21,7 @@ namespace danog\MadelineProto\TL\Conversion;
trait TD trait TD
{ {
public function tdcli_to_td(&$params, $key = null) public function tdcliToTd(&$params, $key = null)
{ {
if (!\is_array($params)) { if (!\is_array($params)) {
return $params; return $params;
@ -32,7 +32,7 @@ trait TD
return $params; return $params;
} }
foreach ($params as $key => $value) { foreach ($params as $key => $value) {
$value = $this->tdcli_to_td($value); $value = $this->tdcliToTd($value);
if (\preg_match('/_$/', $key)) { if (\preg_match('/_$/', $key)) {
$params[\preg_replace('/_$/', '', $key)] = $value; $params[\preg_replace('/_$/', '', $key)] = $value;
unset($params[$key]); unset($params[$key]);
@ -44,7 +44,7 @@ trait TD
return $params; return $params;
} }
public function td_to_mtproto_async($params) public function tdToMTProto($params)
{ {
$newparams = ['_' => self::REVERSE[$params['_']]]; $newparams = ['_' => self::REVERSE[$params['_']]];
foreach (self::TD_PARAMS_CONVERSION[$newparams['_']] as $td => $mtproto) { foreach (self::TD_PARAMS_CONVERSION[$newparams['_']] as $td => $mtproto) {
@ -66,7 +66,7 @@ trait TD
default: default:
$newparams[$mtproto[0]] = isset($params[$td]) ? $params[$td] : null; $newparams[$mtproto[0]] = isset($params[$td]) ? $params[$td] : null;
if (\is_array($newparams[$mtproto[0]])) { if (\is_array($newparams[$mtproto[0]])) {
$newparams[$mtproto[0]] = yield $this->mtproto_to_td_async($newparams[$mtproto[0]]); $newparams[$mtproto[0]] = yield $this->MTProtoToTd($newparams[$mtproto[0]]);
} }
} }
} }
@ -75,12 +75,12 @@ trait TD
return $newparams; return $newparams;
} }
public function mtproto_to_tdcli_async($params) public function MTProtoToTdcli($params)
{ {
return $this->td_to_tdcli(yield $this->mtproto_to_td_async($params)); return $this->tdToTdcli(yield $this->MTProtoToTd($params));
} }
public function mtproto_to_td_async(&$params) public function MTProtoToTd(&$params)
{ {
if (!\is_array($params)) { if (!\is_array($params)) {
return $params; return $params;
@ -100,7 +100,7 @@ trait TD
} else { } else {
switch (\end($mtproto)) { switch (\end($mtproto)) {
case 'choose_chat_id_from_botapi': case 'choose_chat_id_from_botapi':
$newparams[$td] = (yield $this->get_info_async($params[$mtproto[0]]))['bot_api_id'] == $this->authorization['user']['id'] ? $params['from_id'] : yield $this->get_info_async($params[$mtproto[0]])['bot_api_id']; $newparams[$td] = (yield $this->getInfo($params[$mtproto[0]]))['bot_api_id'] == $this->authorization['user']['id'] ? $params['from_id'] : yield $this->getInfo($params[$mtproto[0]])['bot_api_id'];
break; break;
case 'choose_incoming_or_sent': case 'choose_incoming_or_sent':
$newparams[$td] = ['_' => $params['out'] ? 'messageIsSuccessfullySent' : 'messageIsIncoming']; $newparams[$td] = ['_' => $params['out'] ? 'messageIsSuccessfullySent' : 'messageIsIncoming'];
@ -138,7 +138,7 @@ trait TD
if ($params['message'] !== '') { if ($params['message'] !== '') {
$newparams[$td] = ['_' => 'messageText', 'text' => $params['message']]; $newparams[$td] = ['_' => 'messageText', 'text' => $params['message']];
if (isset($params['media']['_']) && $params['media']['_'] === 'messageMediaWebPage') { if (isset($params['media']['_']) && $params['media']['_'] === 'messageMediaWebPage') {
$newparams[$td]['web_page'] = yield $this->mtproto_to_td_async($params['media']['webpage']); $newparams[$td]['web_page'] = yield $this->MTProtoToTd($params['media']['webpage']);
} }
if (isset($params['entities'])) { if (isset($params['entities'])) {
$newparams[$td]['entities'] = $params['entities']; $newparams[$td]['entities'] = $params['entities'];
@ -154,7 +154,7 @@ trait TD
$newparams[$td] = isset($params[$mtproto[0]]) ? $params[$mtproto[0]] : null; $newparams[$td] = isset($params[$mtproto[0]]) ? $params[$mtproto[0]] : null;
} }
if (\is_array($newparams[$td])) { if (\is_array($newparams[$td])) {
$newparams[$td] = yield $this->mtproto_to_td_async($newparams[$td]); $newparams[$td] = yield $this->MTProtoToTd($newparams[$td]);
} }
} }
} }
@ -163,7 +163,7 @@ trait TD
return $newparams; return $newparams;
} }
public function td_to_tdcli($params) public function tdToTdcli($params)
{ {
if (!\is_array($params)) { if (!\is_array($params)) {
return $params; return $params;
@ -176,7 +176,7 @@ trait TD
if (!\is_numeric($key) && !\preg_match('/_^/', $key)) { if (!\is_numeric($key) && !\preg_match('/_^/', $key)) {
$key = $key.'_'; $key = $key.'_';
} }
$newparams[$key] = $this->td_to_tdcli($value); $newparams[$key] = $this->tdToTdcli($value);
} }
} }

View File

@ -36,6 +36,6 @@ class Exception extends \Exception
public function __construct($message, $file = '') public function __construct($message, $file = '')
{ {
parent::__construct($message); parent::__construct($message);
$this->prettify_tl($file); $this->prettifyTl($file);
} }
} }

View File

@ -55,7 +55,7 @@ trait PrettyException
{ {
if (!$this->updated) { if (!$this->updated) {
$this->updated = true; $this->updated = true;
$this->prettify_tl($this->method, $trace); $this->prettifyTl($this->method, $trace);
} }
} }
/** /**
@ -76,7 +76,7 @@ trait PrettyException
* *
* @return void * @return void
*/ */
public function prettify_tl(string $init = '', array $trace = null) public function prettifyTl(string $init = '', array $trace = null)
{ {
$this->method = $init; $this->method = $init;
$previous_trace = $this->tl_trace; $previous_trace = $this->tl_trace;

View File

@ -29,10 +29,10 @@ trait TL
public $td_descriptions; public $td_descriptions;
public $tl_callbacks = []; public $tl_callbacks = [];
public function construct_tl($files, $objects = []) public function constructTl($files, $objects = [])
{ {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['TL_loading'], \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['TL_loading'], \danog\MadelineProto\Logger::VERBOSE);
$this->update_callbacks($objects); $this->updateCallbacks($objects);
$this->constructors = new TLConstructor(); $this->constructors = new TLConstructor();
$this->methods = new TLMethod(); $this->methods = new TLMethod();
$this->td_constructors = new TLConstructor(); $this->td_constructors = new TLConstructor();
@ -147,10 +147,10 @@ trait TL
} }
} else { } else {
foreach ($TL_dict['constructors'] as $key => $value) { foreach ($TL_dict['constructors'] as $key => $value) {
$TL_dict['constructors'][$key]['id'] = $this->pack_signed_int($TL_dict['constructors'][$key]['id']); $TL_dict['constructors'][$key]['id'] = $this->packSignedInt($TL_dict['constructors'][$key]['id']);
} }
foreach ($TL_dict['methods'] as $key => $value) { foreach ($TL_dict['methods'] as $key => $value) {
$TL_dict['methods'][$key]['id'] = $this->pack_signed_int($TL_dict['methods'][$key]['id']); $TL_dict['methods'][$key]['id'] = $this->packSignedInt($TL_dict['methods'][$key]['id']);
} }
} }
@ -176,7 +176,7 @@ trait TL
if (isset($files['td']) && isset($files['telegram'])) { if (isset($files['td']) && isset($files['telegram'])) {
foreach ($this->td_constructors->by_id as $id => $data) { foreach ($this->td_constructors->by_id as $id => $data) {
$name = $data['predicate']; $name = $data['predicate'];
if ($this->constructors->find_by_id($id) === false) { if ($this->constructors->findById($id) === false) {
unset($this->td_descriptions['constructors'][$name]); unset($this->td_descriptions['constructors'][$name]);
} else { } else {
if (!\count($this->td_descriptions['constructors'][$name]['params'])) { if (!\count($this->td_descriptions['constructors'][$name]['params'])) {
@ -189,7 +189,7 @@ trait TL
} }
foreach ($this->td_methods->by_id as $id => $data) { foreach ($this->td_methods->by_id as $id => $data) {
$name = $data['method']; $name = $data['method'];
if ($this->methods->find_by_id($id) === false) { if ($this->methods->findById($id) === false) {
unset($this->td_descriptions['methods'][$name]); unset($this->td_descriptions['methods'][$name]);
} else { } else {
foreach ($this->td_descriptions['methods'][$name]['params'] as $k => $param) { foreach ($this->td_descriptions['methods'][$name]['params'] as $k => $param) {
@ -200,7 +200,7 @@ trait TL
} }
} }
public function get_method_namespaces() public function getMethodNamespaces()
{ {
$res = []; $res = [];
foreach ($this->methods->method_namespace as $pair) { foreach ($this->methods->method_namespace as $pair) {
@ -211,12 +211,12 @@ trait TL
return $res; return $res;
} }
public function get_methods_namespaced() public function getMethodsNamespaced()
{ {
return $this->methods->method_namespace; return $this->methods->method_namespace;
} }
public function update_callbacks($objects) public function updateCallbacks($objects)
{ {
$this->tl_callbacks = []; $this->tl_callbacks = [];
foreach ($objects as $object) { foreach ($objects as $object) {
@ -246,9 +246,9 @@ trait TL
} }
} }
public function deserialize_bool($id) public function deserializeBool($id)
{ {
$tl_elem = $this->constructors->find_by_id($id); $tl_elem = $this->constructors->findById($id);
if ($tl_elem === false) { if ($tl_elem === false) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['bool_error']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['bool_error']);
} }
@ -256,25 +256,25 @@ trait TL
return $tl_elem['predicate'] === 'boolTrue'; return $tl_elem['predicate'] === 'boolTrue';
} }
public function serialize_object_async($type, $object, $ctx, $layer = -1) public function serializeObject($type, $object, $ctx, $layer = -1)
{ {
switch ($type['type']) { switch ($type['type']) {
case 'int': case 'int':
if (!\is_numeric($object)) { if (!\is_numeric($object)) {
if (\is_array($object) && $type['name'] === 'hash') { if (\is_array($object) && $type['name'] === 'hash') {
$object = $this->gen_vector_hash($object); $object = $this->genVectorHash($object);
} else { } else {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']);
} }
} }
return $this->pack_signed_int($object); return $this->packSignedInt($object);
case '#': case '#':
if (!\is_numeric($object)) { if (!\is_numeric($object)) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']);
} }
return $this->pack_unsigned_int($object); return $this->packUnsignedInt($object);
case 'long': case 'long':
if (\is_object($object)) { if (\is_object($object)) {
return \str_pad(\strrev($object->toBytes()), 8, \chr(0)); return \str_pad(\strrev($object->toBytes()), 8, \chr(0));
@ -289,7 +289,7 @@ trait TL
throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['not_numeric']);
} }
return $this->pack_signed_long($object); return $this->packSignedLong($object);
case 'int128': case 'int128':
if (\strlen($object) !== 16) { if (\strlen($object) !== 16) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['long_not_16']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['long_not_16']);
@ -309,7 +309,7 @@ trait TL
return (string) $object; return (string) $object;
case 'double': case 'double':
return $this->pack_double($object); return $this->packDouble($object);
case 'string': case 'string':
if (!\is_string($object)) { if (!\is_string($object)) {
throw new Exception("You didn't provide a valid string"); throw new Exception("You didn't provide a valid string");
@ -323,7 +323,7 @@ trait TL
$concat .= \pack('@'.$this->posmod(-$l - 1, 4)); $concat .= \pack('@'.$this->posmod(-$l - 1, 4));
} else { } else {
$concat .= \chr(254); $concat .= \chr(254);
$concat .= \substr($this->pack_signed_int($l), 0, 3); $concat .= \substr($this->packSignedInt($l), 0, 3);
$concat .= $object; $concat .= $object;
$concat .= \pack('@'.$this->posmod(-$l, 4)); $concat .= \pack('@'.$this->posmod(-$l, 4));
} }
@ -344,14 +344,14 @@ trait TL
$concat .= \pack('@'.$this->posmod(-$l - 1, 4)); $concat .= \pack('@'.$this->posmod(-$l - 1, 4));
} else { } else {
$concat .= \chr(254); $concat .= \chr(254);
$concat .= \substr($this->pack_signed_int($l), 0, 3); $concat .= \substr($this->packSignedInt($l), 0, 3);
$concat .= $object; $concat .= $object;
$concat .= \pack('@'.$this->posmod(-$l, 4)); $concat .= \pack('@'.$this->posmod(-$l, 4));
} }
return $concat; return $concat;
case 'Bool': case 'Bool':
return $this->constructors->find_by_predicate((bool) $object ? 'boolTrue' : 'boolFalse')['id']; return $this->constructors->findByPredicate((bool) $object ? 'boolTrue' : 'boolFalse')['id'];
case 'true': case 'true':
return; return;
case '!X': case '!X':
@ -363,10 +363,10 @@ trait TL
if (isset($object['_'])) { if (isset($object['_'])) {
throw new Exception('You must provide an array of '.$type['subtype'].' objects, not a '.$type['subtype']." object. Example: [['_' => ".$type['subtype'].', ... ]]'); throw new Exception('You must provide an array of '.$type['subtype'].' objects, not a '.$type['subtype']." object. Example: [['_' => ".$type['subtype'].', ... ]]');
} }
$concat = $this->constructors->find_by_predicate('vector')['id']; $concat = $this->constructors->findByPredicate('vector')['id'];
$concat .= $this->pack_unsigned_int(\count($object)); $concat .= $this->packUnsignedInt(\count($object));
foreach ($object as $k => $current_object) { foreach ($object as $k => $current_object) {
$concat .= yield $this->serialize_object_async(['type' => $type['subtype']], $current_object, $k); $concat .= yield $this->serializeObject(['type' => $type['subtype']], $current_object, $k);
} }
return $concat; return $concat;
@ -374,9 +374,9 @@ trait TL
if (!\is_array($object)) { if (!\is_array($object)) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['array_invalid']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['array_invalid']);
} }
$concat = $this->pack_unsigned_int(\count($object)); $concat = $this->packUnsignedInt(\count($object));
foreach ($object as $k => $current_object) { foreach ($object as $k => $current_object) {
$concat .= yield $this->serialize_object_async(['type' => $type['subtype']], $current_object, $k); $concat .= yield $this->serializeObject(['type' => $type['subtype']], $current_object, $k);
} }
return $concat; return $concat;
@ -389,7 +389,7 @@ trait TL
if ($type['type'] === 'InputMessage' && !\is_array($object)) { if ($type['type'] === 'InputMessage' && !\is_array($object)) {
$object = ['_' => 'inputMessageID', 'id' => $object]; $object = ['_' => 'inputMessageID', 'id' => $object];
} elseif (isset($this->tl_callbacks[TLCallback::TYPE_MISMATCH_CALLBACK][$type['type']]) && (!\is_array($object) || isset($object['_']) && $this->constructors->find_by_predicate($object['_'])['type'] !== $type['type'])) { } elseif (isset($this->tl_callbacks[TLCallback::TYPE_MISMATCH_CALLBACK][$type['type']]) && (!\is_array($object) || isset($object['_']) && $this->constructors->findByPredicate($object['_'])['type'] !== $type['type'])) {
$object = yield $this->tl_callbacks[TLCallback::TYPE_MISMATCH_CALLBACK][$type['type']]($object); $object = yield $this->tl_callbacks[TLCallback::TYPE_MISMATCH_CALLBACK][$type['type']]($object);
if (!isset($object[$type['type']])) { if (!isset($object[$type['type']])) {
throw new \danog\MadelineProto\Exception("Could not convert {$type['type']} object"); throw new \danog\MadelineProto\Exception("Could not convert {$type['type']} object");
@ -397,7 +397,7 @@ trait TL
$object = $object[$type['type']]; $object = $object[$type['type']];
} }
if (!isset($object['_'])) { if (!isset($object['_'])) {
$constructorData = $this->constructors->find_by_predicate($type['type'], $layer); $constructorData = $this->constructors->findByPredicate($type['type'], $layer);
if ($constructorData === false) { if ($constructorData === false) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['predicate_not_set']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['predicate_not_set']);
} }
@ -409,7 +409,7 @@ trait TL
} }
$predicate = $object['_']; $predicate = $object['_'];
$constructorData = $this->constructors->find_by_predicate($predicate, $layer); $constructorData = $this->constructors->findByPredicate($predicate, $layer);
if ($constructorData === false) { if ($constructorData === false) {
$this->logger->logger($object, \danog\MadelineProto\Logger::FATAL_ERROR); $this->logger->logger($object, \danog\MadelineProto\Logger::FATAL_ERROR);
@ -422,7 +422,7 @@ trait TL
$bare = true; $bare = true;
} }
if ($predicate === 'messageEntityMentionName') { if ($predicate === 'messageEntityMentionName') {
$constructorData = $this->constructors->find_by_predicate('inputMessageEntityMentionName'); $constructorData = $this->constructors->findByPredicate('inputMessageEntityMentionName');
} }
$concat = ''; $concat = '';
@ -430,10 +430,10 @@ trait TL
$concat = $constructorData['id']; $concat = $constructorData['id'];
} }
return $concat.yield $this->serialize_params_async($constructorData, $object, '', $layer); return $concat.yield $this->serializeParams($constructorData, $object, '', $layer);
} }
public function serialize_method_async($method, $arguments) public function serializeMethod($method, $arguments)
{ {
if ($method === 'messages.importChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['hash'], $matches)) { if ($method === 'messages.importChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['hash'], $matches)) {
if ($matches[1] === '') { if ($matches[1] === '') {
@ -466,11 +466,11 @@ trait TL
if ( if (
( (
!\is_array($arguments['file']) || !\is_array($arguments['file']) ||
!(isset($arguments['file']['_']) && $this->constructors->find_by_predicate($arguments['file']['_']) === 'InputEncryptedFile') !(isset($arguments['file']['_']) && $this->constructors->findByPredicate($arguments['file']['_']) === 'InputEncryptedFile')
) && ) &&
$this->settings['upload']['allow_automatic_upload'] $this->settings['upload']['allow_automatic_upload']
) { ) {
$arguments['file'] = yield $this->upload_encrypted_async($arguments['file']); $arguments['file'] = yield $this->uploadEncrypted($arguments['file']);
} }
if (isset($arguments['file']['key'])) { if (isset($arguments['file']['key'])) {
$arguments['message']['media']['key'] = $arguments['file']['key']; $arguments['message']['media']['key'] = $arguments['file']['key'];
@ -480,7 +480,7 @@ trait TL
} }
} }
} elseif (\in_array($method, ['messages.addChatUser', 'messages.deleteChatUser', 'messages.editChatAdmin', 'messages.editChatPhoto', 'messages.editChatTitle', 'messages.getFullChat', 'messages.exportChatInvite', 'messages.editChatAdmin', 'messages.migrateChat']) && isset($arguments['chat_id']) && (!\is_numeric($arguments['chat_id']) || $arguments['chat_id'] < 0)) { } elseif (\in_array($method, ['messages.addChatUser', 'messages.deleteChatUser', 'messages.editChatAdmin', 'messages.editChatPhoto', 'messages.editChatTitle', 'messages.getFullChat', 'messages.exportChatInvite', 'messages.editChatAdmin', 'messages.migrateChat']) && isset($arguments['chat_id']) && (!\is_numeric($arguments['chat_id']) || $arguments['chat_id'] < 0)) {
$res = yield $this->get_info_async($arguments['chat_id']); $res = yield $this->getInfo($arguments['chat_id']);
if ($res['type'] !== 'chat') { if ($res['type'] !== 'chat') {
throw new \danog\MadelineProto\Exception('chat_id is not a chat id (only normal groups allowed, not supergroups)!'); throw new \danog\MadelineProto\Exception('chat_id is not a chat id (only normal groups allowed, not supergroups)!');
} }
@ -505,18 +505,18 @@ trait TL
} }
} }
$tl = $this->methods->find_by_method($method); $tl = $this->methods->findByMethod($method);
if ($tl === false) { if ($tl === false) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['method_not_found'].$method); throw new Exception(\danog\MadelineProto\Lang::$current_lang['method_not_found'].$method);
} }
return $tl['id'].yield $this->serialize_params_async($tl, $arguments, $method); return $tl['id'].yield $this->serializeParams($tl, $arguments, $method);
} }
public function serialize_params_async($tl, $arguments, $ctx, $layer = -1) public function serializeParams($tl, $arguments, $ctx, $layer = -1)
{ {
$serialized = ''; $serialized = '';
$arguments = yield $this->botAPI_to_MTProto_async($arguments); $arguments = yield $this->botAPIToMTProto($arguments);
$flags = 0; $flags = 0;
foreach ($tl['params'] as $cur_flag) { foreach ($tl['params'] as $cur_flag) {
if (isset($cur_flag['pow'])) { if (isset($cur_flag['pow'])) {
@ -546,11 +546,11 @@ trait TL
continue; continue;
} }
if ($current_argument['name'] === 'random_bytes') { if ($current_argument['name'] === 'random_bytes') {
$serialized .= yield $this->serialize_object_async(['type' => 'bytes'], $this->random(15 + 4 * $this->random_int($modulus = 3)), 'random_bytes'); $serialized .= yield $this->serializeObject(['type' => 'bytes'], $this->random(15 + 4 * $this->randomInt($modulus = 3)), 'random_bytes');
continue; continue;
} }
if ($current_argument['name'] === 'data' && isset($tl['method']) && \in_array($tl['method'], ['messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService']) && isset($arguments['message'])) { if ($current_argument['name'] === 'data' && isset($tl['method']) && \in_array($tl['method'], ['messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService']) && isset($arguments['message'])) {
$serialized .= yield $this->serialize_object_async($current_argument, yield $this->encrypt_secret_message_async($arguments['peer']['chat_id'], $arguments['message']), 'data'); $serialized .= yield $this->serializeObject($current_argument, yield $this->encryptSecretMessage($arguments['peer']['chat_id'], $arguments['message']), 'data');
continue; continue;
} }
if ($current_argument['name'] === 'random_id') { if ($current_argument['name'] === 'random_id') {
@ -563,8 +563,8 @@ trait TL
continue 2; continue 2;
case 'Vector t': case 'Vector t':
if (isset($arguments['id'])) { if (isset($arguments['id'])) {
$serialized .= $this->constructors->find_by_predicate('vector')['id']; $serialized .= $this->constructors->findByPredicate('vector')['id'];
$serialized .= $this->pack_unsigned_int(\count($arguments['id'])); $serialized .= $this->packUnsignedInt(\count($arguments['id']));
$serialized .= $this->random(8 * \count($arguments['id'])); $serialized .= $this->random(8 * \count($arguments['id']));
continue 2; continue 2;
} }
@ -575,7 +575,7 @@ trait TL
continue; continue;
} }
if ($tl['type'] === 'InputMedia' && $current_argument['name'] === 'mime_type') { if ($tl['type'] === 'InputMedia' && $current_argument['name'] === 'mime_type') {
$serialized .= yield $this->serialize_object_async($current_argument, $arguments['file']['mime_type'], $current_argument['name'], $layer); $serialized .= yield $this->serializeObject($current_argument, $arguments['file']['mime_type'], $current_argument['name'], $layer);
continue; continue;
} }
if ($tl['type'] === 'DocumentAttribute' && \in_array($current_argument['name'], ['w', 'h', 'duration'])) { if ($tl['type'] === 'DocumentAttribute' && \in_array($current_argument['name'], ['w', 'h', 'duration'])) {
@ -586,11 +586,11 @@ trait TL
$serialized .= \pack('@4'); $serialized .= \pack('@4');
continue; continue;
} }
if (($id = $this->constructors->find_by_predicate(\lcfirst($current_argument['type']).'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) { if (($id = $this->constructors->findByPredicate(\lcfirst($current_argument['type']).'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) {
$serialized .= $id['id']; $serialized .= $id['id'];
continue; continue;
} }
if (($id = $this->constructors->find_by_predicate('input'.$current_argument['type'].'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) { if (($id = $this->constructors->findByPredicate('input'.$current_argument['type'].'Empty', isset($tl['layer']) ? $tl['layer'] : -1)) && $id['type'] === $current_argument['type']) {
$serialized .= $id['id']; $serialized .= $id['id'];
continue; continue;
} }
@ -614,7 +614,7 @@ trait TL
$arguments[$current_argument['name']] = false; $arguments[$current_argument['name']] = false;
break; break;
default: default:
$arguments[$current_argument['name']] = ['_' => $this->constructors->find_by_type($current_argument['type'])['predicate']]; $arguments[$current_argument['name']] = ['_' => $this->constructors->findByType($current_argument['type'])['predicate']];
break;*/ break;*/
} }
} }
@ -633,17 +633,17 @@ trait TL
!\is_array($arguments[$current_argument['name']]) !\is_array($arguments[$current_argument['name']])
|| !( || !(
isset($arguments[$current_argument['name']]['_']) isset($arguments[$current_argument['name']]['_'])
&& $this->constructors->find_by_predicate($arguments[$current_argument['name']]['_']) === 'InputFile' && $this->constructors->findByPredicate($arguments[$current_argument['name']]['_']) === 'InputFile'
) )
) )
&& $this->settings['upload']['allow_automatic_upload'] && $this->settings['upload']['allow_automatic_upload']
) { ) {
$arguments[$current_argument['name']] = yield $this->upload_async($arguments[$current_argument['name']]); $arguments[$current_argument['name']] = yield $this->upload($arguments[$current_argument['name']]);
} }
if ($current_argument['type'] === 'InputEncryptedChat' && (!\is_array($arguments[$current_argument['name']]) || isset($arguments[$current_argument['name']]['_']) && $this->constructors->find_by_predicate($arguments[$current_argument['name']]['_'])['type'] !== $current_argument['type'])) { if ($current_argument['type'] === 'InputEncryptedChat' && (!\is_array($arguments[$current_argument['name']]) || isset($arguments[$current_argument['name']]['_']) && $this->constructors->findByPredicate($arguments[$current_argument['name']]['_'])['type'] !== $current_argument['type'])) {
if (\is_array($arguments[$current_argument['name']])) { if (\is_array($arguments[$current_argument['name']])) {
$arguments[$current_argument['name']] = (yield $this->get_info_async($arguments[$current_argument['name']]))['InputEncryptedChat']; $arguments[$current_argument['name']] = (yield $this->getInfo($arguments[$current_argument['name']]))['InputEncryptedChat'];
} else { } else {
if (!isset($this->secret_chats[$arguments[$current_argument['name']]])) { if (!isset($this->secret_chats[$arguments[$current_argument['name']]])) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['sec_peer_not_in_db']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['sec_peer_not_in_db']);
@ -652,13 +652,13 @@ trait TL
} }
} }
//$this->logger->logger('Serializing '.$current_argument['name'].' of type '.$current_argument['type'); //$this->logger->logger('Serializing '.$current_argument['name'].' of type '.$current_argument['type');
$serialized .= yield $this->serialize_object_async($current_argument, $arguments[$current_argument['name']], $current_argument['name'], $layer); $serialized .= yield $this->serializeObject($current_argument, $arguments[$current_argument['name']], $current_argument['name'], $layer);
} }
return $serialized; return $serialized;
} }
public function get_length($stream, $type = ['type' => '']) public function getLength($stream, $type = ['type' => ''])
{ {
if (\is_string($stream)) { if (\is_string($stream)) {
$res = \fopen('php://memory', 'rw+b'); $res = \fopen('php://memory', 'rw+b');
@ -688,9 +688,9 @@ trait TL
} }
switch ($type['type']) { switch ($type['type']) {
case 'Bool': case 'Bool':
return $this->deserialize_bool(\stream_get_contents($stream, 4)); return $this->deserializeBool(\stream_get_contents($stream, 4));
case 'int': case 'int':
return $this->unpack_signed_int(\stream_get_contents($stream, 4)); return $this->unpackSignedInt(\stream_get_contents($stream, 4));
case '#': case '#':
return \unpack('V', \stream_get_contents($stream, 4))[1]; return \unpack('V', \stream_get_contents($stream, 4))[1];
case 'long': case 'long':
@ -698,9 +698,9 @@ trait TL
return \stream_get_contents($stream, 8); return \stream_get_contents($stream, 8);
} }
return \danog\MadelineProto\Magic::$bigint || isset($type['strlong']) ? \stream_get_contents($stream, 8) : $this->unpack_signed_long(\stream_get_contents($stream, 8)); return \danog\MadelineProto\Magic::$bigint || isset($type['strlong']) ? \stream_get_contents($stream, 8) : $this->unpackSignedLong(\stream_get_contents($stream, 8));
case 'double': case 'double':
return $this->unpack_double(\stream_get_contents($stream, 8)); return $this->unpackDouble(\stream_get_contents($stream, 8));
case 'int128': case 'int128':
return \stream_get_contents($stream, 16); return \stream_get_contents($stream, 16);
case 'int256': case 'int256':
@ -734,9 +734,9 @@ trait TL
return $type['type'] === 'bytes' ? new Types\Bytes($x) : $x; return $type['type'] === 'bytes' ? new Types\Bytes($x) : $x;
case 'Vector t': case 'Vector t':
$id = \stream_get_contents($stream, 4); $id = \stream_get_contents($stream, 4);
$constructorData = $this->constructors->find_by_id($id); $constructorData = $this->constructors->findById($id);
if ($constructorData === false) { if ($constructorData === false) {
$constructorData = $this->methods->find_by_id($id); $constructorData = $this->methods->findById($id);
$constructorData['predicate'] = 'method_'.$constructorData['method']; $constructorData['predicate'] = 'method_'.$constructorData['method'];
} }
if ($constructorData === false) { if ($constructorData === false) {
@ -764,17 +764,17 @@ trait TL
} }
if ($type['type'] != '' && $type['type'][0] === '%') { if ($type['type'] != '' && $type['type'][0] === '%') {
$checkType = \substr($type['type'], 1); $checkType = \substr($type['type'], 1);
$constructorData = $this->constructors->find_by_type($checkType); $constructorData = $this->constructors->findByType($checkType);
if ($constructorData === false) { if ($constructorData === false) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['constructor_not_found'].$checkType); throw new Exception(\danog\MadelineProto\Lang::$current_lang['constructor_not_found'].$checkType);
} }
} else { } else {
$constructorData = $this->constructors->find_by_predicate($type['type']); $constructorData = $this->constructors->findByPredicate($type['type']);
if ($constructorData === false) { if ($constructorData === false) {
$id = \stream_get_contents($stream, 4); $id = \stream_get_contents($stream, 4);
$constructorData = $this->constructors->find_by_id($id); $constructorData = $this->constructors->findById($id);
if ($constructorData === false) { if ($constructorData === false) {
$constructorData = $this->methods->find_by_id($id); $constructorData = $this->methods->findById($id);
if ($constructorData === false) { if ($constructorData === false) {
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['type_extract_error_id'], $type['type'], \bin2hex(\strrev($id)))); throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['type_extract_error_id'], $type['type'], \bin2hex(\strrev($id))));
} }

View File

@ -50,10 +50,10 @@ class TLConstructor
$json_dict['layer'] = ''; $json_dict['layer'] = '';
} }
$this->by_predicate_and_layer[$predicate.$json_dict['layer']] = $json_dict['id']; $this->by_predicate_and_layer[$predicate.$json_dict['layer']] = $json_dict['id'];
$this->parse_params($json_dict['id'], $scheme_type === 'mtproto'); $this->parseParams($json_dict['id'], $scheme_type === 'mtproto');
} }
public function find_by_type($type) public function findByType($type)
{ {
foreach ($this->by_id as $id => $constructor) { foreach ($this->by_id as $id => $constructor) {
if ($constructor['type'] === $type) { if ($constructor['type'] === $type) {
@ -66,7 +66,7 @@ class TLConstructor
return false; return false;
} }
public function find_by_predicate($predicate, $layer = -1) public function findByPredicate($predicate, $layer = -1)
{ {
if ($layer !== -1) { if ($layer !== -1) {
foreach ($this->layers as $alayer) { foreach ($this->layers as $alayer) {
@ -96,7 +96,7 @@ class TLConstructor
return false; return false;
} }
public function find_by_id($id) public function findById($id)
{ {
if (isset($this->by_id[$id])) { if (isset($this->by_id[$id])) {
$constructor = $this->by_id[$id]; $constructor = $this->by_id[$id];

View File

@ -41,10 +41,10 @@ class TLMethod
if (isset($namespace[1])) { if (isset($namespace[1])) {
$this->method_namespace[] = [$namespace[0] => $namespace[1]]; $this->method_namespace[] = [$namespace[0] => $namespace[1]];
} }
$this->parse_params($json_dict['id']); $this->parseParams($json_dict['id']);
} }
public function find_by_id($id) public function findById($id)
{ {
if (isset($this->by_id[$id])) { if (isset($this->by_id[$id])) {
$method = $this->by_id[$id]; $method = $this->by_id[$id];
@ -56,7 +56,7 @@ class TLMethod
return false; return false;
} }
public function find_by_method($method_name) public function findByMethod($method_name)
{ {
if (isset($this->by_method[$method_name])) { if (isset($this->by_method[$method_name])) {
$method = $this->by_id[$this->by_method[$method_name]]; $method = $this->by_id[$this->by_method[$method_name]];

View File

@ -21,7 +21,7 @@ namespace danog\MadelineProto\TL;
trait TLParams trait TLParams
{ {
public function parse_params($key, $mtproto = false) public function parseParams($key, $mtproto = false)
{ {
foreach ($this->by_id[$key]['params'] as $kkey => $param) { foreach ($this->by_id[$key]['params'] as $kkey => $param) {
if (\preg_match('/(\w*)\.(\d*)\?(.*)/', $param['type'], $matches)) { if (\preg_match('/(\w*)\.(\d*)\?(.*)/', $param['type'], $matches)) {

View File

@ -53,7 +53,7 @@ class Button implements \JsonSerializable, \ArrayAccess
case 'keyboardButtonUrl': case 'keyboardButtonUrl':
return $this->data['url']; return $this->data['url'];
case 'keyboardButton': case 'keyboardButton':
$res = $this->info['API']->method_call_async_read('messages.sendMessage', ['peer' => $this->info['peer'], 'message' => $this->data['text'], 'reply_to_msg_id' => $this->info['id']], ['datacenter' => $this->info['API']->datacenter->curdc]); $res = $this->info['API']->methodCallAsyncRead('messages.sendMessage', ['peer' => $this->info['peer'], 'message' => $this->data['text'], 'reply_to_msg_id' => $this->info['id']], ['datacenter' => $this->info['API']->datacenter->curdc]);
break; break;
case 'keyboardButtonCallback': case 'keyboardButtonCallback':
$res = $this->info['API']->$method('messages.getBotCallbackAnswer', ['peer' => $this->info['peer'], 'msg_id' => $this->info['id'], 'data' => $this->data['data']], ['datacenter' => $this->info['API']->datacenter->curdc]); $res = $this->info['API']->$method('messages.getBotCallbackAnswer', ['peer' => $this->info['peer'], 'msg_id' => $this->info['id'], 'data' => $this->data['data']], ['datacenter' => $this->info['API']->datacenter->curdc]);

View File

@ -42,7 +42,7 @@ use function Amp\Promise\wait;
*/ */
trait Tools trait Tools
{ {
public static function gen_vector_hash($ints) public static function genVectorHash($ints)
{ {
//sort($ints, SORT_NUMERIC); //sort($ints, SORT_NUMERIC);
if (\danog\MadelineProto\Magic::$bigint) { if (\danog\MadelineProto\Magic::$bigint) {
@ -50,7 +50,7 @@ trait Tools
foreach ($ints as $int) { foreach ($ints as $int) {
$hash = $hash->multiply(\danog\MadelineProto\Magic::$twozerotwosixone)->add(\danog\MadelineProto\Magic::$zeroeight)->add(new \phpseclib\Math\BigInteger($int))->divide(\danog\MadelineProto\Magic::$zeroeight)[1]; $hash = $hash->multiply(\danog\MadelineProto\Magic::$twozerotwosixone)->add(\danog\MadelineProto\Magic::$zeroeight)->add(new \phpseclib\Math\BigInteger($int))->divide(\danog\MadelineProto\Magic::$zeroeight)[1];
} }
$hash = self::unpack_signed_int(\strrev(\str_pad($hash->toBytes(), 4, "\0", STR_PAD_LEFT))); $hash = self::unpackSignedInt(\strrev(\str_pad($hash->toBytes(), 4, "\0", STR_PAD_LEFT)));
} else { } else {
$hash = 0; $hash = 0;
foreach ($ints as $int) { foreach ($ints as $int) {
@ -61,7 +61,7 @@ trait Tools
return $hash; return $hash;
} }
public static function random_int($modulus = false) public static function randomInt($modulus = false)
{ {
if ($modulus === false) { if ($modulus === false) {
$modulus = PHP_INT_MAX; $modulus = PHP_INT_MAX;
@ -81,9 +81,9 @@ trait Tools
} }
if (Magic::$bigint) { if (Magic::$bigint) {
$number = self::unpack_signed_int(self::random(4)); $number = self::unpackSignedInt(self::random(4));
} else { } else {
$number = self::unpack_signed_long(self::random(8)); $number = self::unpackSignedLong(self::random(8));
} }
return ($number & PHP_INT_MAX) % $modulus; return ($number & PHP_INT_MAX) % $modulus;
@ -105,7 +105,7 @@ trait Tools
return $resto < 0 ? $resto + \abs($b) : $resto; return $resto < 0 ? $resto + \abs($b) : $resto;
} }
public static function unpack_signed_int($value) public static function unpackSignedInt($value)
{ {
if (\strlen($value) !== 4) { if (\strlen($value) !== 4) {
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_4']); throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_4']);
@ -114,7 +114,7 @@ trait Tools
return \unpack('l', \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($value) : $value)[1]; return \unpack('l', \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($value) : $value)[1];
} }
public static function unpack_signed_long($value) public static function unpackSignedLong($value)
{ {
if (\strlen($value) !== 8) { if (\strlen($value) !== 8) {
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_8']); throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_8']);
@ -123,7 +123,7 @@ trait Tools
return \unpack('q', \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($value) : $value)[1]; return \unpack('q', \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($value) : $value)[1];
} }
public static function unpack_signed_long_string($value) public static function unpackSignedLongString($value)
{ {
if (\is_int($value)) { if (\is_int($value)) {
return (string) $value; return (string) $value;
@ -136,7 +136,7 @@ trait Tools
return (string) $big; return (string) $big;
} }
public static function pack_signed_int($value) public static function packSignedInt($value)
{ {
if ($value > 2147483647) { if ($value > 2147483647) {
throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_bigger_than_2147483647'], $value)); throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_bigger_than_2147483647'], $value));
@ -149,7 +149,7 @@ trait Tools
return \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($res) : $res; return \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($res) : $res;
} }
public static function pack_signed_long($value) public static function packSignedLong($value)
{ {
if ($value > 9223372036854775807) { if ($value > 9223372036854775807) {
throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_bigger_than_9223372036854775807'], $value)); throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_bigger_than_9223372036854775807'], $value));
@ -157,12 +157,12 @@ trait Tools
if ($value < -9.223372036854776E+18) { if ($value < -9.223372036854776E+18) {
throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_smaller_than_9223372036854775808'], $value)); throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_smaller_than_9223372036854775808'], $value));
} }
$res = \danog\MadelineProto\Magic::$bigint ? self::pack_signed_int($value)."\0\0\0\0" : (\danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev(\pack('q', $value)) : \pack('q', $value)); $res = \danog\MadelineProto\Magic::$bigint ? self::packSignedInt($value)."\0\0\0\0" : (\danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev(\pack('q', $value)) : \pack('q', $value));
return $res; return $res;
} }
public static function pack_unsigned_int($value) public static function packUnsignedInt($value)
{ {
if ($value > 4294967295) { if ($value > 4294967295) {
throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_bigger_than_4294967296'], $value)); throw new TL\Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['value_bigger_than_4294967296'], $value));
@ -174,7 +174,7 @@ trait Tools
return \pack('V', $value); return \pack('V', $value);
} }
public static function pack_double($value) public static function packDouble($value)
{ {
$res = \pack('d', $value); $res = \pack('d', $value);
if (\strlen($res) !== 8) { if (\strlen($res) !== 8) {
@ -184,7 +184,7 @@ trait Tools
return \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($res) : $res; return \danog\MadelineProto\Magic::$BIG_ENDIAN ? \strrev($res) : $res;
} }
public static function unpack_double($value) public static function unpackDouble($value)
{ {
if (\strlen($value) !== 8) { if (\strlen($value) !== 8) {
throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_8']); throw new TL\Exception(\danog\MadelineProto\Lang::$current_lang['length_not_8']);
@ -441,7 +441,7 @@ trait Tools
{ {
return getOutputBufferStream()->write($string); return getOutputBufferStream()->write($string);
} }
public static function is_array_or_alike($var) public static function isArrayOrAlike($var)
{ {
return \is_array($var) || return \is_array($var) ||
($var instanceof ArrayAccess && ($var instanceof ArrayAccess &&
@ -456,7 +456,7 @@ trait Tools
* *
* @return string * @return string
*/ */
public static function from_snake_case(string $input): string public static function fromSnakeCase(string $input): string
{ {
return \lcfirst(\str_replace('_', '', \ucwords($input, '_'))); return \lcfirst(\str_replace('_', '', \ucwords($input, '_')));
} }
@ -467,7 +467,7 @@ trait Tools
* *
* @return string * @return string
*/ */
public static function from_camel_case(string $input): string public static function fromCamelCase(string $input): string
{ {
\preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches); \preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0]; $ret = $matches[0];

View File

@ -29,41 +29,41 @@ trait AuthKeyHandler
{ {
private $calls = []; private $calls = [];
public function request_call($user) public function requestCall($user)
{ {
return $this->wait($this->request_call_async($user)); return $this->wait($this->requestCallAsync($user));
} }
public function accept_call($user) public function acceptCall($user)
{ {
return $this->wait($this->accept_call_async($user)); return $this->wait($this->acceptCallAsync($user));
} }
public function discard_call($call, $reason, $rating = [], $need_debug = true) public function discardCall($call, $reason, $rating = [], $need_debug = true)
{ {
return $this->wait($this->discard_call_async($call, $reason, $rating, $need_debug)); return $this->wait($this->discardCallAsync($call, $reason, $rating, $need_debug));
} }
public function request_call_async($user) public function requestCallAsync($user)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip'); throw \danog\MadelineProto\Exception::extension('libtgvoip');
} }
$user = yield $this->get_info_async($user); $user = yield $this->getInfo($user);
if (!isset($user['InputUser']) || $user['InputUser']['_'] === 'inputUserSelf') { if (!isset($user['InputUser']) || $user['InputUser']['_'] === 'inputUserSelf') {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['peer_not_in_db']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['peer_not_in_db']);
} }
$user = $user['InputUser']; $user = $user['InputUser'];
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['calling_user'], $user['user_id']), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['calling_user'], $user['user_id']), \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_a'], \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_a'], \danog\MadelineProto\Logger::VERBOSE);
$a = \phpseclib\Math\BigInteger::randomRange(\danog\MadelineProto\Magic::$two, $dh_config['p']->subtract(\danog\MadelineProto\Magic::$two)); $a = \phpseclib\Math\BigInteger::randomRange(\danog\MadelineProto\Magic::$two, $dh_config['p']->subtract(\danog\MadelineProto\Magic::$two));
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_g_a'], \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_g_a'], \danog\MadelineProto\Logger::VERBOSE);
$g_a = $dh_config['g']->powMod($a, $dh_config['p']); $g_a = $dh_config['g']->powMod($a, $dh_config['p']);
$this->check_G($g_a, $dh_config['p']); $this->checkG($g_a, $dh_config['p']);
$controller = new \danog\MadelineProto\VoIP(true, $user['user_id'], $this, \danog\MadelineProto\VoIP::CALL_STATE_REQUESTED); $controller = new \danog\MadelineProto\VoIP(true, $user['user_id'], $this, \danog\MadelineProto\VoIP::CALL_STATE_REQUESTED);
$controller->storage = ['a' => $a, 'g_a' => \str_pad($g_a->toBytes(), 256, \chr(0), \STR_PAD_LEFT)]; $controller->storage = ['a' => $a, 'g_a' => \str_pad($g_a->toBytes(), 256, \chr(0), \STR_PAD_LEFT)];
$res = yield $this->method_call_async_read('phone.requestCall', ['user_id' => $user, 'g_a_hash' => \hash('sha256', $g_a->toBytes(), true), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_p2p' => true, 'udp_reflector' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]); $res = yield $this->methodCallAsyncRead('phone.requestCall', ['user_id' => $user, 'g_a_hash' => \hash('sha256', $g_a->toBytes(), true), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_p2p' => true, 'udp_reflector' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]);
$controller->setCall($res['phone_call']); $controller->setCall($res['phone_call']);
$this->calls[$res['phone_call']['id']] = $controller; $this->calls[$res['phone_call']['id']] = $controller;
yield $this->updaters[false]->resume(); yield $this->updaters[false]->resume();
@ -71,25 +71,25 @@ trait AuthKeyHandler
return $controller; return $controller;
} }
public function accept_call_async($call) public function acceptCallAsync($call)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw new \danog\MadelineProto\Exception(); throw new \danog\MadelineProto\Exception();
} }
if ($this->call_status($call['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED) { if ($this->callStatus($call['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_1'], $call['id'])); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_1'], $call['id']));
return false; return false;
} }
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['accepting_call'], $this->calls[$call['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['accepting_call'], $this->calls[$call['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_b'], \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_b'], \danog\MadelineProto\Logger::VERBOSE);
$b = \phpseclib\Math\BigInteger::randomRange(\danog\MadelineProto\Magic::$two, $dh_config['p']->subtract(\danog\MadelineProto\Magic::$two)); $b = \phpseclib\Math\BigInteger::randomRange(\danog\MadelineProto\Magic::$two, $dh_config['p']->subtract(\danog\MadelineProto\Magic::$two));
$g_b = $dh_config['g']->powMod($b, $dh_config['p']); $g_b = $dh_config['g']->powMod($b, $dh_config['p']);
$this->check_G($g_b, $dh_config['p']); $this->checkG($g_b, $dh_config['p']);
try { try {
$res = yield $this->method_call_async_read('phone.acceptCall', ['peer' => $call, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]); $res = yield $this->methodCallAsyncRead('phone.acceptCall', ['peer' => $call, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'CALL_ALREADY_ACCEPTED') { if ($e->rpc === 'CALL_ALREADY_ACCEPTED') {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id'])); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id']));
@ -98,7 +98,7 @@ trait AuthKeyHandler
} }
if ($e->rpc === 'CALL_ALREADY_DECLINED') { if ($e->rpc === 'CALL_ALREADY_DECLINED') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['call_already_declined']); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['call_already_declined']);
yield $this->discard_call_async($call['id'], 'phoneCallDiscardReasonHangup'); yield $this->discardCallAsync($call['id'], 'phoneCallDiscardReasonHangup');
return false; return false;
} }
@ -111,23 +111,23 @@ trait AuthKeyHandler
return true; return true;
} }
public function confirm_call_async($params) public function confirmCall($params)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip'); throw \danog\MadelineProto\Exception::extension('libtgvoip');
} }
if ($this->call_status($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_REQUESTED) { if ($this->callStatus($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_REQUESTED) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_2'], $params['id'])); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_2'], $params['id']));
return false; return false;
} }
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_confirming'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_confirming'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
$params['g_b'] = new \phpseclib\Math\BigInteger((string) $params['g_b'], 256); $params['g_b'] = new \phpseclib\Math\BigInteger((string) $params['g_b'], 256);
$this->check_G($params['g_b'], $dh_config['p']); $this->checkG($params['g_b'], $dh_config['p']);
$key = \str_pad($params['g_b']->powMod($this->calls[$params['id']]->storage['a'], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $key = \str_pad($params['g_b']->powMod($this->calls[$params['id']]->storage['a'], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
try { try {
$res = (yield $this->method_call_async_read('phone.confirmCall', ['key_fingerprint' => \substr(\sha1($key, true), -8), 'peer' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'g_a' => $this->calls[$params['id']]->storage['g_a'], 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]))['phone_call']; $res = (yield $this->methodCallAsyncRead('phone.confirmCall', ['key_fingerprint' => \substr(\sha1($key, true), -8), 'peer' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'g_a' => $this->calls[$params['id']]->storage['g_a'], 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => 65, 'max_layer' => \danog\MadelineProto\VoIP::getConnectionMaxLayer()]], ['datacenter' => $this->datacenter->curdc]))['phone_call'];
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'CALL_ALREADY_ACCEPTED') { if ($e->rpc === 'CALL_ALREADY_ACCEPTED') {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id'])); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id']));
@ -136,7 +136,7 @@ trait AuthKeyHandler
} }
if ($e->rpc === 'CALL_ALREADY_DECLINED') { if ($e->rpc === 'CALL_ALREADY_DECLINED') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['call_already_declined']); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['call_already_declined']);
yield $this->discard_call_async($call['id'], 'phoneCallDiscardReasonHangup'); yield $this->discardCallAsync($call['id'], 'phoneCallDiscardReasonHangup');
return false; return false;
} }
@ -160,23 +160,23 @@ trait AuthKeyHandler
return $res; return $res;
} }
public function complete_call_async($params) public function completeCall($params)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip'); throw \danog\MadelineProto\Exception::extension('libtgvoip');
} }
if ($this->call_status($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED || !isset($this->calls[$params['id']]->storage['b'])) { if ($this->callStatus($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED || !isset($this->calls[$params['id']]->storage['b'])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_3'], $params['id'])); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_error_3'], $params['id']));
return false; return false;
} }
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_completing'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_completing'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE);
$dh_config = yield $this->get_dh_config_async(); $dh_config = yield $this->getDhConfig();
if (\hash('sha256', $params['g_a_or_b'], true) != $this->calls[$params['id']]->storage['g_a_hash']) { if (\hash('sha256', $params['g_a_or_b'], true) != $this->calls[$params['id']]->storage['g_a_hash']) {
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['invalid_g_a']); throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['invalid_g_a']);
} }
$params['g_a_or_b'] = new \phpseclib\Math\BigInteger((string) $params['g_a_or_b'], 256); $params['g_a_or_b'] = new \phpseclib\Math\BigInteger((string) $params['g_a_or_b'], 256);
$this->check_G($params['g_a_or_b'], $dh_config['p']); $this->checkG($params['g_a_or_b'], $dh_config['p']);
$key = \str_pad($params['g_a_or_b']->powMod($this->calls[$params['id']]->storage['b'], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT); $key = \str_pad($params['g_a_or_b']->powMod($this->calls[$params['id']]->storage['b'], $dh_config['p'])->toBytes(), 256, \chr(0), \STR_PAD_LEFT);
if (\substr(\sha1($key, true), -8) != $params['key_fingerprint']) { if (\substr(\sha1($key, true), -8) != $params['key_fingerprint']) {
throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_invalid']); throw new \danog\MadelineProto\SecurityException(\danog\MadelineProto\Lang::$current_lang['fingerprint_invalid']);
@ -195,7 +195,7 @@ trait AuthKeyHandler
return $this->calls[$params['id']]->startTheMagic(); return $this->calls[$params['id']]->startTheMagic();
} }
public function call_status($id) public function callStatus($id)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip'); throw \danog\MadelineProto\Exception::extension('libtgvoip');
@ -207,7 +207,7 @@ trait AuthKeyHandler
return \danog\MadelineProto\VoIP::CALL_STATE_NONE; return \danog\MadelineProto\VoIP::CALL_STATE_NONE;
} }
public function get_call($call) public function getCall($call)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip'); throw \danog\MadelineProto\Exception::extension('libtgvoip');
@ -216,7 +216,7 @@ trait AuthKeyHandler
return $this->calls[$call]; return $this->calls[$call];
} }
public function discard_call_async($call, $reason, $rating = [], $need_debug = true) public function discardCallAsync($call, $reason, $rating = [], $need_debug = true)
{ {
if (!\class_exists('\\danog\\MadelineProto\\VoIP')) { if (!\class_exists('\\danog\\MadelineProto\\VoIP')) {
throw \danog\MadelineProto\Exception::extension('libtgvoip'); throw \danog\MadelineProto\Exception::extension('libtgvoip');
@ -227,7 +227,7 @@ trait AuthKeyHandler
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_discarding'], $call['id']), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_discarding'], $call['id']), \danog\MadelineProto\Logger::VERBOSE);
try { try {
$res = yield $this->method_call_async_read('phone.discardCall', ['peer' => $call, 'duration' => \time() - $this->calls[$call['id']]->whenCreated(), 'connection_id' => $this->calls[$call['id']]->getPreferredRelayID(), 'reason' => $reason], ['datacenter' => $this->datacenter->curdc]); $res = yield $this->methodCallAsyncRead('phone.discardCall', ['peer' => $call, 'duration' => \time() - $this->calls[$call['id']]->whenCreated(), 'connection_id' => $this->calls[$call['id']]->getPreferredRelayID(), 'reason' => $reason], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if (!\in_array($e->rpc, ['CALL_ALREADY_DECLINED', 'CALL_ALREADY_ACCEPTED'])) { if (!\in_array($e->rpc, ['CALL_ALREADY_DECLINED', 'CALL_ALREADY_ACCEPTED'])) {
throw $e; throw $e;
@ -235,17 +235,17 @@ trait AuthKeyHandler
} }
if (!empty($rating)) { if (!empty($rating)) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_set_rating'], $call['id']), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_set_rating'], $call['id']), \danog\MadelineProto\Logger::VERBOSE);
yield $this->method_call_async_read('phone.setCallRating', ['peer' => $call, 'rating' => $rating['rating'], 'comment' => $rating['comment']], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('phone.setCallRating', ['peer' => $call, 'rating' => $rating['rating'], 'comment' => $rating['comment']], ['datacenter' => $this->datacenter->curdc]);
} }
if ($need_debug && isset($this->calls[$call['id']])) { if ($need_debug && isset($this->calls[$call['id']])) {
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_debug_saving'], $call['id']), \danog\MadelineProto\Logger::VERBOSE); $this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['call_debug_saving'], $call['id']), \danog\MadelineProto\Logger::VERBOSE);
yield $this->method_call_async_read('phone.saveCallDebug', ['peer' => $call, 'debug' => $this->calls[$call['id']]->getDebugLog()], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('phone.saveCallDebug', ['peer' => $call, 'debug' => $this->calls[$call['id']]->getDebugLog()], ['datacenter' => $this->datacenter->curdc]);
} }
$update = ['_' => 'updatePhoneCall', 'phone_call' => $this->calls[$call['id']]]; $update = ['_' => 'updatePhoneCall', 'phone_call' => $this->calls[$call['id']]];
if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict']) { if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict']) {
$this->pwr_update_handler($update); $this->pwrUpdateHandler($update);
} else { } else {
\in_array($this->settings['updates']['callback'], [['danog\\MadelineProto\\API', 'get_updates_update_handler'], 'get_updates_update_handler']) ? $this->get_updates_update_handler($update) : $this->settings['updates']['callback']($update); \in_array($this->settings['updates']['callback'], [['danog\\MadelineProto\\API', 'get_updates_update_handler'], 'get_updates_update_handler']) ? $this->getUpdatesUpdateHandler($update) : $this->settings['updates']['callback']($update);
} }
unset($this->calls[$call['id']]); unset($this->calls[$call['id']]);
} }

View File

@ -28,7 +28,7 @@ use function Amp\ByteStream\getStdout;
*/ */
trait ApiStart trait ApiStart
{ {
public function api_start_async($settings) public function APIStart($settings)
{ {
if (PHP_SAPI === 'cli') { if (PHP_SAPI === 'cli') {
$stdout = getStdout(); $stdout = getStdout();
@ -49,16 +49,16 @@ Note that you can also provide the API parameters directly in the code using the
return $app; return $app;
} }
$this->my_telegram_org_wrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings); $this->my_telegram_org_wrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings);
yield $this->my_telegram_org_wrapper->login_async(yield Tools::readLine('Enter a phone number that is already registered on Telegram: ')); yield $this->my_telegram_org_wrapper->login(yield Tools::readLine('Enter a phone number that is already registered on Telegram: '));
yield $this->my_telegram_org_wrapper->complete_login_async(yield Tools::readLine('Enter the verification code you received in telegram: ')); yield $this->my_telegram_org_wrapper->completeLogin(yield Tools::readLine('Enter the verification code you received in telegram: '));
if (!yield $this->my_telegram_org_wrapper->has_app_async()) { if (!yield $this->my_telegram_org_wrapper->hasApp()) {
$app_title = yield Tools::readLine('Enter the app\'s name, can be anything: '); $app_title = yield Tools::readLine('Enter the app\'s name, can be anything: ');
$short_name = yield Tools::readLine('Enter the app\'s short name, can be anything: '); $short_name = yield Tools::readLine('Enter the app\'s short name, can be anything: ');
$url = yield Tools::readLine('Enter the app/website\'s URL, or t.me/yourusername: '); $url = yield Tools::readLine('Enter the app/website\'s URL, or t.me/yourusername: ');
$description = yield Tools::readLine('Describe your app: '); $description = yield Tools::readLine('Describe your app: ');
$app = yield $this->my_telegram_org_wrapper->create_app_async(['app_title' => $app_title, 'app_shortname' => $short_name, 'app_url' => $url, 'app_platform' => 'web', 'app_desc' => $description]); $app = yield $this->my_telegram_org_wrapper->createApp(['app_title' => $app_title, 'app_shortname' => $short_name, 'app_url' => $url, 'app_platform' => 'web', 'app_desc' => $description]);
} else { } else {
$app = yield $this->my_telegram_org_wrapper->get_app_async(); $app = yield $this->my_telegram_org_wrapper->getApp();
} }
return $app; return $app;
@ -72,17 +72,17 @@ Note that you can also provide the API parameters directly in the code using the
return $app; return $app;
} elseif (isset($_POST['phone_number'])) { } elseif (isset($_POST['phone_number'])) {
yield $this->web_api_phone_login_async($settings); yield $this->webAPIPhoneLogin($settings);
} else { } else {
yield $this->web_api_echo_async(); yield $this->webAPIEcho();
} }
} elseif (!$this->my_telegram_org_wrapper->logged_in()) { } elseif (!$this->my_telegram_org_wrapper->logged_in()) {
if (isset($_POST['code'])) { if (isset($_POST['code'])) {
yield $this->web_api_complete_login_async(); yield $this->webAPICompleteLogin();
if (yield $this->my_telegram_org_wrapper->has_app_async()) { if (yield $this->my_telegram_org_wrapper->hasApp()) {
return yield $this->my_telegram_org_wrapper->get_app_async(); return yield $this->my_telegram_org_wrapper->getApp();
} }
yield $this->web_api_echo_async(); yield $this->webAPIEcho();
} elseif (isset($_POST['api_id']) && isset($_POST['api_hash'])) { } elseif (isset($_POST['api_id']) && isset($_POST['api_hash'])) {
$app['api_id'] = (int) $_POST['api_id']; $app['api_id'] = (int) $_POST['api_id'];
$app['api_hash'] = $_POST['api_hash']; $app['api_hash'] = $_POST['api_hash'];
@ -90,58 +90,58 @@ Note that you can also provide the API parameters directly in the code using the
return $app; return $app;
} elseif (isset($_POST['phone_number'])) { } elseif (isset($_POST['phone_number'])) {
yield $this->web_api_phone_login_async($settings); yield $this->webAPIPhoneLogin($settings);
} else { } else {
$this->my_telegram_org_wrapper = null; $this->my_telegram_org_wrapper = null;
yield $this->web_api_echo_async(); yield $this->webAPIEcho();
} }
} else { } else {
if (isset($_POST['app_title'], $_POST['app_shortname'], $_POST['app_url'], $_POST['app_platform'], $_POST['app_desc'])) { if (isset($_POST['app_title'], $_POST['app_shortname'], $_POST['app_url'], $_POST['app_platform'], $_POST['app_desc'])) {
$app = yield $this->web_api_create_app_async(); $app = yield $this->webAPICreateApp();
$this->getting_api_id = false; $this->getting_api_id = false;
return $app; return $app;
} }
yield $this->web_api_echo_async("You didn't provide all of the required parameters!"); yield $this->webAPIEcho("You didn't provide all of the required parameters!");
} }
$this->asyncInitPromise = null; $this->asyncInitPromise = null;
exit; exit;
} }
public function web_api_phone_login_async($settings) public function webAPIPhoneLogin($settings)
{ {
try { try {
$this->my_telegram_org_wrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings); $this->my_telegram_org_wrapper = new \danog\MadelineProto\MyTelegramOrgWrapper($settings);
yield $this->my_telegram_org_wrapper->login_async($_POST['phone_number']); yield $this->my_telegram_org_wrapper->login($_POST['phone_number']);
yield $this->web_api_echo_async(); yield $this->webAPIEcho();
} catch (\Throwable $e) { } catch (\Throwable $e) {
yield $this->web_api_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
public function web_api_complete_login_async() public function webAPICompleteLogin()
{ {
try { try {
yield $this->my_telegram_org_wrapper->complete_login_async($_POST['code']); yield $this->my_telegram_org_wrapper->completeLogin($_POST['code']);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_api_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_api_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webAPIEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
public function web_api_create_app_async() public function webAPICreateApp()
{ {
try { try {
$params = $_POST; $params = $_POST;
unset($params['creating_app']); unset($params['creating_app']);
$app = yield $this->my_telegram_org_wrapper->create_app_async($params); $app = yield $this->my_telegram_org_wrapper->createApp($params);
return $app; return $app;
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_api_echo_async('ERROR: '.$e->getMessage().' Try again.'); yield $this->webAPIEcho('ERROR: '.$e->getMessage().' Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_api_echo_async('ERROR: '.$e->getMessage().' Try again.'); yield $this->webAPIEcho('ERROR: '.$e->getMessage().' Try again.');
} }
} }
} }

View File

@ -38,28 +38,28 @@ trait ApiTemplates
</body> </body>
</html>'; </html>';
public function web_api_echo_template($message, $form) public function webAPIEchoTemplate($message, $form)
{ {
return \sprintf($this->web_api_template, $message, $form); return \sprintf($this->web_api_template, $message, $form);
} }
public function get_web_api_template() public function getWebAPITemplate()
{ {
return $this->web_template; return $this->web_template;
} }
public function set_web_api_template($template) public function setWebAPITemplate($template)
{ {
$this->web_template = $template; $this->web_template = $template;
} }
public function web_api_echo_async($message = '') public function webAPIEcho($message = '')
{ {
$stdout = getOutputBufferStream(); $stdout = getOutputBufferStream();
if (!isset($this->my_telegram_org_wrapper)) { if (!isset($this->my_telegram_org_wrapper)) {
if (isset($_POST['type'])) { if (isset($_POST['type'])) {
if ($_POST['type'] === 'manual') { if ($_POST['type'] === 'manual') {
yield $stdout->write($this->web_api_echo_template('Enter your API ID and API hash<br><b>'.$message.'</b><ol> yield $stdout->write($this->webAPIEchoTemplate('Enter your API ID and API hash<br><b>'.$message.'</b><ol>
<li>Login to my.telegram.org</li> <li>Login to my.telegram.org</li>
<li>Go to API development tools</li> <li>Go to API development tools</li>
<li> <li>
@ -73,19 +73,19 @@ trait ApiTemplates
<li>Click on create application</li> <li>Click on create application</li>
</ol>', '<input type="string" name="api_id" placeholder="API ID" required/><input type="string" name="api_hash" placeholder="API hash" required/>')); </ol>', '<input type="string" name="api_id" placeholder="API ID" required/><input type="string" name="api_hash" placeholder="API hash" required/>'));
} else { } else {
yield $stdout->write($this->web_api_echo_template('Enter a phone number that is <b>already registered</b> on telegram to get the API ID<br><b>'.$message.'</b>', '<input type="text" name="phone_number" placeholder="Phone number" required/>')); yield $stdout->write($this->webAPIEchoTemplate('Enter a phone number that is <b>already registered</b> on telegram to get the API ID<br><b>'.$message.'</b>', '<input type="text" name="phone_number" placeholder="Phone number" required/>'));
} }
} else { } else {
if ($message) { if ($message) {
$message = '<br><br>'.$message; $message = '<br><br>'.$message;
} }
yield $stdout->write($this->web_api_echo_template('Do you want to enter the API id and the API hash manually or automatically?<br>Note that you can also provide it directly in the code using the <a href="https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id">settings</a>.<b>'.$message.'</b>', '<select name="type"><option value="automatic">Automatically</option><option value="manual">Manually</option></select>')); yield $stdout->write($this->webAPIEchoTemplate('Do you want to enter the API id and the API hash manually or automatically?<br>Note that you can also provide it directly in the code using the <a href="https://docs.madelineproto.xyz/docs/SETTINGS.html#settingsapp_infoapi_id">settings</a>.<b>'.$message.'</b>', '<select name="type"><option value="automatic">Automatically</option><option value="manual">Manually</option></select>'));
} }
} else { } else {
if (!$this->my_telegram_org_wrapper->logged_in()) { if (!$this->my_telegram_org_wrapper->logged_in()) {
yield $stdout->write($this->web_api_echo_template('Enter your code<br><b>'.$message.'</b>', '<input type="text" name="code" placeholder="Code" required/>')); yield $stdout->write($this->webAPIEchoTemplate('Enter your code<br><b>'.$message.'</b>', '<input type="text" name="code" placeholder="Code" required/>'));
} else { } else {
yield $stdout->write($this->web_api_echo_template( yield $stdout->write($this->webAPIEchoTemplate(
'Enter the API info<br><b>'.$message.'</b>', 'Enter the API info<br><b>'.$message.'</b>',
'<input type="hidden" name="creating_app" value="yes" required/> '<input type="hidden" name="creating_app" value="yes" required/>
Enter the app name, can be anything: <br><input type="text" name="app_title" required/><br> Enter the app name, can be anything: <br><input type="text" name="app_title" required/><br>

View File

@ -21,25 +21,25 @@ namespace danog\MadelineProto\Wrappers;
trait DialogHandler trait DialogHandler
{ {
public function get_dialogs_async($force = true) public function getDialogs($force = true)
{ {
if ($this->authorization['user']['bot']) { if ($this->authorization['user']['bot']) {
$res = []; $res = [];
foreach ($this->chats as $chat) { foreach ($this->chats as $chat) {
$res[] = $this->gen_all($chat)['Peer']; $res[] = $this->genAll($chat)['Peer'];
} }
return $res; return $res;
} }
$res = []; $res = [];
foreach (yield $this->get_full_dialogs_async($force) as $dialog) { foreach (yield $this->getFullDialogs($force) as $dialog) {
$res[] = $dialog['peer']; $res[] = $dialog['peer'];
} }
return $res; return $res;
} }
public function get_full_dialogs_async($force = true) public function getFullDialogs($force = true)
{ {
if ($force || !isset($this->dialog_params['offset_date']) || \is_null($this->dialog_params['offset_date']) || !isset($this->dialog_params['offset_id']) || \is_null($this->dialog_params['offset_id']) || !isset($this->dialog_params['offset_peer']) || \is_null($this->dialog_params['offset_peer']) || !isset($this->dialog_params['count']) || \is_null($this->dialog_params['count'])) { if ($force || !isset($this->dialog_params['offset_date']) || \is_null($this->dialog_params['offset_date']) || !isset($this->dialog_params['offset_id']) || \is_null($this->dialog_params['offset_id']) || !isset($this->dialog_params['offset_peer']) || \is_null($this->dialog_params['offset_peer']) || !isset($this->dialog_params['count']) || \is_null($this->dialog_params['count'])) {
$this->dialog_params = ['limit' => 100, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty'], 'count' => 0, 'hash' => 0]; $this->dialog_params = ['limit' => 100, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty'], 'count' => 0, 'hash' => 0];
@ -53,13 +53,13 @@ trait DialogHandler
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getting_dialogs']); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getting_dialogs']);
while ($this->dialog_params['count'] < $res['count']) { while ($this->dialog_params['count'] < $res['count']) {
$res = yield $this->method_call_async_read('messages.getDialogs', $this->dialog_params, ['datacenter' => $datacenter, 'FloodWaitLimit' => 100]); $res = yield $this->methodCallAsyncRead('messages.getDialogs', $this->dialog_params, ['datacenter' => $datacenter, 'FloodWaitLimit' => 100]);
$last_peer = 0; $last_peer = 0;
$last_date = 0; $last_date = 0;
$last_id = 0; $last_id = 0;
$res['messages'] = \array_reverse($res['messages'] ?? []); $res['messages'] = \array_reverse($res['messages'] ?? []);
foreach (\array_reverse($res['dialogs'] ?? []) as $dialog) { foreach (\array_reverse($res['dialogs'] ?? []) as $dialog) {
$id = $this->get_id($dialog['peer']); $id = $this->getId($dialog['peer']);
if (!isset($dialogs[$id])) { if (!isset($dialogs[$id])) {
$dialogs[$id] = $dialog; $dialogs[$id] = $dialog;
} }
@ -71,7 +71,7 @@ trait DialogHandler
$last_id = $dialog['top_message']; $last_id = $dialog['top_message'];
} }
foreach ($res['messages'] as $message) { foreach ($res['messages'] as $message) {
if ($this->get_id($message) === $last_peer && $last_id === $message['id']) { if ($this->getId($message) === $last_peer && $last_id === $message['id']) {
$last_date = $message['date']; $last_date = $message['date'];
break; break;
} }

View File

@ -71,7 +71,7 @@ trait Events
return $this->event_handler_instance; return $this->event_handler_instance;
} }
public function event_update_handler($update) public function eventUpdateHandler($update)
{ {
if (isset($this->event_handler_methods[$update['_']])) { if (isset($this->event_handler_methods[$update['_']])) {
return $this->event_handler_methods[$update['_']]($update); return $this->event_handler_methods[$update['_']]($update);

View File

@ -27,9 +27,9 @@ use danog\MadelineProto\MTProtoTools\PasswordCalculator;
*/ */
trait Login trait Login
{ {
public function logout_async() public function logout()
{ {
yield $this->method_call_async_read('auth.logOut', [], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('auth.logOut', [], ['datacenter' => $this->datacenter->curdc]);
$this->resetSession(); $this->resetSession();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['logout_ok'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['logout_ok'], \danog\MadelineProto\Logger::NOTICE);
$this->startUpdateSystem(); $this->startUpdateSystem();
@ -37,23 +37,23 @@ trait Login
return true; return true;
} }
public function bot_login_async($token) public function botLogin($token)
{ {
if ($this->authorized === self::LOGGED_IN) { if ($this->authorized === self::LOGGED_IN) {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['already_logged_in'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['already_logged_in'], \danog\MadelineProto\Logger::NOTICE);
yield $this->logout_async(); yield $this->logout();
} }
$callbacks = [$this, $this->referenceDatabase]; $callbacks = [$this, $this->referenceDatabase];
$this->update_callbacks($callbacks); $this->updateCallbacks($callbacks);
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_bot'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_bot'], \danog\MadelineProto\Logger::NOTICE);
$this->authorization = yield $this->method_call_async_read('auth.importBotAuthorization', ['bot_auth_token' => $token, 'api_id' => $this->settings['app_info']['api_id'], 'api_hash' => $this->settings['app_info']['api_hash']], ['datacenter' => $this->datacenter->curdc]); $this->authorization = yield $this->methodCallAsyncRead('auth.importBotAuthorization', ['bot_auth_token' => $token, 'api_id' => $this->settings['app_info']['api_id'], 'api_hash' => $this->settings['app_info']['api_hash']], ['datacenter' => $this->datacenter->curdc]);
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->authorized_dc = $this->datacenter->curdc; $this->authorized_dc = $this->datacenter->curdc;
$this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true); $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true);
$this->updates = []; $this->updates = [];
$this->updates_key = 0; $this->updates_key = 0;
yield $this->init_authorization_async(); yield $this->initAuthorization();
$this->startUpdateSystem(); $this->startUpdateSystem();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_ok'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_ok'], \danog\MadelineProto\Logger::NOTICE);
@ -61,14 +61,14 @@ trait Login
return $this->authorization; return $this->authorization;
} }
public function phone_login_async($number, $sms_type = 5) public function phoneLogin($number, $sms_type = 5)
{ {
if ($this->authorized === self::LOGGED_IN) { if ($this->authorized === self::LOGGED_IN) {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['already_logged_in'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['already_logged_in'], \danog\MadelineProto\Logger::NOTICE);
yield $this->logout_async(); yield $this->logout();
} }
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_code_sending'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_code_sending'], \danog\MadelineProto\Logger::NOTICE);
$this->authorization = yield $this->method_call_async_read('auth.sendCode', ['settings' => ['_' => 'codeSettings'], 'phone_number' => $number, 'sms_type' => $sms_type, 'api_id' => $this->settings['app_info']['api_id'], 'api_hash' => $this->settings['app_info']['api_hash'], 'lang_code' => $this->settings['app_info']['lang_code']], ['datacenter' => $this->datacenter->curdc]); $this->authorization = yield $this->methodCallAsyncRead('auth.sendCode', ['settings' => ['_' => 'codeSettings'], 'phone_number' => $number, 'sms_type' => $sms_type, 'api_id' => $this->settings['app_info']['api_id'], 'api_hash' => $this->settings['app_info']['api_hash'], 'lang_code' => $this->settings['app_info']['lang_code']], ['datacenter' => $this->datacenter->curdc]);
$this->authorized_dc = $this->datacenter->curdc; $this->authorized_dc = $this->datacenter->curdc;
$this->authorization['phone_number'] = $number; $this->authorization['phone_number'] = $number;
//$this->authorization['_'] .= 'MP'; //$this->authorization['_'] .= 'MP';
@ -80,7 +80,7 @@ trait Login
return $this->authorization; return $this->authorization;
} }
public function complete_phone_login_async($code) public function completePhoneLogin($code)
{ {
if ($this->authorized !== self::WAITING_CODE) { if ($this->authorized !== self::WAITING_CODE) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['login_code_uncalled']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['login_code_uncalled']);
@ -89,11 +89,11 @@ trait Login
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_user'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_user'], \danog\MadelineProto\Logger::NOTICE);
try { try {
$authorization = yield $this->method_call_async_read('auth.signIn', ['phone_number' => $this->authorization['phone_number'], 'phone_code_hash' => $this->authorization['phone_code_hash'], 'phone_code' => (string) $code], ['datacenter' => $this->datacenter->curdc]); $authorization = yield $this->methodCallAsyncRead('auth.signIn', ['phone_number' => $this->authorization['phone_number'], 'phone_code_hash' => $this->authorization['phone_code_hash'], 'phone_code' => (string) $code], ['datacenter' => $this->datacenter->curdc]);
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
if ($e->rpc === 'SESSION_PASSWORD_NEEDED') { if ($e->rpc === 'SESSION_PASSWORD_NEEDED') {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_2fa_enabled'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_2fa_enabled'], \danog\MadelineProto\Logger::NOTICE);
$this->authorization = yield $this->method_call_async_read('account.getPassword', [], ['datacenter' => $this->datacenter->curdc]); $this->authorization = yield $this->methodCallAsyncRead('account.getPassword', [], ['datacenter' => $this->datacenter->curdc]);
if (!isset($this->authorization['hint'])) { if (!isset($this->authorization['hint'])) {
$this->authorization['hint'] = ''; $this->authorization['hint'] = '';
} }
@ -122,8 +122,8 @@ trait Login
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->authorization = $authorization; $this->authorization = $authorization;
$this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true); $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true);
yield $this->init_authorization_async(); yield $this->initAuthorization();
yield $this->get_phone_config_async(); yield $this->getPhoneConfig();
$this->startUpdateSystem(); $this->startUpdateSystem();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_ok'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_ok'], \danog\MadelineProto\Logger::NOTICE);
@ -131,11 +131,11 @@ trait Login
return $this->authorization; return $this->authorization;
} }
public function import_authorization_async($authorization) public function importAuthorization($authorization)
{ {
if ($this->authorized === self::LOGGED_IN) { if ($this->authorized === self::LOGGED_IN) {
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['already_logged_in'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['already_logged_in'], \danog\MadelineProto\Logger::NOTICE);
yield $this->logout_async(); yield $this->logout();
} }
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_auth_key'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_auth_key'], \danog\MadelineProto\Logger::NOTICE);
list($dc_id, $auth_key) = $authorization; list($dc_id, $auth_key) = $authorization;
@ -150,45 +150,45 @@ trait Login
$dataCenterConnection->setPermAuthKey($auth_key); $dataCenterConnection->setPermAuthKey($auth_key);
$dataCenterConnection->authorized(true); $dataCenterConnection->authorized(true);
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
yield $this->init_authorization_async(); yield $this->initAuthorization();
yield $this->get_phone_config_async(); yield $this->getPhoneConfig();
$res = yield $this->get_self_async(); $res = yield $this->getSelf();
$callbacks = [$this, $this->referenceDatabase]; $callbacks = [$this, $this->referenceDatabase];
if (!($this->authorization['user']['bot'] ?? false)) { if (!($this->authorization['user']['bot'] ?? false)) {
$callbacks []= $this->minDatabase; $callbacks []= $this->minDatabase;
} }
$this->update_callbacks($callbacks); $this->updateCallbacks($callbacks);
$this->startUpdateSystem(); $this->startUpdateSystem();
return $res; return $res;
} }
public function export_authorization_async() public function exportAuthorization()
{ {
if ($this->authorized !== self::LOGGED_IN) { if ($this->authorized !== self::LOGGED_IN) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['not_logged_in']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['not_logged_in']);
} }
yield $this->get_self_async(); yield $this->getSelf();
$this->authorized_dc = $this->datacenter->curdc; $this->authorized_dc = $this->datacenter->curdc;
return [$this->datacenter->curdc, $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->getPermAuthKey()->getAuthKey()]; return [$this->datacenter->curdc, $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->getPermAuthKey()->getAuthKey()];
} }
public function complete_signup_async($first_name, $last_name) public function completeSignup($first_name, $last_name)
{ {
if ($this->authorized !== self::WAITING_SIGNUP) { if ($this->authorized !== self::WAITING_SIGNUP) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['signup_uncalled']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['signup_uncalled']);
} }
$this->authorized = self::NOT_LOGGED_IN; $this->authorized = self::NOT_LOGGED_IN;
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['signing_up'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['signing_up'], \danog\MadelineProto\Logger::NOTICE);
$this->authorization = yield $this->method_call_async_read('auth.signUp', ['phone_number' => $this->authorization['phone_number'], 'phone_code_hash' => $this->authorization['phone_code_hash'], 'phone_code' => $this->authorization['phone_code'], 'first_name' => $first_name, 'last_name' => $last_name], ['datacenter' => $this->datacenter->curdc]); $this->authorization = yield $this->methodCallAsyncRead('auth.signUp', ['phone_number' => $this->authorization['phone_number'], 'phone_code_hash' => $this->authorization['phone_code_hash'], 'phone_code' => $this->authorization['phone_code'], 'first_name' => $first_name, 'last_name' => $last_name], ['datacenter' => $this->datacenter->curdc]);
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true); $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true);
yield $this->init_authorization_async(); yield $this->initAuthorization();
yield $this->get_phone_config_async(); yield $this->getPhoneConfig();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['signup_ok'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['signup_ok'], \danog\MadelineProto\Logger::NOTICE);
$this->startUpdateSystem(); $this->startUpdateSystem();
@ -196,7 +196,7 @@ trait Login
return $this->authorization; return $this->authorization;
} }
public function complete_2fa_login_async($password) public function complete2faLogin($password)
{ {
if ($this->authorized !== self::WAITING_PASSWORD) { if ($this->authorized !== self::WAITING_PASSWORD) {
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['2fa_uncalled']); throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['2fa_uncalled']);
@ -205,12 +205,12 @@ trait Login
$hasher = new PasswordCalculator($this->logger); $hasher = new PasswordCalculator($this->logger);
$hasher->addInfo($this->authorization); $hasher->addInfo($this->authorization);
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_user'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_user'], \danog\MadelineProto\Logger::NOTICE);
$this->authorization = yield $this->method_call_async_read('auth.checkPassword', ['password' => $hasher->getCheckPassword($password)], ['datacenter' => $this->datacenter->curdc]); $this->authorization = yield $this->methodCallAsyncRead('auth.checkPassword', ['password' => $hasher->getCheckPassword($password)], ['datacenter' => $this->datacenter->curdc]);
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true); $this->datacenter->getDataCenterConnection($this->datacenter->curdc)->authorized(true);
yield $this->init_authorization_async(); yield $this->initAuthorization();
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_ok'], \danog\MadelineProto\Logger::NOTICE); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_ok'], \danog\MadelineProto\Logger::NOTICE);
yield $this->get_phone_config_async(); yield $this->getPhoneConfig();
$this->startUpdateSystem(); $this->startUpdateSystem();
return $this->authorization; return $this->authorization;
@ -224,11 +224,11 @@ trait Login
* @param array $params The params * @param array $params The params
* @return void * @return void
*/ */
public function update_2fa_async(array $params) public function update2fa(array $params)
{ {
$hasher = new PasswordCalculator($this->logger); $hasher = new PasswordCalculator($this->logger);
$hasher->addInfo(yield $this->method_call_async_read('account.getPassword', [], ['datacenter' => $this->datacenter->curdc])); $hasher->addInfo(yield $this->methodCallAsyncRead('account.getPassword', [], ['datacenter' => $this->datacenter->curdc]));
return yield $this->method_call_async_read('account.updatePasswordSettings', $hasher->getPassword($params), ['datacenter' => $this->datacenter->curdc]); return yield $this->methodCallAsyncRead('account.updatePasswordSettings', $hasher->getPassword($params), ['datacenter' => $this->datacenter->curdc]);
} }
} }

View File

@ -35,7 +35,7 @@ trait Loop
$this->loop_callback = $callback; $this->loop_callback = $callback;
} }
public function loop_async($max_forks = 0) public function loop($max_forks = 0)
{ {
if (\is_callable($max_forks)) { if (\is_callable($max_forks)) {
$this->logger->logger('Running async callable'); $this->logger->logger('Running async callable');
@ -115,7 +115,7 @@ trait Loop
$uri = $_SERVER['REQUEST_URI']; $uri = $_SERVER['REQUEST_URI'];
$params = $_GET; $params = $_GET;
$params['MadelineSelfRestart'] = Tools::random_int(); $params['MadelineSelfRestart'] = Tools::randomInt();
$url = \explode($uri, '?', 2)[0] ?? ''; $url = \explode($uri, '?', 2)[0] ?? '';

View File

@ -26,120 +26,120 @@ use danog\MadelineProto\Tools;
*/ */
trait Start trait Start
{ {
public function start_async() public function start()
{ {
if ($this->authorized === self::LOGGED_IN) { if ($this->authorized === self::LOGGED_IN) {
return yield $this->get_self_async(); return yield $this->getSelf();
} }
if (PHP_SAPI === 'cli') { if (PHP_SAPI === 'cli') {
if (\strpos(yield Tools::readLine('Do you want to login as user or bot (u/b)? '), 'b') !== false) { if (\strpos(yield Tools::readLine('Do you want to login as user or bot (u/b)? '), 'b') !== false) {
yield $this->bot_login_async(yield Tools::readLine('Enter your bot token: ')); yield $this->botLogin(yield Tools::readLine('Enter your bot token: '));
} else { } else {
yield $this->phone_login_async(yield Tools::readLine('Enter your phone number: ')); yield $this->phoneLogin(yield Tools::readLine('Enter your phone number: '));
$authorization = yield $this->complete_phone_login_async(yield Tools::readLine('Enter the phone code: ')); $authorization = yield $this->completePhoneLogin(yield Tools::readLine('Enter the phone code: '));
if ($authorization['_'] === 'account.password') { if ($authorization['_'] === 'account.password') {
$authorization = yield $this->complete_2fa_login_async(yield Tools::readLine('Please enter your password (hint '.$authorization['hint'].'): ')); $authorization = yield $this->complete2faLogin(yield Tools::readLine('Please enter your password (hint '.$authorization['hint'].'): '));
} }
if ($authorization['_'] === 'account.needSignup') { if ($authorization['_'] === 'account.needSignup') {
$authorization = yield $this->complete_signup_async(yield Tools::readLine('Please enter your first name: '), yield Tools::readLine('Please enter your last name (can be empty): ')); $authorization = yield $this->completeSignup(yield Tools::readLine('Please enter your first name: '), yield Tools::readLine('Please enter your last name (can be empty): '));
} }
} }
$this->serialize(); $this->serialize();
return yield $this->get_self_async(); return yield $this->getSelf();
} }
if ($this->authorized === self::NOT_LOGGED_IN) { if ($this->authorized === self::NOT_LOGGED_IN) {
if (isset($_POST['phone_number'])) { if (isset($_POST['phone_number'])) {
yield $this->web_phone_login_async(); yield $this->webPhoneLogin();
} elseif (isset($_POST['token'])) { } elseif (isset($_POST['token'])) {
yield $this->web_bot_login_async(); yield $this->webBotLogin();
} else { } else {
yield $this->web_echo_async(); yield $this->webEcho();
} }
} elseif ($this->authorized === self::WAITING_CODE) { } elseif ($this->authorized === self::WAITING_CODE) {
if (isset($_POST['phone_code'])) { if (isset($_POST['phone_code'])) {
yield $this->web_complete_phone_login_async(); yield $this->webCompletePhoneLogin();
} else { } else {
yield $this->web_echo_async("You didn't provide a phone code!"); yield $this->webEcho("You didn't provide a phone code!");
} }
} elseif ($this->authorized === self::WAITING_PASSWORD) { } elseif ($this->authorized === self::WAITING_PASSWORD) {
if (isset($_POST['password'])) { if (isset($_POST['password'])) {
yield $this->web_complete_2fa_login_async(); yield $this->webComplete2faLogin();
} else { } else {
yield $this->web_echo_async("You didn't provide the password!"); yield $this->webEcho("You didn't provide the password!");
} }
} elseif ($this->authorized === self::WAITING_SIGNUP) { } elseif ($this->authorized === self::WAITING_SIGNUP) {
if (isset($_POST['first_name'])) { if (isset($_POST['first_name'])) {
yield $this->web_complete_signup_async(); yield $this->webCompleteSignup();
} else { } else {
yield $this->web_echo_async("You didn't provide the first name!"); yield $this->webEcho("You didn't provide the first name!");
} }
} }
if ($this->authorized === self::LOGGED_IN) { if ($this->authorized === self::LOGGED_IN) {
$this->serialize(); $this->serialize();
return yield $this->get_self_async(); return yield $this->getSelf();
} }
exit; exit;
} }
public function web_phone_login_async() public function webPhoneLogin()
{ {
try { try {
yield $this->phone_login_async($_POST['phone_number']); yield $this->phoneLogin($_POST['phone_number']);
yield $this->web_echo_async(); yield $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
public function web_complete_phone_login_async() public function webCompletePhoneLogin()
{ {
try { try {
yield $this->complete_phone_login_async($_POST['phone_code']); yield $this->completePhoneLogin($_POST['phone_code']);
yield $this->web_echo_async(); yield $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
public function web_complete_2fa_login_async() public function webComplete2faLogin()
{ {
try { try {
yield $this->complete_2fa_login_async($_POST['password']); yield $this->complete2faLogin($_POST['password']);
yield $this->web_echo_async(); yield $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
public function web_complete_signup_async() public function webCompleteSignup()
{ {
try { try {
yield $this->complete_signup_async($_POST['first_name'], isset($_POST['last_name']) ? $_POST['last_name'] : ''); yield $this->completeSignup($_POST['first_name'], isset($_POST['last_name']) ? $_POST['last_name'] : '');
yield $this->web_echo_async(); yield $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
public function web_bot_login_async() public function webBotLogin()
{ {
try { try {
yield $this->bot_login_async($_POST['token']); yield $this->botLogin($_POST['token']);
yield $this->web_echo_async(); yield $this->webEcho();
} catch (\danog\MadelineProto\RPCErrorException $e) { } catch (\danog\MadelineProto\RPCErrorException $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
yield $this->web_echo_async('ERROR: '.$e->getMessage().'. Try again.'); yield $this->webEcho('ERROR: '.$e->getMessage().'. Try again.');
} }
} }
} }

View File

@ -24,12 +24,12 @@ namespace danog\MadelineProto\Wrappers;
*/ */
trait TOS trait TOS
{ {
public function check_tos_async() public function checkTos()
{ {
if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot']) { if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot']) {
if ($this->tos['expires'] < \time()) { if ($this->tos['expires'] < \time()) {
$this->logger->logger('Fetching TOS...'); $this->logger->logger('Fetching TOS...');
$this->tos = yield $this->method_call_async_read('help.getTermsOfServiceUpdate', [], ['datacenter' => $this->datacenter->curdc]); $this->tos = yield $this->methodCallAsyncRead('help.getTermsOfServiceUpdate', [], ['datacenter' => $this->datacenter->curdc]);
$this->tos['accepted'] = $this->tos['_'] === 'help.termsOfServiceUpdateEmpty'; $this->tos['accepted'] = $this->tos['_'] === 'help.termsOfServiceUpdateEmpty';
} }
@ -46,9 +46,9 @@ trait TOS
} }
} }
public function accept_tos_async() public function acceptTos()
{ {
$this->tos['accepted'] = yield $this->method_call_async_read('help.acceptTermsOfService', ['id' => $this->tos['terms_of_service']['id']], ['datacenter' => $this->datacenter->curdc]); $this->tos['accepted'] = yield $this->methodCallAsyncRead('help.acceptTermsOfService', ['id' => $this->tos['terms_of_service']['id']], ['datacenter' => $this->datacenter->curdc]);
if ($this->tos['accepted']) { if ($this->tos['accepted']) {
$this->logger->logger('TOS accepted successfully'); $this->logger->logger('TOS accepted successfully');
} else { } else {
@ -56,9 +56,9 @@ trait TOS
} }
} }
public function decline_tos_async() public function declineTos()
{ {
yield $this->method_call_async_read('account.deleteAccount', ['reason' => 'Decline ToS update'], ['datacenter' => $this->datacenter->curdc]); yield $this->methodCallAsyncRead('account.deleteAccount', ['reason' => 'Decline ToS update'], ['datacenter' => $this->datacenter->curdc]);
yield $this->logout_async(); yield $this->logout();
} }
} }

View File

@ -23,32 +23,32 @@ use function Amp\ByteStream\getOutputBufferStream;
trait Templates trait Templates
{ {
public function web_echo_async($message = '') public function webEcho($message = '')
{ {
$stdout = getOutputBufferStream(); $stdout = getOutputBufferStream();
switch ($this->authorized) { switch ($this->authorized) {
case self::NOT_LOGGED_IN: case self::NOT_LOGGED_IN:
if (isset($_POST['type'])) { if (isset($_POST['type'])) {
if ($_POST['type'] === 'phone') { if ($_POST['type'] === 'phone') {
yield $stdout->write($this->web_echo_template('Enter your phone number<br><b>'.$message.'</b>', '<input type="text" name="phone_number" placeholder="Phone number" required/>')); yield $stdout->write($this->webEchoTemplate('Enter your phone number<br><b>'.$message.'</b>', '<input type="text" name="phone_number" placeholder="Phone number" required/>'));
} else { } else {
yield $stdout->write($this->web_echo_template('Enter your bot token<br><b>'.$message.'</b>', '<input type="text" name="token" placeholder="Bot token" required/>')); yield $stdout->write($this->webEchoTemplate('Enter your bot token<br><b>'.$message.'</b>', '<input type="text" name="token" placeholder="Bot token" required/>'));
} }
} else { } else {
yield $stdout->write($this->web_echo_template('Do you want to login as user or bot?<br><b>'.$message.'</b>', '<select name="type"><option value="phone">User</option><option value="bot">Bot</option></select>')); yield $stdout->write($this->webEchoTemplate('Do you want to login as user or bot?<br><b>'.$message.'</b>', '<select name="type"><option value="phone">User</option><option value="bot">Bot</option></select>'));
} }
break; break;
case self::WAITING_CODE: case self::WAITING_CODE:
yield $stdout->write($this->web_echo_template('Enter your code<br><b>'.$message.'</b>', '<input type="text" name="phone_code" placeholder="Phone code" required/>')); yield $stdout->write($this->webEchoTemplate('Enter your code<br><b>'.$message.'</b>', '<input type="text" name="phone_code" placeholder="Phone code" required/>'));
break; break;
case self::WAITING_PASSWORD: case self::WAITING_PASSWORD:
yield $stdout->write($this->web_echo_template('Enter your password<br><b>'.$message.'</b>', '<input type="password" name="password" placeholder="Hint: '.$this->authorization['hint'].'" required/>')); yield $stdout->write($this->webEchoTemplate('Enter your password<br><b>'.$message.'</b>', '<input type="password" name="password" placeholder="Hint: '.$this->authorization['hint'].'" required/>'));
break; break;
case self::WAITING_SIGNUP: case self::WAITING_SIGNUP:
yield $stdout->write($this->web_echo_template('Sign up please<br><b>'.$message.'</b>', '<input type="text" name="first_name" placeholder="First name" required/><input type="text" name="last_name" placeholder="Last name"/>')); yield $stdout->write($this->webEchoTemplate('Sign up please<br><b>'.$message.'</b>', '<input type="text" name="first_name" placeholder="First name" required/><input type="text" name="last_name" placeholder="Last name"/>'));
break; break;
} }
} }
@ -68,17 +68,17 @@ trait Templates
</body> </body>
</html>'; </html>';
public function web_echo_template($message, $form) public function webEchoTemplate($message, $form)
{ {
return \sprintf($this->web_template, $form, $message); return \sprintf($this->web_template, $form, $message);
} }
public function get_web_template() public function getWebTemplate()
{ {
return $this->web_template; return $this->web_template;
} }
public function set_web_template($template) public function setWebTemplate($template)
{ {
$this->web_template = $template; $this->web_template = $template;
} }

View File

@ -31,7 +31,7 @@ foreach ($methods as $methodObj) {
} }
$new = Tools::from_snake_case($method); $new = Tools::from_snake_case($method);
$new = \str_ireplace(['mtproto', 'api'], ['MTProto', 'API'], $new); $new = \str_ireplace(['mtproto', 'api'], ['MTProto', 'API'], $new);
$new = preg_replace('/async$/i', '', $new); if (!in_array($method, ['discard_call_async', 'accept_call_async', 'request_call_async'])) $new = preg_replace('/async$/i', '', $new);
if (method_exists((string) $methodObj->getDeclaringClass(), preg_replace('/async$/i', '', $method))) { if (method_exists((string) $methodObj->getDeclaringClass(), preg_replace('/async$/i', '', $method))) {
var_dump("Skipping $method => $new"); var_dump("Skipping $method => $new");
@ -61,6 +61,8 @@ foreach (new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryI
$new = \str_replace($find, $replace, $old = \file_get_contents($filename)); $new = \str_replace($find, $replace, $old = \file_get_contents($filename));
} while ($old !== $new); } while ($old !== $new);
} }
exit;
foreach (new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(\realpath('docs'))), '/\.md$/') as $filename) { foreach (new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(\realpath('docs'))), '/\.md$/') as $filename) {
$filename = (string) $filename; $filename = (string) $filename;
$new = \str_replace($find, $replace, $old = \file_get_contents($filename)); $new = \str_replace($find, $replace, $old = \file_get_contents($filename));