diff --git a/docs b/docs index fe346258..04490a66 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit fe346258733323e5173e674f15059dea1a1eb880 +Subproject commit 04490a66c7c0389d47981f3c78a8e6015de2bce2 diff --git a/src/danog/MadelineProto/DataCenter.php b/src/danog/MadelineProto/DataCenter.php index 3d018183..c712052a 100644 --- a/src/danog/MadelineProto/DataCenter.php +++ b/src/danog/MadelineProto/DataCenter.php @@ -181,49 +181,80 @@ class DataCenter } } } - public function __magic_construct($API, $dclist, $settings, CookieJar $jar = null) + /** + * Constructor function. + * + * @param MTProto $API Main MTProto instance + * @param array $dclist DC IP list + * @param array $settings Settings + * @param boolean $reconnectAll Whether to reconnect to all DCs or just to changed ones + * @param CookieJar $jar Cookie jar + * + * @return void + */ + public function __magic_construct(MTProto $API, array $dclist, array $settings, bool $reconnectAll = true, CookieJar $jar = null) { $this->API = $API; + + $changed = []; + $changedSettings = $this->settings !== $settings; + if (!$reconnectAll) { + $changed = []; + $test = ($API->get_cached_config()['test_mode'] ?? false) ? 'test' : 'main'; + foreach ($dclist[$test] as $ipv6 => $dcs) { + foreach ($dcs as $id => $dc) { + if ($dc !== ($this->dclist[$test][$ipv6][$id] ?? [])) { + $changed[$id] = true; + } + } + } + } + $this->dclist = $dclist; $this->settings = $settings; foreach ($this->sockets as $key => $socket) { if ($socket instanceof DataCenterConnection && !\strpos($key, '_bk')) { //$this->API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_stop'], $key), \danog\MadelineProto\Logger::VERBOSE); - $socket->needReconnect(true); - $socket->setExtra($this->API); - $socket->disconnect(); + if ($reconnectAll || isset($changed[$id])) { + $socket->needReconnect(true); + $socket->setExtra($this->API); + $socket->disconnect(); + } } else { unset($this->sockets[$key]); } } - $this->CookieJar = $jar ?? new ArrayCookieJar; - $this->HTTPClient = new DefaultClient($this->CookieJar, new HttpSocketPool(new ProxySocketPool([$this, 'rawConnectAsync']))); - $DoHHTTPClient = new DefaultClient( - $this->CookieJar, - new HttpSocketPool( + if ($reconnectAll || $changedSettings || !$this->CookieJar) { + $this->CookieJar = $jar ?? new ArrayCookieJar; + $this->HTTPClient = new DefaultClient($this->CookieJar, new HttpSocketPool(new ProxySocketPool([$this, 'rawConnectAsync']))); + + $DoHHTTPClient = new DefaultClient( + $this->CookieJar, + new HttpSocketPool( new ProxySocketPool( function (string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null) { return $this->rawConnectAsync($uri, $token, $ctx, true); } ) ) - ); - $DoHConfig = new DoHConfig( - [ + ); + $DoHConfig = new DoHConfig( + [ new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'), new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]), ], - $DoHHTTPClient - ); - $NonProxiedDoHConfig = new DoHConfig( - [ + $DoHHTTPClient + ); + $NonProxiedDoHConfig = new DoHConfig( + [ new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'), new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]), ] - ); - $this->DoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($DoHConfig); - $this->NonProxiedDoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($NonProxiedDoHConfig); + ); + $this->DoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($DoHConfig); + $this->NonProxiedDoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($NonProxiedDoHConfig); + } } /** @@ -500,6 +531,7 @@ class DataCenter ($id !== -1 && $this->sockets[$dc_number]->hasConnection($id) && $this->sockets[$dc_number]->getConnection($id)->shouldReconnect()) ); if (isset($this->sockets[$dc_number]) && !$old) { + $this->API->logger("Not reconnecting to DC $dc_number ($id)"); return false; } $ctxs = $this->generateContexts($dc_number); @@ -916,12 +948,13 @@ class DataCenter } /** - * Get all DCs. + * Get all DC IDs. * - * @param boolean $all - * @return void + * @param boolean $all Whether to get all possible DC IDs, or only connected ones + * + * @return array */ - public function get_dcs($all = true) + public function get_dcs($all = true): array { $test = $this->settings['all']['test_mode'] ? 'test' : 'main'; $ipv6 = $this->settings['all']['ipv6'] ? 'ipv6' : 'ipv4'; diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 4749c846..d300ba24 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -1227,7 +1227,7 @@ class MTProto extends AsyncConstruct implements TLCallback } // Connects to all datacenters and if necessary creates authorization keys, binds them and writes client info - public function connect_to_all_dcs_async(): \Generator + public function connect_to_all_dcs_async(bool $reconnectAll = true): \Generator { $this->channels_state->get(false); foreach ($this->channels_state->get() as $state) { @@ -1243,7 +1243,7 @@ class MTProto extends AsyncConstruct implements TLCallback $this->seqUpdater = new SeqLoop($this); } - $this->datacenter->__construct($this, $this->settings['connection'], $this->settings['connection_settings']); + $this->datacenter->__construct($this, $this->settings['connection'], $this->settings['connection_settings'], $reconnectAll); $dcs = []; foreach ($this->datacenter->get_dcs() as $new_dc) { $dcs[] = $this->datacenter->dcConnectAsync($new_dc); @@ -1395,6 +1395,11 @@ class MTProto extends AsyncConstruct implements TLCallback } } + public function get_cached_config() + { + return $this->config; + } + public function get_config_async($config = [], $options = []) { if ($this->config['expires'] > \time()) { @@ -1409,8 +1414,9 @@ class MTProto extends AsyncConstruct implements TLCallback public function parse_config_async() { if (isset($this->config['dc_options'])) { - yield $this->parse_dc_options_async($this->config['dc_options']); + $options = $this->config['dc_options']; unset($this->config['dc_options']); + yield $this->parse_dc_options_async($options); } $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['config_updated'], Logger::NOTICE); $this->logger->logger($this->config, Logger::NOTICE); @@ -1418,7 +1424,6 @@ class MTProto extends AsyncConstruct implements TLCallback public function parse_dc_options_async($dc_options) { - $changed = []; foreach ($dc_options as $dc) { $test = $this->config['test_mode'] ? 'test' : 'main'; $id = $dc['id']; @@ -1436,34 +1441,12 @@ class MTProto extends AsyncConstruct implements TLCallback } unset($dc['cdn'], $dc['media_only'], $dc['id'], $dc['ipv6']); - if ($dc !== ($this->settings['connection'][$test][$ipv6][$id] ?? [])) { - $changed[$id] = true; - } $this->settings['connection'][$test][$ipv6][$id] = $dc; } $curdc = $this->datacenter->curdc; - if ($changed) { + if (!$this->datacenter->has($curdc) || $this->datacenter->getDataCenterConnection($curdc)->byIPAddress()) { $this->logger->logger('Got new DC options, reconnecting'); - foreach ($this->datacenter->sockets as $key => $socket) { - if ($socket instanceof DataCenterConnection && isset($changed[$key]) && $socket->byIPAddress()) { - //$this->API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_stop'], $key), \danog\MadelineProto\Logger::VERBOSE); - $socket->shouldReconnect(true); - $socket->disconnect(); - unset($changed[$key]); - } - } - $dcs = []; - foreach ($this->datacenter->get_dcs() as $new_dc) { - $dcs[] = $this->datacenter->dcConnectAsync($new_dc); - } - yield $this->all($dcs); - yield $this->init_authorization_async(); - $dcs = []; - foreach ($this->datacenter->get_dcs(false) as $new_dc) { - $dcs[] = $this->datacenter->dcConnectAsync($new_dc); - } - yield $this->all($dcs); - yield $this->init_authorization_async(); + yield $this->connect_to_all_dcs_async(false); } $this->datacenter->curdc = $curdc; } diff --git a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php index b58455ad..d2002e13 100644 --- a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php @@ -639,6 +639,7 @@ trait AuthKeyHandler $this->logger("Pending auth, not initing auth"); return; } + $this->logger("Initing authorization..."); $initing = $this->initing_authorization; $this->initing_authorization = true; @@ -696,6 +697,7 @@ trait AuthKeyHandler */ public function init_authorization_socket_async(string $id, DataCenterConnection $socket): \Generator { + $this->logger("Initing authorization DC $id..."); $this->init_auth_dcs[$id] = true; $connection = $socket->getAuthConnection(); @@ -749,6 +751,7 @@ trait AuthKeyHandler yield $this->sync_authorization_async($id); } } finally { + $this->logger("Done initing authorization DC $id"); unset($this->init_auth_dcs[$id]); } } diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index a9631d77..081aaab0 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -833,6 +833,9 @@ trait PeerHandler if (isset($participant['date'])) { $newres['date'] = $participant['date']; } + if (isset($participant['rank'])) { + $newres['rank'] = $participant['rank']; + } switch ($participant['_']) { case 'channelParticipantSelf': $newres['role'] = 'user';