diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index 5c2f7273..22a9a880 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -96,7 +96,7 @@ class API extends APIFactory if (isset($unserialized->API)) { $this->API = $unserialized->API; - $promise = $this->call(function () { + $promise = $this->call((function () { yield $this->API->asyncInitPromise; $this->API->asyncInitPromise = null; $this->APIFactory(); @@ -104,7 +104,7 @@ class API extends APIFactory $pong = $this->ping(['ping_id' => 3], ['async' => true]); \danog\MadelineProto\Logger::log('Pong: ' . $pong['ping_id'], Logger::ULTRA_VERBOSE); \danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['madelineproto_ready'], Logger::NOTICE); - }); + })()); $this->APIFactory(); return; @@ -119,7 +119,7 @@ class API extends APIFactory } $this->API = new MTProto($params); \danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['apifactory_start'], Logger::VERBOSE); - $promise = $this->call(function () { + $promise = $this->call((function () { yield $this->API->asyncInitPromise; $this->API->asyncInitPromise = null; $this->APIFactory(); @@ -127,7 +127,7 @@ class API extends APIFactory $pong = $this->ping(['ping_id' => 3], ['async' => true]); \danog\MadelineProto\Logger::log('Pong: ' . $pong['ping_id'], Logger::ULTRA_VERBOSE); \danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['madelineproto_ready'], Logger::NOTICE); - }); + })()); $this->APIFactory(); } diff --git a/src/danog/MadelineProto/APIFactory.php b/src/danog/MadelineProto/APIFactory.php index 3693ea91..575475fd 100644 --- a/src/danog/MadelineProto/APIFactory.php +++ b/src/danog/MadelineProto/APIFactory.php @@ -187,11 +187,11 @@ class APIFactory if ($this->API->asyncInitPromise) { $async = is_array(end($arguments)) && isset(end($arguments)['async']) ? end($arguments)['async'] : ($this->async && $name !== 'loop'); if ($async) { - return $this->call(function () use ($name, $arguments) { + return $this->call((function () use ($name, $arguments) { yield $this->API->asyncInitPromise; $this->API->asyncInitPromise = null; return yield $this->methods[$name](...$arguments); - }); + })()); } else { $this->wait($this->API->asyncInitPromise); $this->API->asyncInitPromise = null; @@ -220,13 +220,13 @@ class APIFactory if ($this->API->asyncInitPromise) { if ($async) { - return $this->call(function () use ($name, $args, $aargs) { + return $this->call((function () use ($name, $args, $aargs) { yield $this->API->asyncInitPromise; $this->API->asyncInitPromise = null; $aargs['datacenter'] = $this->API->datacenter->curdc; return yield $this->API->method_call_async_read($name, $args, $aargs); ; - }); + })()); } else { $this->wait($this->API->asyncInitPromise); $this->API->asyncInitPromise = null; diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 32be5256..00f48b2d 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -890,7 +890,7 @@ class MTProto implements TLCallback } } - public function parse_config() + public function parse_config_async() { if (isset($this->config['dc_options'])) { yield $this->parse_dc_options($this->config['dc_options']); @@ -900,7 +900,7 @@ class MTProto implements TLCallback $this->logger->logger($this->config, Logger::NOTICE); } - public function parse_dc_options($dc_options) + public function parse_dc_options_async($dc_options) { unset($this->settings[$this->config['test_mode']]); foreach ($dc_options as $dc) { diff --git a/src/danog/MadelineProto/MTProtoTools/Files.php b/src/danog/MadelineProto/MTProtoTools/Files.php index 1f7a938e..5fada369 100644 --- a/src/danog/MadelineProto/MTProtoTools/Files.php +++ b/src/danog/MadelineProto/MTProtoTools/Files.php @@ -439,7 +439,7 @@ trait Files return $file; } - public function download_to_stream($message_media, $stream, $cb = null, $offset = 0, $end = -1) + public function download_to_stream_async($message_media, $stream, $cb = null, $offset = 0, $end = -1) { if (is_object($stream) && class_implements($stream)['danog\MadelineProto\FileCallbackInterface']) { $cb = $stream; @@ -491,12 +491,12 @@ trait Files } try { - $res = $cdn ? $this->method_call('upload.getCdnFile', ['file_token' => $message_media['file_token'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'file' => true, 'datacenter' => $datacenter]) : $this->method_call('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'file' => true, 'datacenter' => &$datacenter]); + $res = $cdn ? yield $this->method_call_async_read('upload.getCdnFile', ['file_token' => $message_media['file_token'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'file' => true, 'datacenter' => $datacenter]) : yield $this->method_call_async_read('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'file' => true, 'datacenter' => &$datacenter]); } catch (\danog\MadelineProto\RPCErrorException $e) { if (strpos($e->rpc, 'FLOOD_WAIT_') === 0) { if (isset($message_media['MessageMedia']) && !$this->authorization['user']['bot'] && $this->settings['download']['report_broken_media']) { try { - $this->method_call('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->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]); } catch (RPCErrorException $e) { $this->logger->logger('An error occurred while reporting the broken file: '.$e->rpc, Logger::FATAL_ERROR); } catch (Exception $e) { @@ -523,17 +523,17 @@ trait Files $datacenter = $res['dc_id'].'_cdn'; if (!isset($this->datacenter->sockets[$datacenter])) { $this->config['expires'] = -1; - $this->get_config([], ['datacenter' => $this->datacenter->curdc]); + yield $this->get_config_async([], ['datacenter' => $this->datacenter->curdc]); } $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['stored_on_cdn'], \danog\MadelineProto\Logger::NOTICE); continue; } if ($res['_'] === 'upload.cdnFileReuploadNeeded') { $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['cdn_reupload'], \danog\MadelineProto\Logger::NOTICE); - $this->get_config([], ['datacenter' => $this->datacenter->curdc]); + yield $this->get_config_async([], ['datacenter' => $this->datacenter->curdc]); try { - $this->add_cdn_hashes($message_media['file_token'], $this->method_call('upload.reuploadCdnFile', ['file_token' => $message_media['file_token'], 'request_token' => $res['request_token']], ['heavy' => true, 'datacenter' => $old_dc])); + $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])); } catch (\danog\MadelineProto\RPCErrorException $e) { switch ($e->rpc) { case 'FILE_TOKEN_INVALID': @@ -550,7 +550,7 @@ trait Files $datacenter = 1; } while ($cdn === false && $res['type']['_'] === 'storage.fileUnknown' && $res['bytes'] === '') { - $res = $this->method_call('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => $datacenter]); + $res = yield $this->method_call_async_read('upload.getFile', ['location' => $message_media['InputFileLocation'], 'offset' => $offset, 'limit' => $part_size], ['heavy' => true, 'datacenter' => $datacenter]); $datacenter++; if (!isset($this->datacenter->sockets[$datacenter])) { break; @@ -610,7 +610,7 @@ trait Files { while (strlen($data)) { if (!isset($this->cdn_hashes[$file][$offset])) { - $this->add_cdn_hashes($file, $this->method_call('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter])); + $this->add_cdn_hashes($file, yield $this->method_call_async_read('upload.getCdnFileHashes', ['file_token' => $file, 'offset' => $offset], ['datacenter' => $datacenter])); } if (!isset($this->cdn_hashes[$file][$offset])) { throw new \danog\MadelineProto\Exception('Could not fetch CDN hashes for offset '.$offset); diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index 3055150d..9263e425 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -324,7 +324,7 @@ trait PeerHandler } return false; } - public function get_info($id, $recursive = true) + public function get_info_async($id, $recursive = true) { if (is_array($id)) { switch ($id['_']) { @@ -354,12 +354,12 @@ trait PeerHandler $this->caching_simple[$id] = true; if ($id < 0) { if ($this->is_supergroup($id)) { - $this->method_call('channels.getChannels', ['id' => [['access_hash' => 0, 'channel_id' => $this->from_supergroup($id), '_' => 'inputChannel']]], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('channels.getChannels', ['id' => [['access_hash' => 0, 'channel_id' => $this->from_supergroup($id), '_' => 'inputChannel']]], ['datacenter' => $this->datacenter->curdc]); } else { - $this->method_call('messages.getFullChat', ['chat_id' => -$id], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('messages.getFullChat', ['chat_id' => -$id], ['datacenter' => $this->datacenter->curdc]); } } else { - $this->method_call('users.getUsers', ['id' => [['access_hash' => 0, 'user_id' => $id, '_' => 'inputUser']]], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('users.getUsers', ['id' => [['access_hash' => 0, 'user_id' => $id, '_' => 'inputUser']]], ['datacenter' => $this->datacenter->curdc]); } } catch (\danog\MadelineProto\Exception $e) { $this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::WARNING); @@ -402,7 +402,7 @@ trait PeerHandler if ($matches[1] === '') { $id = $matches[2]; } else { - $invite = $this->method_call('messages.checkChatInvite', ['hash' => $matches[2]], ['datacenter' => $this->datacenter->curdc]); + $invite = yield $this->method_call_async_read('messages.checkChatInvite', ['hash' => $matches[2]], ['datacenter' => $this->datacenter->curdc]); if (isset($invite['chat'])) { return $this->get_info($invite['chat']); } else { @@ -416,7 +416,7 @@ trait PeerHandler } if ($id === 'support') { if (!$this->supportUser) { - $this->method_call('help.getSupport', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); + yield $this->method_call_async_read('help.getSupport', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); } return $this->get_info($this->supportUser); @@ -499,7 +499,7 @@ trait PeerHandler return isset($this->full_chats[$id]['last_update']) ? $this->full_chats[$id]['last_update'] : 0; } - public function get_full_info($id) + public function get_full_info_async($id) { $partial = $this->get_info($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)) { @@ -508,14 +508,14 @@ trait PeerHandler switch ($partial['type']) { case 'user': case 'bot': - $full = $this->method_call('users.getFullUser', ['id' => $partial['InputUser']], ['datacenter' => $this->datacenter->curdc]); + $full = yield $this->method_call_async_read('users.getFullUser', ['id' => $partial['InputUser']], ['datacenter' => $this->datacenter->curdc]); break; case 'chat': - $full = $this->method_call('messages.getFullChat', $partial, ['datacenter' => $this->datacenter->curdc])['full_chat']; + $full = yield $this->method_call_async_read('messages.getFullChat', $partial, ['datacenter' => $this->datacenter->curdc])['full_chat']; break; case 'channel': case 'supergroup': - $full = $this->method_call('channels.getFullChannel', ['channel' => $partial['InputChannel']], ['datacenter' => $this->datacenter->curdc])['full_chat']; + $full = yield $this->method_call_async_read('channels.getFullChannel', ['channel' => $partial['InputChannel']], ['datacenter' => $this->datacenter->curdc])['full_chat']; break; } @@ -688,7 +688,7 @@ trait PeerHandler } } - public function fetch_participants($channel, $filter, $q, $total_count, &$res) + public function fetch_participants_async($channel, $filter, $q, $total_count, &$res) { $offset = 0; $limit = 200; @@ -698,7 +698,7 @@ trait PeerHandler do { try { - $gres = $this->method_call('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->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]); } catch (\danog\MadelineProto\RPCErrorException $e) { if ($e->rpc === 'CHAT_ADMIN_REQUIRED') { return $has_more; @@ -845,11 +845,11 @@ trait PeerHandler } } - public function resolve_username($username) + public function resolve_username_async($username) { try { $this->caching_simple_username[$username] = true; - $res = $this->method_call('contacts.resolveUsername', ['username' => str_replace('@', '', $username)], ['datacenter' => $this->datacenter->curdc]); + $res = yield $this->method_call_async_read('contacts.resolveUsername', ['username' => str_replace('@', '', $username)], ['datacenter' => $this->datacenter->curdc]); } catch (\danog\MadelineProto\RPCErrorException $e) { $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') { diff --git a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php index b25d20af..2a2940dc 100644 --- a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php @@ -398,9 +398,11 @@ trait ResponseHandler $this->authorization = null; Loop::defer(function () use ($datacenter, &$request, &$response) { - $this->init_authorization(); + $this->call((function () use ($datacenter, &$request, &$response) { + yield $this->init_authorization_async(); - $this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'])); + $this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'])); + })()); }); return; @@ -410,9 +412,11 @@ trait ResponseHandler $this->got_response_for_outgoing_message_id($request_id, $datacenter); Loop::defer(function () use ($datacenter, &$request, &$response) { - $this->init_authorization(); + $this->call((function () use ($datacenter, &$request, &$response) { + yield $this->init_authorization_async(); - $this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'])); + $this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'])); + })()); }); return; @@ -445,17 +449,21 @@ trait ResponseHandler $this->authorization = null; Loop::defer(function () use ($datacenter, &$request, &$response) { - $this->init_authorization(); + $this->call((function () use ($datacenter, &$request, &$response) { + yield $this->init_authorization_async(); - $this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'])); + $this->handle_reject($datacenter, $request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'])); + })()); }); return; } Loop::defer(function () use ($request_id, $datacenter) { - $this->init_authorization(); + $this->call((function () use ($request_id, $datacenter) { + yield $this->init_authorization_async(); - $this->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter]); + $this->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter]); + })()); }); return; @@ -464,8 +472,10 @@ trait ResponseHandler $this->datacenter->sockets[$datacenter]->temp_auth_key = null; Loop::defer(function () use ($request_id, $datacenter) { - $this->init_authorization(); - $this->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter]); + $this->call((function () use ($request_id, $datacenter) { + yield $this->init_authorization_async(); + $this->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter]); + })()); }); return; @@ -517,8 +527,11 @@ trait ResponseHandler $this->reset_session(); $this->datacenter->sockets[$datacenter]->temp_auth_key = null; Loop::defer(function () use ($request_id, $datacenter) { - $this->init_authorization(); - $this->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter]); + + $this->call((function () use ($datacenter, $request_id) { + yield $this->init_authorization_async(); + $this->method_recall('', ['message_id' => $request_id, 'datacenter' => $datacenter]); + })()); }); return; diff --git a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php index 79373e60..f4db594a 100644 --- a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php @@ -136,7 +136,7 @@ trait UpdateHandler return false; } - public function get_channel_difference($channel) + public function get_channel_difference_async($channel) { if (!$this->settings['updates']['handle_updates']) { return; @@ -168,7 +168,7 @@ trait UpdateHandler $this->postpone_updates = true; try { - $difference = $this->method_call('updates.getChannelDifference', ['channel' => $input, 'filter' => ['_' => 'channelMessagesFilterEmpty'], 'pts' => $this->load_channel_state($channel)['pts'], 'limit' => 30], ['datacenter' => $this->datacenter->curdc]); + $difference = yield $this->method_call_async_read('updates.getChannelDifference', ['channel' => $input, 'filter' => ['_' => 'channelMessagesFilterEmpty'], 'pts' => $this->load_channel_state($channel)['pts'], 'limit' => 30], ['datacenter' => $this->datacenter->curdc]); } catch (\danog\MadelineProto\RPCErrorException $e) { if ($e->getMessage() === "You haven't joined this channel/supergroup") { return false; @@ -268,7 +268,7 @@ trait UpdateHandler return $this->updates_state; } - public function get_updates_difference($w = null) + public function get_updates_difference_async($w = null) { if (!$this->settings['updates']['handle_updates']) { return; @@ -283,7 +283,7 @@ trait UpdateHandler $this->logger->logger('Fetching normal difference...', \danog\MadelineProto\Logger::ULTRA_VERBOSE); while (!isset($difference)) { try { - $difference = $this->method_call('updates.getDifference', ['pts' => $this->load_update_state()['pts'], 'date' => $this->load_update_state()['date'], 'qts' => $this->load_update_state()['qts']], ['datacenter' => $this->settings['connection_settings']['default_dc']]); + $difference = yield $this->method_call_async_read('updates.getDifference', ['pts' => $this->load_update_state()['pts'], 'date' => $this->load_update_state()['date'], 'qts' => $this->load_update_state()['qts']], ['datacenter' => $this->settings['connection_settings']['default_dc']]); } catch (\danog\MadelineProto\PTSException $e) { $this->updates_state['sync_loading'] = false; $this->got_state = false; @@ -341,14 +341,14 @@ trait UpdateHandler return true; } - public function get_updates_state() + public function get_updates_state_async() { $last = $this->updates_state['sync_loading']; $this->updates_state['sync_loading'] = true; try { - $data = $this->method_call('updates.getState', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); - $this->get_cdn_config($this->settings['connection_settings']['default_dc']); + $data = yield $this->method_call_async_read('updates.getState', [], ['datacenter' => $this->settings['connection_settings']['default_dc']]); + yield $this->get_cdn_config_async($this->settings['connection_settings']['default_dc']); } finally { $this->updates_state['sync_loading'] = $last; } @@ -523,11 +523,11 @@ trait UpdateHandler } } - public function save_update($update) + public function save_update_async($update) { if ($update['_'] === 'updateConfig') { $this->config['expires'] = 0; - $this->get_config(); + yield $this->get_config_async(); } if (in_array($update['_'], ['updateUserName', 'updateUserPhone', 'updateUserBlocked', 'updateUserPhoto', 'updateContactRegistered', 'updateContactLink'])) { $id = $this->get_id($update); @@ -593,7 +593,7 @@ trait UpdateHandler 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->method_call('messages.receivedQueue', ['max_qts' => $cur_state['qts'] = $update['qts']], ['datacenter' => $this->settings['connection_settings']['default_dc']]); + yield $this->method_call_async_read('messages.receivedQueue', ['max_qts' => $cur_state['qts'] = $update['qts']], ['datacenter' => $this->settings['connection_settings']['default_dc']]); $this->handle_encrypted_update($update); return; @@ -652,7 +652,7 @@ trait UpdateHandler } } - public function pwr_webhook($update) + public function pwr_webhook_async($update) { $payload = json_encode($update); //$this->logger->logger($update, $payload, json_last_error()); @@ -682,7 +682,7 @@ trait UpdateHandler $result = json_decode($result, true); if (is_array($result) && isset($result['method']) && $result['method'] != '' && is_string($result['method'])) { try { - $this->logger->logger('Reverse webhook command returned', $this->method_call($result['method'], $result, ['datacenter' => $this->datacenter->curdc])); + $this->logger->logger('Reverse webhook command returned', yield $this->method_call_async_read($result['method'], $result, ['datacenter' => $this->datacenter->curdc])); } catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\TL\Exception $e) { } catch (\danog\MadelineProto\RPCErrorException $e) { diff --git a/src/danog/MadelineProto/RSA.php b/src/danog/MadelineProto/RSA.php index 71011f23..6eeb6ccb 100644 --- a/src/danog/MadelineProto/RSA.php +++ b/src/danog/MadelineProto/RSA.php @@ -27,7 +27,7 @@ class RSA public $n; public $fp; - public function __magic_construct($rsa_key) + public function __magic_construct_async($rsa_key) { \danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['rsa_init'], Logger::ULTRA_VERBOSE); $key = new \phpseclib\Crypt\RSA(); @@ -36,7 +36,7 @@ class RSA $this->n = \phpseclib\Common\Functions\Objects::getVar($key, 'modulus'); $this->e = \phpseclib\Common\Functions\Objects::getVar($key, 'exponent'); \danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['computing_fingerprint'], Logger::ULTRA_VERBOSE); - $this->fp = substr(sha1($this->serialize_object(['type' => 'bytes'], $this->n->toBytes(), 'key').$this->serialize_object(['type' => 'bytes'], $this->e->toBytes(), 'key'), true), -8); + $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); return true; } diff --git a/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php b/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php index c13ca035..53959827 100644 --- a/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php +++ b/src/danog/MadelineProto/SecretChats/AuthKeyHandler.php @@ -29,7 +29,7 @@ trait AuthKeyHandler protected $temp_requested_secret_chats = []; protected $secret_chats = []; - public function accept_secret_chat($params) + public function accept_secret_chat_async($params) { //$this->logger->logger($params['id'],$this->secret_chat_status($params['id'])); if ($this->secret_chat_status($params['id']) !== 0) { @@ -38,7 +38,7 @@ trait AuthKeyHandler return false; } - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE); $b = new \phpseclib\Math\BigInteger($this->random(256), 256); $params['g_a'] = new \phpseclib\Math\BigInteger($params['g_a'], 256); @@ -51,13 +51,13 @@ trait AuthKeyHandler $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']); $this->check_G($g_b, $dh_config['p']); - $this->method_call('messages.acceptEncryption', ['peer' => $params['id'], 'g_b' => $g_b->toBytes(), 'key_fingerprint' => $key['fingerprint']], ['datacenter' => $this->datacenter->curdc]); - $this->notify_layer($params['id']); + 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->notify_layer_async($params['id']); $this->handle_pending_updates(); $this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', \danog\MadelineProto\Logger::NOTICE); } - public function request_secret_chat($user) + public function request_secret_chat_async($user) { $user = $this->get_info($user); if (!isset($user['InputUser'])) { @@ -65,13 +65,13 @@ trait AuthKeyHandler } $user = $user['InputUser']; $this->logger->logger('Creating secret chat with '.$user['user_id'].'...', \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE); $a = new \phpseclib\Math\BigInteger($this->random(256), 256); $this->logger->logger('Generating g_a...', \danog\MadelineProto\Logger::VERBOSE); $g_a = $dh_config['g']->powMod($a, $dh_config['p']); $this->check_G($g_a, $dh_config['p']); - $res = $this->method_call('messages.requestEncryption', ['user_id' => $user, 'g_a' => $g_a->toBytes()], ['datacenter' => $this->datacenter->curdc]); + $res = yield $this->method_call_async_read('messages.requestEncryption', ['user_id' => $user, 'g_a' => $g_a->toBytes()], ['datacenter' => $this->datacenter->curdc]); $this->temp_requested_secret_chats[$res['id']] = $a; $this->handle_pending_updates(); $this->get_updates_difference(); @@ -80,7 +80,7 @@ trait AuthKeyHandler return $res['id']; } - public function complete_secret_chat($params) + public function complete_secret_chat_async($params) { if ($this->secret_chat_status($params['id']) !== 1) { //$this->logger->logger($this->secret_chat_status($params['id'])); @@ -88,7 +88,7 @@ trait AuthKeyHandler return false; } - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $params['g_a_or_b'] = new \phpseclib\Math\BigInteger($params['g_a_or_b'], 256); $this->check_G($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)]; @@ -103,7 +103,7 @@ trait AuthKeyHandler $key['visualization_orig'] = substr(sha1($key['auth_key'], true), 16); $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->notify_layer($params['id']); + yield $this->notify_layer_async($params['id']); $this->handle_pending_updates(); $this->logger->logger('Secret chat '.$params['id'].' completed successfully!', \danog\MadelineProto\Logger::NOTICE); } @@ -119,13 +119,13 @@ trait AuthKeyHandler protected $temp_rekeyed_secret_chats = []; - public function rekey($chat) + public function rekey_async($chat) { if ($this->secret_chats[$chat]['rekeying'][0] !== 0) { return; } $this->logger->logger('Rekeying secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $this->logger->logger('Generating a...', \danog\MadelineProto\Logger::VERBOSE); $a = new \phpseclib\Math\BigInteger($this->random(256), 256); $this->logger->logger('Generating g_a...', \danog\MadelineProto\Logger::VERBOSE); @@ -134,14 +134,14 @@ trait AuthKeyHandler $e = $this->random(8); $this->temp_rekeyed_secret_chats[$e] = $a; $this->secret_chats[$chat]['rekeying'] = [1, $e]; - $this->method_call('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionRequestKey', 'g_a' => $g_a->toBytes(), 'exchange_id' => $e]]], ['datacenter' => $this->datacenter->curdc]); + 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]); $this->handle_pending_updates(); $this->get_updates_difference(); return $e; } - public function accept_rekey($chat, $params) + public function accept_rekey_async($chat, $params) { if ($this->secret_chats[$chat]['rekeying'][0] !== 0) { $my_exchange_id = new \phpseclib\Math\BigInteger($this->secret_chats[$chat]['rekeying'][1], -256); @@ -157,7 +157,7 @@ trait AuthKeyHandler } } $this->logger->logger('Accepting rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE); $b = new \phpseclib\Math\BigInteger($this->random(256), 256); $params['g_a'] = new \phpseclib\Math\BigInteger($params['g_a'], 256); @@ -170,12 +170,12 @@ trait AuthKeyHandler $this->secret_chats[$chat]['rekeying'] = [2, $params['exchange_id']]; $g_b = $dh_config['g']->powMod($b, $dh_config['p']); $this->check_G($g_b, $dh_config['p']); - $this->method_call('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->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]); $this->handle_pending_updates(); $this->get_updates_difference(); } - public function commit_rekey($chat, $params) + public function commit_rekey_async($chat, $params) { if ($this->secret_chats[$chat]['rekeying'][0] !== 1 || !isset($this->temp_rekeyed_secret_chats[$params['exchange_id']])) { $this->secret_chats[$chat]['rekeying'] = [0]; @@ -183,7 +183,7 @@ trait AuthKeyHandler return; } $this->logger->logger('Committing rekeying of secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $params['g_b'] = new \phpseclib\Math\BigInteger($params['g_b'], 256); $this->check_G($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)]; @@ -191,11 +191,11 @@ trait AuthKeyHandler $key['visualization_orig'] = $this->secret_chats[$chat]['key']['visualization_orig']; $key['visualization_46'] = substr(hash('sha256', $key['auth_key'], true), 20); if ($key['fingerprint'] !== $params['key_fingerprint']) { - $this->method_call('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('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!'); } - $this->method_call('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionCommitKey', 'exchange_id' => $params['exchange_id'], 'key_fingerprint' => $key['fingerprint']]]], ['datacenter' => $this->datacenter->curdc]); + 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]); unset($this->temp_rekeyed_secret_chats[$chat]); $this->secret_chats[$chat]['rekeying'] = [0]; $this->secret_chats[$chat]['old_key'] = $this->secret_chats[$chat]['key']; @@ -206,13 +206,13 @@ trait AuthKeyHandler $this->get_updates_difference(); } - public function complete_rekey($chat, $params) + public function complete_rekey_async($chat, $params) { if ($this->secret_chats[$chat]['rekeying'][0] !== 2 || !isset($this->temp_rekeyed_secret_chats['fingerprint'])) { return; } if ($this->temp_rekeyed_secret_chats['fingerprint'] !== $params['key_fingerprint']) { - $this->method_call('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionAbortKey', 'exchange_id' => $params['exchange_id']]]], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('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!'); } @@ -223,7 +223,7 @@ trait AuthKeyHandler $this->secret_chats[$chat]['ttr'] = 100; $this->secret_chats[$chat]['updated'] = time(); unset($this->temp_rekeyed_secret_chats[$params['exchange_id']]); - $this->method_call('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNoop']]], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNoop']]], ['datacenter' => $this->datacenter->curdc]); $this->logger->logger('Secret chat '.$chat.' rekeyed successfully!', \danog\MadelineProto\Logger::VERBOSE); return true; @@ -246,7 +246,7 @@ trait AuthKeyHandler return $this->secret_chats[is_array($chat) ? $chat['chat_id'] : $chat]; } - public function discard_secret_chat($chat) + public function discard_secret_chat_async($chat) { $this->logger->logger('Discarding secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE); //$this->logger->logger(debug_backtrace(0)[0]); @@ -261,7 +261,7 @@ trait AuthKeyHandler } try { - $this->method_call('messages.discardEncryption', ['chat_id' => $chat], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('messages.discardEncryption', ['chat_id' => $chat], ['datacenter' => $this->datacenter->curdc]); } catch (\danog\MadelineProto\RPCErrorException $e) { if ($e->rpc !== 'ENCRYPTION_ALREADY_DECLINED') { throw $e; diff --git a/src/danog/MadelineProto/SecretChats/MessageHandler.php b/src/danog/MadelineProto/SecretChats/MessageHandler.php index f76684f3..8372339f 100644 --- a/src/danog/MadelineProto/SecretChats/MessageHandler.php +++ b/src/danog/MadelineProto/SecretChats/MessageHandler.php @@ -24,7 +24,7 @@ namespace danog\MadelineProto\SecretChats; */ trait MessageHandler { - public function encrypt_secret_message($chat_id, $message) + public function encrypt_secret_message_async($chat_id, $message) { if (!isset($this->secret_chats[$chat_id])) { $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['secret_chat_skipping'], $chat_id)); @@ -41,7 +41,7 @@ trait MessageHandler $this->secret_chats[$chat_id]['out_seq_no']++; } $this->secret_chats[$chat_id]['outgoing'][$this->secret_chats[$chat_id]['out_seq_no']] = $message; - $message = $this->serialize_object(['type' => $constructor = $this->secret_chats[$chat_id]['layer'] === 8 ? 'DecryptedMessage' : 'DecryptedMessageLayer'], $message, $constructor, $this->secret_chats[$chat_id]['layer']); + $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 = $this->pack_unsigned_int(strlen($message)).$message; if ($this->secret_chats[$chat_id]['mtproto'] === 2) { $padding = $this->posmod(-strlen($message), 16); diff --git a/src/danog/MadelineProto/SecretChats/ResponseHandler.php b/src/danog/MadelineProto/SecretChats/ResponseHandler.php index 182296e2..43be0178 100644 --- a/src/danog/MadelineProto/SecretChats/ResponseHandler.php +++ b/src/danog/MadelineProto/SecretChats/ResponseHandler.php @@ -24,7 +24,7 @@ namespace danog\MadelineProto\SecretChats; */ trait ResponseHandler { - public function handle_decrypted_update($update) + public function handle_decrypted_update_async($update) { /*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']); @@ -48,7 +48,7 @@ trait ResponseHandler case 'decryptedMessageActionNotifyLayer': $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) { - $this->notify_layer($update['message']['chat_id']); + yield $this->notify_layer_async($update['message']['chat_id']); } if ($update['message']['decrypted_message']['action']['layer'] >= 73) { $this->secret_chats[$update['message']['chat_id']]['mtproto'] = 2; @@ -72,7 +72,7 @@ trait ResponseHandler 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']) { //throw new \danog\MadelineProto\ResponseException(\danog\MadelineProto\Lang::$current_lang['resending_unsupported']); - $this->method_call('messages.sendEncrypted', ['peer' => $update['message']['chat_id'], 'message' => $update['message']['decrypted_message']], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('messages.sendEncrypted', ['peer' => $update['message']['chat_id'], 'message' => $update['message']['decrypted_message']], ['datacenter' => $this->datacenter->curdc]); } } @@ -91,7 +91,7 @@ trait ResponseHandler if ($update['message']['decrypted_message']['layer'] >= 17) { $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) { - $this->notify_layer($update['message']['chat_id']); + yield $this->notify_layer_async($update['message']['chat_id']); } } $update['message']['decrypted_message'] = $update['message']['decrypted_message']['message']; diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php index 348133bb..6862a56f 100644 --- a/src/danog/MadelineProto/Serialization.php +++ b/src/danog/MadelineProto/Serialization.php @@ -58,11 +58,11 @@ class Serialization throw new \danog\MadelineProto\Exception('Empty filename'); } if ($instance->API->asyncInitPromise) { - return $instance->call(static function () use ($filename, $instance, $force) { + return $instance->call((static function () use ($filename, $instance, $force) { yield $instance->API->asyncInitPromise; $instance->API->asyncInitPromise = null; return self::serialize($filename, $instance, $force); - }); + })()); } if (isset($instance->API->setdem) && $instance->API->setdem) { $instance->API->setdem = false; diff --git a/src/danog/MadelineProto/Server/Handler.php b/src/danog/MadelineProto/Server/Handler.php index e9d381db..c3bdff17 100644 --- a/src/danog/MadelineProto/Server/Handler.php +++ b/src/danog/MadelineProto/Server/Handler.php @@ -254,17 +254,17 @@ class Handler extends \danog\MadelineProto\Connection } $exception['trace']['frames'][] = $tl_frame; } - $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageException', 'request_id' => $request_id, 'exception' => $exception], 'exception')); + $this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageException', 'request_id' => $request_id, 'exception' => $exception], 'exception')); } public function send_response($request_id, $response) { - $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageResponse', 'request_id' => $request_id, 'data' => $response], 'exception')); + $this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageResponse', 'request_id' => $request_id, 'data' => $response], 'exception')); } public function send_data($stream_id, $data) { - $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageRawData', 'stream_id' => $stream_id, 'data' => $data], 'data')); + $this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageRawData', 'stream_id' => $stream_id, 'data' => $data], 'data')); } public $logging = false; @@ -277,7 +277,7 @@ class Handler extends \danog\MadelineProto\Connection $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')]; - $this->send_message_safe($this->serialize_object(['type' => ''], $message, 'log')); + $this->send_message_safe(yield $this->serialize_object_async(['type' => ''], $message, 'log')); } finally { $this->logging = false; } @@ -300,11 +300,11 @@ class Handler extends \danog\MadelineProto\Connection public function update_handler($update) { - $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageUpdate', 'data' => $update], 'update')); + $this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageUpdate', 'data' => $update], 'update')); } public function __call($method, $args) { - $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageRequest', 'request_id' => 0, 'method' => [$method], 'args' => $args], 'method')); + $this->send_message_safe(yield $this->serialize_object_async(['type' => ''], ['_' => 'socketMessageRequest', 'request_id' => 0, 'method' => [$method], 'args' => $args], 'method')); } } diff --git a/src/danog/MadelineProto/Stream/MTProtoTools/SaltHandler.php b/src/danog/MadelineProto/Stream/MTProtoTools/SaltHandler.php index e22b7c9d..cc8b160d 100644 --- a/src/danog/MadelineProto/Stream/MTProtoTools/SaltHandler.php +++ b/src/danog/MadelineProto/Stream/MTProtoTools/SaltHandler.php @@ -40,6 +40,6 @@ trait SaltHandler public function handle_future_salts($salt) { - $this->method_call('messages.sendMessage', ['peer' => $salt, 'message' => base64_decode('UG93ZXJlZCBieSBATWFkZWxpbmVQcm90bw==')], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('messages.sendMessage', ['peer' => $salt, 'message' => base64_decode('UG93ZXJlZCBieSBATWFkZWxpbmVQcm90bw==')], ['datacenter' => $this->datacenter->curdc]); } } diff --git a/src/danog/MadelineProto/TL/Conversion/BotAPI.php b/src/danog/MadelineProto/TL/Conversion/BotAPI.php index 15990f85..f2746c41 100644 --- a/src/danog/MadelineProto/TL/Conversion/BotAPI.php +++ b/src/danog/MadelineProto/TL/Conversion/BotAPI.php @@ -155,7 +155,7 @@ trait BotAPI return $markup; } - public function MTProto_to_botAPI($data, $sent_arguments = []) + public function MTProto_to_botAPI_async($data, $sent_arguments = []) { $newd = []; if (!isset($data['_'])) { @@ -370,7 +370,7 @@ trait BotAPI $data['document']['_'] = 'bot_'.$type_name; $res['file_size'] = $data['document']['size']; $res['mime_type'] = $data['document']['mime_type']; - $res['file_id'] = $this->base64url_encode($this->rle_encode($this->serialize_object(['type' => 'File'], $data['document'], 'File').chr(2))); + $res['file_id'] = $this->base64url_encode($this->rle_encode(yield $this->serialize_object_async(['type' => 'File'], $data['document'], 'File').chr(2))); return [$type_name => $res, 'caption' => isset($data['caption']) ? $data['caption'] : '']; default: diff --git a/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php b/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php index a6ee45d6..5c78ac66 100644 --- a/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php +++ b/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php @@ -70,13 +70,13 @@ trait BotAPIFiles return $new; } - public function photosize_to_botapi($photoSize, $photo, $thumbnail = false) + public function photosize_to_botapi_async($photoSize, $photo, $thumbnail = false) { $ext = $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'); $photoSize['location']['access_hash'] = isset($photo['access_hash']) ? $photo['access_hash'] : 0; $photoSize['location']['id'] = isset($photo['id']) ? $photo['id'] : 0; $photoSize['location']['_'] = $thumbnail ? 'bot_thumbnail' : 'bot_photo'; - $data = $this->serialize_object(['type' => 'File'], $photoSize['location'], 'File').chr(2); + $data = yield $this->serialize_object_async(['type' => 'File'], $photoSize['location'], 'File').chr(2); return ['file_id' => $this->base64url_encode($this->rle_encode($data)), 'width' => $photoSize['w'], 'height' => $photoSize['h'], 'file_size' => isset($photoSize['size']) ? $photoSize['size'] : strlen($photoSize['bytes']), 'mime_type' => 'image/jpeg', 'file_name' => $photoSize['location']['volume_id'].'_'.$photoSize['location']['local_id'].$ext]; } diff --git a/src/danog/MadelineProto/TL/Conversion/Extension.php b/src/danog/MadelineProto/TL/Conversion/Extension.php index 8277f8ff..1045ba88 100644 --- a/src/danog/MadelineProto/TL/Conversion/Extension.php +++ b/src/danog/MadelineProto/TL/Conversion/Extension.php @@ -40,10 +40,10 @@ trait Extension return ''; } - public function get_extension_from_location($location, $default) + public function get_extension_from_location_async($location, $default) { return $default; - $res = $this->method_call('upload.getFile', ['location' => $location, 'offset' => 0, 'limit' => 2], ['heavy' => true, 'datacenter' => $location['dc_id']]); + $res = yield $this->method_call_async_read('upload.getFile', ['location' => $location, 'offset' => 0, 'limit' => 2], ['heavy' => true, 'datacenter' => $location['dc_id']]); if (!isset($res['type']['_'])) { return $default; } diff --git a/src/danog/MadelineProto/TL/TL.php b/src/danog/MadelineProto/TL/TL.php index c5ee6f8f..afccfe0c 100644 --- a/src/danog/MadelineProto/TL/TL.php +++ b/src/danog/MadelineProto/TL/TL.php @@ -516,7 +516,7 @@ trait TL return $tl['id'].yield $this->serialize_params($tl, $arguments, $method); } - public function serialize_params($tl, $arguments, $ctx, $layer = -1) + public function serialize_params_async($tl, $arguments, $ctx, $layer = -1) { $serialized = ''; $arguments = $this->botAPI_to_MTProto($arguments); diff --git a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php index d5f4ae52..7def3778 100644 --- a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php +++ b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php @@ -29,7 +29,7 @@ trait AuthKeyHandler { private $calls = []; - public function request_call($user) + public function request_call_async($user) { if (!class_exists('\\danog\\MadelineProto\\VoIP')) { throw new \danog\MadelineProto\Exception(['extension', 'libtgvoip']); @@ -45,7 +45,7 @@ trait AuthKeyHandler } $user = $user['InputUser']; $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['calling_user'], $user['user_id']), \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $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)); $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['generating_g_a'], \danog\MadelineProto\Logger::VERBOSE); @@ -53,7 +53,7 @@ trait AuthKeyHandler $this->check_G($g_a, $dh_config['p']); $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)]; - $res = $this->method_call('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->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]); $controller->setCall($res['phone_call']); $this->calls[$res['phone_call']['id']] = $controller; $this->handle_pending_updates(); @@ -62,7 +62,7 @@ trait AuthKeyHandler return $controller; } - public function accept_call($call) + public function accept_call_async($call) { if (!class_exists('\\danog\\MadelineProto\\VoIP')) { throw new \danog\MadelineProto\Exception(); @@ -78,14 +78,14 @@ trait AuthKeyHandler return false; } $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['accepting_call'], $this->calls[$call['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $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)); $g_b = $dh_config['g']->powMod($b, $dh_config['p']); $this->check_G($g_b, $dh_config['p']); try { - $res = $this->method_call('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->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]); } catch (\danog\MadelineProto\RPCErrorException $e) { if ($e->rpc === 'CALL_ALREADY_ACCEPTED') { $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['call_already_accepted'], $call['id'])); @@ -108,7 +108,7 @@ trait AuthKeyHandler return true; } - public function confirm_call($params) + public function confirm_call_async($params) { if (!class_exists('\\danog\\MadelineProto\\VoIP')) { throw new \danog\MadelineProto\Exception(['extension', 'libtgvoip']); @@ -124,11 +124,11 @@ trait AuthKeyHandler return false; } $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['call_confirming'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); $params['g_b'] = new \phpseclib\Math\BigInteger($params['g_b'], 256); $this->check_G($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); - $res = $this->method_call('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->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']; $visualization = []; $length = new \phpseclib\Math\BigInteger(count(\danog\MadelineProto\Magic::$emojis)); foreach (str_split(hash('sha256', $key.str_pad($this->calls[$params['id']]->storage['g_a'], 256, chr(0), \STR_PAD_LEFT), true), 8) as $number) { @@ -146,7 +146,7 @@ trait AuthKeyHandler return $res; } - public function complete_call($params) + public function complete_call_async($params) { if (!class_exists('\\danog\\MadelineProto\\VoIP')) { throw new \danog\MadelineProto\Exception(['extension', 'libtgvoip']); @@ -162,7 +162,7 @@ trait AuthKeyHandler return false; } $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['call_completing'], $this->calls[$params['id']]->getOtherID()), \danog\MadelineProto\Logger::VERBOSE); - $dh_config = $this->get_dh_config(); + $dh_config = yield $this->get_dh_config_async(); 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']); } @@ -217,7 +217,7 @@ trait AuthKeyHandler return $this->calls[$call]; } - public function discard_call($call, $reason, $rating = [], $need_debug = true) + public function discard_call_async($call, $reason, $rating = [], $need_debug = true) { if (!class_exists('\\danog\\MadelineProto\\VoIP')) { throw new \danog\MadelineProto\Exception(['extension', 'libtgvoip']); @@ -228,7 +228,7 @@ trait AuthKeyHandler $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['call_discarding'], $call['id']), \danog\MadelineProto\Logger::VERBOSE); try { - $res = $this->method_call('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->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]); } catch (\danog\MadelineProto\RPCErrorException $e) { if (!in_array($e->rpc, ['CALL_ALREADY_DECLINED', 'CALL_ALREADY_ACCEPTED'])) { throw $e; @@ -236,11 +236,11 @@ trait AuthKeyHandler } if (!empty($rating)) { $this->logger->logger(sprintf(\danog\MadelineProto\Lang::$current_lang['call_set_rating'], $call['id']), \danog\MadelineProto\Logger::VERBOSE); - $this->method_call('phone.setCallRating', ['peer' => $call, 'rating' => $rating['rating'], 'comment' => $rating['comment']], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('phone.setCallRating', ['peer' => $call, 'rating' => $rating['rating'], 'comment' => $rating['comment']], ['datacenter' => $this->datacenter->curdc]); } 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->method_call('phone.saveCallDebug', ['peer' => $call, 'debug' => $this->calls[$call['id']]->getDebugLog()], ['datacenter' => $this->datacenter->curdc]); + yield $this->method_call_async_read('phone.saveCallDebug', ['peer' => $call, 'debug' => $this->calls[$call['id']]->getDebugLog()], ['datacenter' => $this->datacenter->curdc]); } $update = ['_' => 'updatePhoneCall', 'phone_call' => $this->calls[$call['id']]]; if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict']) { diff --git a/src/danog/MadelineProto/Wrappers/Start.php b/src/danog/MadelineProto/Wrappers/Start.php index 5313ea2b..a6ba7c91 100644 --- a/src/danog/MadelineProto/Wrappers/Start.php +++ b/src/danog/MadelineProto/Wrappers/Start.php @@ -95,7 +95,7 @@ trait Start } } - public function web_phone_login() + public function web_phone_login_async() { try { yield $this->phone_login_async($_POST['phone_number']); @@ -107,7 +107,7 @@ trait Start } } - public function web_complete_phone_login() + public function web_complete_phone_login_async() { try { yield $this->complete_phone_login_async($_POST['phone_code']); @@ -119,7 +119,7 @@ trait Start } } - public function web_complete_2fa_login() + public function web_complete_2fa_login_async() { try { yield $this->complete_2fa_login_async($_POST['password']); @@ -131,7 +131,7 @@ trait Start } } - public function web_complete_signup() + public function web_complete_signup_async() { try { yield $this->complete_signup_async($_POST['first_name'], isset($_POST['last_name']) ? $_POST['last_name'] : ''); @@ -143,7 +143,7 @@ trait Start } } - public function web_bot_login() + public function web_bot_login_async() { try { yield $this->bot_login_async($_POST['token']); diff --git a/src/danog/MadelineProto/Wrappers/TOS.php b/src/danog/MadelineProto/Wrappers/TOS.php index b1293dcd..bc102645 100644 --- a/src/danog/MadelineProto/Wrappers/TOS.php +++ b/src/danog/MadelineProto/Wrappers/TOS.php @@ -24,12 +24,12 @@ namespace danog\MadelineProto\Wrappers; */ trait TOS { - public function check_tos() + public function check_tos_async() { if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot']) { if ($this->tos['expires'] < time()) { $this->logger->logger('Fetching TOS...'); - $this->tos = $this->method_call('help.getTermsOfServiceUpdate', [], ['datacenter' => $this->datacenter->curdc]); + $this->tos = yield $this->method_call_async_read('help.getTermsOfServiceUpdate', [], ['datacenter' => $this->datacenter->curdc]); $this->tos['accepted'] = $this->tos['_'] === 'help.termsOfServiceUpdateEmpty'; } @@ -46,9 +46,9 @@ trait TOS } } - public function accept_tos() + public function accept_tos_async() { - $this->tos['accepted'] = $this->method_call('help.acceptTermsOfService', ['id' => $this->tos['terms_of_service']['id']], ['datacenter' => $this->datacenter->curdc]); + $this->tos['accepted'] = yield $this->method_call_async_read('help.acceptTermsOfService', ['id' => $this->tos['terms_of_service']['id']], ['datacenter' => $this->datacenter->curdc]); if ($this->tos['accepted']) { $this->logger->logger('TOS accepted successfully'); } else { @@ -56,9 +56,9 @@ trait TOS } } - public function decline_tos() + public function decline_tos_async() { - $this->method_call('account.deleteAccount', ['reason' => 'Decline ToS update'], ['datacenter' => $this->datacenter->curdc]); - $this->logout(); + yield $this->method_call_async_read('account.deleteAccount', ['reason' => 'Decline ToS update'], ['datacenter' => $this->datacenter->curdc]); + yield $this->logout_async(); } }