mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 09:58:59 +01:00
Async constructor
This commit is contained in:
parent
2e4be09279
commit
406a2d8aad
2
docs
2
docs
@ -1 +1 @@
|
||||
Subproject commit 0fcff8e5a31af300511949c4dbafc7be6c0d4dd7
|
||||
Subproject commit 6d9ffce34a50e6400dba4a516c78062e5dc2f346
|
@ -62,14 +62,17 @@ class API extends APIFactory
|
||||
class_exists('\\Volatile');
|
||||
$tounserialize = str_replace('O:26:"danog\\MadelineProto\\Button":', 'O:35:"danog\\MadelineProto\\TL\\Types\\Button":', $tounserialize);
|
||||
foreach (['RSA', 'TL\\TLMethod', 'TL\\TLConstructor', 'MTProto', 'API', 'DataCenter', 'Connection', 'TL\\Types\\Button', 'TL\\Types\\Bytes', 'APIFactory'] as $class) {
|
||||
class_exists('\\danog\\MadelineProto\\'.$class);
|
||||
class_exists('\\danog\\MadelineProto\\' . $class);
|
||||
}
|
||||
$unserialized = \danog\Serialization::unserialize($tounserialize);
|
||||
} catch (\danog\MadelineProto\Exception $e) {
|
||||
if ($e->getFile() === 'MadelineProto' && $e->getLine() === 1) {
|
||||
throw $e;
|
||||
}
|
||||
class_exists('\\Volatile');
|
||||
$tounserialize = str_replace('O:26:"danog\\MadelineProto\\Button":', 'O:35:"danog\\MadelineProto\\TL\\Types\\Button":', $tounserialize);
|
||||
foreach (['RSA', 'TL\\TLMethod', 'TL\\TLConstructor', 'MTProto', 'API', 'DataCenter', 'Connection', 'TL\\Types\\Button', 'TL\\Types\\Bytes', 'APIFactory'] as $class) {
|
||||
class_exists('\\danog\\MadelineProto\\'.$class);
|
||||
class_exists('\\danog\\MadelineProto\\' . $class);
|
||||
}
|
||||
Logger::log((string) $e, Logger::ERROR);
|
||||
if (strpos($e->getMessage(), "Erroneous data format for unserializing 'phpseclib\\Math\\BigInteger'") === 0) {
|
||||
@ -89,6 +92,15 @@ class API extends APIFactory
|
||||
|
||||
if (isset($unserialized->API)) {
|
||||
$this->API = $unserialized->API;
|
||||
$promise = $this->call(function () {
|
||||
yield $this->API->asyncInitPromise;
|
||||
$this->API->asyncInitPromise = null;
|
||||
$this->APIFactory();
|
||||
\danog\MadelineProto\Logger::log('Ping...', Logger::ULTRA_VERBOSE);
|
||||
$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;
|
||||
@ -103,11 +115,16 @@ 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 () {
|
||||
yield $this->API->asyncInitPromise;
|
||||
$this->API->asyncInitPromise = null;
|
||||
$this->APIFactory();
|
||||
\danog\MadelineProto\Logger::log('Ping...', Logger::ULTRA_VERBOSE);
|
||||
$pong = $this->ping(['ping_id' => 3]);
|
||||
\danog\MadelineProto\Logger::log('Pong: '.$pong['ping_id'], Logger::ULTRA_VERBOSE);
|
||||
$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();
|
||||
}
|
||||
|
||||
public function async($async)
|
||||
@ -156,6 +173,10 @@ class API extends APIFactory
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if ($name === 'settings') {
|
||||
if ($this->API->phoneConfigWatcherId) {
|
||||
$this->wait($this->API->phoneConfigWatcherId);
|
||||
$this->API->phoneConfigWatcherId = null;
|
||||
}
|
||||
if (Magic::is_fork() && !Magic::$processed_fork) {
|
||||
\danog\MadelineProto\Logger::log('Detected fork');
|
||||
$this->API->reset_session();
|
||||
|
@ -124,7 +124,7 @@ class APIFactory
|
||||
|
||||
public function __construct($namespace, $API)
|
||||
{
|
||||
$this->namespace = $namespace.'.';
|
||||
$this->namespace = $namespace . '.';
|
||||
$this->API = $API;
|
||||
}
|
||||
|
||||
@ -143,23 +143,24 @@ class APIFactory
|
||||
$this->API->setdem = false;
|
||||
$this->API->__construct($this->API->settings);
|
||||
}
|
||||
$this->API->get_config([], ['datacenter' => $this->API->datacenter->curdc]);
|
||||
//$this->API->get_config([], ['datacenter' => $this->API->datacenter->curdc]);
|
||||
|
||||
if (isset($this->session) && !is_null($this->session) && time() - $this->serialized > $this->API->settings['serialization']['serialization_interval']) {
|
||||
Logger::log("Didn't serialize in a while, doing that now...");
|
||||
$this->serialize($this->session);
|
||||
}
|
||||
/*
|
||||
if ($name !== 'accept_tos' && $name !== 'decline_tos') {
|
||||
$this->API->check_tos();
|
||||
}
|
||||
}*/
|
||||
$lower_name = strtolower($name);
|
||||
|
||||
if ($this->lua === false) {
|
||||
return $this->namespace !== '' || !isset($this->methods[$lower_name]) ? $this->__mtproto_call($this->namespace.$name, $arguments) : $this->__api_call($lower_name, $arguments);
|
||||
return $this->namespace !== '' || !isset($this->methods[$lower_name]) ? $this->__mtproto_call($this->namespace . $name, $arguments) : $this->__api_call($lower_name, $arguments);
|
||||
}
|
||||
|
||||
try {
|
||||
$deserialized = $this->namespace !== '' || !isset($this->methods[$lower_name]) ? $this->__mtproto_call($this->namespace.$name, $arguments) : $this->__api_call($lower_name, $arguments);
|
||||
$deserialized = $this->namespace !== '' || !isset($this->methods[$lower_name]) ? $this->__mtproto_call($this->namespace . $name, $arguments) : $this->__api_call($lower_name, $arguments);
|
||||
|
||||
Lua::convert_objects($deserialized);
|
||||
|
||||
@ -183,10 +184,23 @@ class APIFactory
|
||||
|
||||
public function __api_call($name, $arguments)
|
||||
{
|
||||
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) {
|
||||
yield $this->API->asyncInitPromise;
|
||||
$this->API->asyncInitPromise = null;
|
||||
return yield $this->methods[$name](...$arguments);
|
||||
});
|
||||
} else {
|
||||
$this->wait($this->API->asyncInitPromise);
|
||||
$this->API->asyncInitPromise = null;
|
||||
}
|
||||
}
|
||||
$result = $this->methods[$name](...$arguments);
|
||||
if (is_object($result) && ($result instanceof \Generator || $result instanceof Promise)) {
|
||||
$async = is_array(end($arguments)) && isset(end($arguments)['async']) ? end($arguments)['async'] : $this->async;
|
||||
if ($async && ($name !== 'loop' || isset(end($arguments)['async']))) {
|
||||
$async = is_array(end($arguments)) && isset(end($arguments)['async']) ? end($arguments)['async'] : ($this->async && $name !== 'loop');
|
||||
if ($async) {
|
||||
return $result;
|
||||
} else {
|
||||
return $this->wait($result);
|
||||
@ -204,6 +218,20 @@ class APIFactory
|
||||
$args = isset($arguments[0]) && is_array($arguments[0]) ? $arguments[0] : [];
|
||||
|
||||
$async = isset(end($arguments)['async']) ? end($arguments)['async'] : $this->async;
|
||||
|
||||
if ($this->API->asyncInitPromise) {
|
||||
if ($async) {
|
||||
return $this->call(function () use ($name, $args, $aargs) {
|
||||
yield $this->API->asyncInitPromise;
|
||||
$this->API->asyncInitPromise = null;
|
||||
return yield $this->API->method_call_async_read($name, $args, $aargs);
|
||||
;
|
||||
});
|
||||
} else {
|
||||
$this->wait($this->API->asyncInitPromise);
|
||||
$this->API->asyncInitPromise = null;
|
||||
}
|
||||
}
|
||||
$res = $this->API->method_call_async_read($name, $args, $aargs);
|
||||
|
||||
if ($async) {
|
||||
|
@ -137,7 +137,6 @@ class MTProto implements TLCallback
|
||||
private $msg_ids = [];
|
||||
private $v = 0;
|
||||
private $dialog_params = ['_' => 'MadelineProto.dialogParams', 'limit' => 0, 'offset_date' => 0, 'offset_id' => 0, 'offset_peer' => ['_' => 'inputPeerEmpty'], 'count' => 0];
|
||||
private $ipv6 = false;
|
||||
public $run_workers = false;
|
||||
public $setdem = false;
|
||||
public $storage = [];
|
||||
@ -148,7 +147,14 @@ class MTProto implements TLCallback
|
||||
public $update_deferred;
|
||||
public $phoneConfigWatcherId;
|
||||
|
||||
public $asyncInitPromise;
|
||||
|
||||
public function __magic_construct($settings = [])
|
||||
{
|
||||
$this->asyncInitPromise = $this->call($this->__async_construct($settings));
|
||||
}
|
||||
|
||||
public function __async_construct($settings = [])
|
||||
{
|
||||
\danog\MadelineProto\Magic::class_exists();
|
||||
// Parse settings
|
||||
@ -185,11 +191,11 @@ class MTProto implements TLCallback
|
||||
*/
|
||||
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['TL_translation'], Logger::ULTRA_VERBOSE);
|
||||
$this->construct_TL($this->settings['tl_schema']['src'], [$this, $this->referenceDatabase]);
|
||||
$this->connect_to_all_dcs();
|
||||
yield $this->connect_to_all_dcs_async();
|
||||
$this->datacenter->curdc = 2;
|
||||
if ((!isset($this->authorization['user']['bot']) || !$this->authorization['user']['bot']) && $this->datacenter->sockets[$this->datacenter->curdc]->temp_auth_key !== null) {
|
||||
try {
|
||||
$nearest_dc = $this->method_call('help.getNearestDc', [], ['datacenter' => $this->datacenter->curdc]);
|
||||
$nearest_dc = yield $this->method_call_async_read('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);
|
||||
if ($nearest_dc['nearest_dc'] != $nearest_dc['this_dc']) {
|
||||
$this->settings['connection_settings']['default_dc'] = $this->datacenter->curdc = (int) $nearest_dc['nearest_dc'];
|
||||
@ -200,10 +206,9 @@ class MTProto implements TLCallback
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->get_config([], ['datacenter' => $this->datacenter->curdc]);
|
||||
yield $this->get_config_async([], ['datacenter' => $this->datacenter->curdc]);
|
||||
$this->v = self::V;
|
||||
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
@ -222,6 +227,10 @@ class MTProto implements TLCallback
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->asyncInitPromise = $this->call($this->__async_wakeup());
|
||||
}
|
||||
public function __async_wakeup()
|
||||
{
|
||||
set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
|
||||
set_exception_handler(['\\danog\\MadelineProto\\Serialization', 'serialize_all']);
|
||||
@ -356,12 +365,12 @@ class MTProto implements TLCallback
|
||||
$this->reset_session(true, true);
|
||||
$this->config = ['expires' => -1];
|
||||
$this->dh_config = ['version' => 0];
|
||||
$this->__construct($settings);
|
||||
yield $this->__async_construct($settings);
|
||||
$force = true;
|
||||
foreach ($this->secret_chats as $chat => $data) {
|
||||
try {
|
||||
if (isset($this->secret_chats[$chat]) && $this->secret_chats[$chat]['InputEncryptedChat'] !== null) {
|
||||
$this->notify_layer($chat);
|
||||
yield $this->notify_layer_async($chat);
|
||||
}
|
||||
} catch (\danog\MadelineProto\RPCErrorException $e) {
|
||||
}
|
||||
@ -372,7 +381,7 @@ class MTProto implements TLCallback
|
||||
$this->channels_state = [];
|
||||
$this->got_state = false;
|
||||
}
|
||||
$this->connect_to_all_dcs();
|
||||
yield $this->connect_to_all_dcs_async();
|
||||
foreach ($this->calls as $id => $controller) {
|
||||
if (!is_object($controller)) {
|
||||
unset($this->calls[$id]);
|
||||
@ -383,15 +392,15 @@ class MTProto implements TLCallback
|
||||
$controller->setMadeline($this);
|
||||
}
|
||||
}
|
||||
if ($this->get_self()) {
|
||||
if (yield $this->get_self_async()) {
|
||||
$this->authorized = self::LOGGED_IN;
|
||||
}
|
||||
if ($this->authorized === self::LOGGED_IN) {
|
||||
$this->get_cdn_config($this->datacenter->curdc);
|
||||
yield $this->get_cdn_config_async($this->datacenter->curdc);
|
||||
$this->setup_logger();
|
||||
}
|
||||
if ($this->authorized === self::LOGGED_IN && !$this->authorization['user']['bot'] && $this->settings['peer']['cache_all_peers_on_startup']) {
|
||||
$this->get_dialogs($force);
|
||||
yield $this->get_dialogs_async($force);
|
||||
}
|
||||
if ($this->authorized === self::LOGGED_IN && $this->settings['updates']['handle_updates'] && !$this->updates_state['sync_loading']) {
|
||||
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['getupdates_deserialization'], Logger::NOTICE);
|
||||
@ -709,7 +718,7 @@ class MTProto implements TLCallback
|
||||
if (!is_array($settings)) {
|
||||
$settings = [];
|
||||
}
|
||||
$settings = array_replace_recursive($this->array_cast_recursive($default_settings, true), $this->array_cast_recursive($settings, true));
|
||||
$settings = array_replace_recursive($default_settings, $settings);
|
||||
if (isset(Lang::$lang[$settings['app_info']['lang_code']])) {
|
||||
Lang::$current_lang = &Lang::$lang[$settings['app_info']['lang_code']];
|
||||
}
|
||||
@ -816,11 +825,6 @@ class MTProto implements TLCallback
|
||||
}
|
||||
|
||||
// Connects to all datacenters and if necessary creates authorization keys, binds them and writes client info
|
||||
public function connect_to_all_dcs()
|
||||
{
|
||||
return $this->wait($this->connect_to_all_dcs_async());
|
||||
}
|
||||
|
||||
public function connect_to_all_dcs_async(): \Generator
|
||||
{
|
||||
$this->datacenter->__construct($this, $this->settings['connection'], $this->settings['connection_settings']);
|
||||
@ -836,7 +840,10 @@ class MTProto implements TLCallback
|
||||
}
|
||||
yield $dcs;
|
||||
yield $this->init_authorization_async();
|
||||
if (!$this->phoneConfigWatcherId) $this->phoneConfigWatcherId = Loop::repeat(24 * 3600 * 1000, [$this, 'get_phone_config_async']);
|
||||
if (!$this->phoneConfigWatcherId) {
|
||||
$this->phoneConfigWatcherId = Loop::repeat(24 * 3600 * 1000, [$this, 'get_phone_config_async']);
|
||||
}
|
||||
|
||||
yield $this->get_phone_config_async();
|
||||
$this->logger->logger("Started phone config fetcher");
|
||||
}
|
||||
@ -868,13 +875,17 @@ class MTProto implements TLCallback
|
||||
}
|
||||
|
||||
public function get_cdn_config($datacenter)
|
||||
{
|
||||
return $this->wait($this->get_cdn_config_async($datacenter));
|
||||
}
|
||||
public function get_cdn_config_async($datacenter)
|
||||
{
|
||||
/*
|
||||
* ***********************************************************************
|
||||
* Fetch RSA keys for CDN datacenters
|
||||
*/
|
||||
try {
|
||||
foreach ($this->method_call('help.getCdnConfig', [], ['datacenter' => $datacenter])['public_keys'] as $curkey) {
|
||||
foreach ((yield $this->method_call_async_read('help.getCdnConfig', [], ['datacenter' => $datacenter]))['public_keys'] as $curkey) {
|
||||
$tempkey = new \danog\MadelineProto\RSA($curkey['public_key']);
|
||||
$this->rsa_keys[$tempkey->fp] = $tempkey;
|
||||
}
|
||||
|
@ -110,7 +110,11 @@ trait AuthKeyHandler
|
||||
|
||||
public function notify_layer($chat)
|
||||
{
|
||||
$this->method_call('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->encrypted_layer]]], ['datacenter' => $this->datacenter->curdc]);
|
||||
return $this->wait($this->notify_layer_async($chat));
|
||||
}
|
||||
public function notify_layer_async($chat)
|
||||
{
|
||||
yield $this->method_call_async_read('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->encrypted_layer]]], ['datacenter' => $this->datacenter->curdc]);
|
||||
}
|
||||
|
||||
protected $temp_rekeyed_secret_chats = [];
|
||||
|
1319
src/danog/MadelineProto/TL_telegram_v98.tl
Normal file
1319
src/danog/MadelineProto/TL_telegram_v98.tl
Normal file
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,7 @@ trait Events
|
||||
$this->settings['updates']['handle_updates'] = true;
|
||||
$this->settings['updates']['run_callback'] = true;
|
||||
|
||||
if (isset($this->datacenter->sockets[$this->settings['connection_settings']['default_dc']]->updater)) {
|
||||
if (isset($this->datacenter->sockets[$this->settings['connection_settings']['default_dc']]->updater) && !$this->asyncInitPromise) {
|
||||
$this->datacenter->sockets[$this->settings['connection_settings']['default_dc']]->updater->start();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user