MadelineProto/src/danog/MadelineProto/API.php

414 lines
12 KiB
PHP
Raw Normal View History

2016-08-07 23:23:10 +02:00
<?php
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
/**
* API module.
*
* This file is part of MadelineProto.
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU General Public License along with MadelineProto.
* If not, see <http://www.gnu.org/licenses/>.
*
* @author Daniil Gentili <daniil@daniil.it>
2020-02-17 14:13:46 +01:00
* @copyright 2016-2020 Daniil Gentili <daniil@daniil.it>
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
* @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
*
2019-10-31 15:07:35 +01:00
* @link https://docs.madelineproto.xyz MadelineProto documentation
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
*/
2018-02-25 17:50:03 +01:00
2016-08-07 23:23:10 +02:00
namespace danog\MadelineProto;
2016-08-08 18:10:28 +02:00
2020-09-22 23:10:56 +02:00
use Amp\Ipc\Sync\ChannelledSocket;
use danog\MadelineProto\Ipc\Client;
2020-09-24 11:45:20 +02:00
use danog\MadelineProto\Ipc\Server;
use danog\MadelineProto\Settings\Logger as SettingsLogger;
2020-09-24 11:45:20 +02:00
use danog\MadelineProto\Settings\Serialization as SettingsSerialization;
2020-02-26 14:14:26 +01:00
2019-12-28 17:34:04 +01:00
/**
* Main API wrapper for MadelineProto.
*/
2019-09-18 20:46:20 +02:00
class API extends InternalDoc
2016-08-07 23:23:30 +02:00
{
use \danog\Serializable;
use \danog\MadelineProto\ApiWrappers\Start;
use \danog\MadelineProto\ApiWrappers\Templates;
/**
* Session paths.
*
* @internal
*/
public SessionPaths $session;
2019-09-14 14:21:11 +02:00
/**
2019-09-14 15:39:42 +02:00
* Instance of MadelineProto.
2019-09-14 14:21:11 +02:00
*
2020-09-22 23:10:56 +02:00
* @var null|MTProto|Client
2019-09-14 14:21:11 +02:00
*/
2018-03-11 18:36:32 +01:00
public $API;
/**
* Storage for externally set properties to be serialized.
*
* @var array
*/
protected array $storage = [];
2019-12-28 17:34:04 +01:00
/**
* Whether we're getting our API ID.
*
* @internal
*
* @var boolean
*/
private bool $gettingApiId = false;
2019-12-28 17:34:04 +01:00
/**
* my.telegram.org API wrapper.
*
* @internal
*
2020-04-25 19:36:15 +02:00
* @var null|MyTelegramOrgWrapper
2019-12-28 17:34:04 +01:00
*/
private $myTelegramOrgWrapper;
2019-12-28 17:34:04 +01:00
/**
* Whether this is an old instance.
2019-12-28 17:34:04 +01:00
*
* @var boolean
2019-12-28 17:34:04 +01:00
*/
private bool $oldInstance = false;
/**
* Whether we're destructing.
*
* @var boolean
*/
private bool $destructing = false;
/**
* API wrapper (to avoid circular references).
*
* @var APIWrapper
*/
private $wrapper;
2019-12-28 17:34:04 +01:00
/**
* Magic constructor function.
*
* @param string $session Session name
* @param array|Settings $settings Settings
2019-12-28 17:34:04 +01:00
*
* @return void
*/
public function __magic_construct(string $session, $settings = []): void
2016-08-07 23:23:30 +02:00
{
2020-09-22 23:10:56 +02:00
Magic::classExists(true);
$settings = Settings::parseFromLegacy($settings);
$this->session = new SessionPaths($session);
$this->wrapper = new APIWrapper($this, $this->exportNamespace());
$this->setInitPromise($this->internalInitAPI($settings));
foreach (\get_class_vars(APIFactory::class) as $key => $var) {
if (\in_array($key, ['namespace', 'API', 'lua', 'async', 'asyncAPIPromise', 'methods'])) {
2019-06-08 13:29:54 +02:00
continue;
}
if (!$this->{$key}) {
$this->{$key} = $this->exportNamespace($key);
2019-06-08 13:29:54 +02:00
}
}
}
2019-12-28 17:34:04 +01:00
/**
* Async constructor function.
*
2020-09-24 11:45:20 +02:00
* @param Settings|SettingsEmpty|SettingsSerialization $settings Settings
2019-12-28 17:34:04 +01:00
*
* @return \Generator
*/
private function internalInitAPI(SettingsAbstract $settings): \Generator
{
2020-09-24 11:45:20 +02:00
Logger::constructorFromSettings($settings instanceof Settings
? $settings->getLogger()
: new SettingsLogger);
if (yield from $this->connectToMadelineProto($settings)) {
return; // OK
}
if (!$settings instanceof Settings) {
$settings = new Settings;
}
$appInfo = $settings->getAppInfo();
if (!$appInfo->hasApiInfo()) {
$app = yield from $this->APIStart($settings);
if (!$app) {
$this->forceInit(true);
die();
}
$appInfo->setApiId($app['api_id']);
$appInfo->setApiHash($app['api_hash']);
}
$this->API = new MTProto($settings, $this->wrapper);
yield from $this->API->initAsynchronously();
$this->APIFactory();
$this->logger->logger(Lang::$current_lang['madelineproto_ready'], Logger::NOTICE);
}
/**
* Connect to MadelineProto.
*
* @param Settings|SettingsEmpty $settings Settings
* @param bool $forceFull Whether to force full initialization
*
* @return \Generator
*/
protected function connectToMadelineProto(SettingsAbstract $settings, bool $forceFull = false): \Generator
{
if ($settings instanceof SettingsSerialization) {
$forceFull = $forceFull || $settings->getForceFull();
} elseif ($settings instanceof Settings) {
$forceFull = $forceFull || $settings->getSerialization()->getForceFull();
}
2020-09-22 23:10:56 +02:00
[$unserialized, $this->unlock] = yield Tools::timeoutWithDefault(
2020-09-24 11:45:20 +02:00
Serialization::unserialize($this->session, $forceFull),
2020-09-22 23:10:56 +02:00
30000,
2020-09-24 11:45:20 +02:00
[0, null]
2020-09-22 23:10:56 +02:00
);
2020-09-24 11:45:20 +02:00
if ($unserialized === 0) {
// Timeout
throw new \RuntimeException("Could not connect to MadelineProto, please check the logs for more details.");
} elseif ($unserialized instanceof \Throwable) {
// IPC server error, try fetching full session
return yield from $this->connectToMadelineProto($settings, true);
} elseif ($unserialized instanceof ChannelledSocket) {
// Success, IPC client
2020-09-22 23:10:56 +02:00
$this->API = new Client($unserialized, Logger::$default);
$this->APIFactory();
2020-09-24 11:45:20 +02:00
return true;
2020-09-22 23:10:56 +02:00
} elseif ($unserialized) {
2020-09-24 11:45:20 +02:00
// Success, full session
$unserialized->storage = $unserialized->storage ?? [];
$unserialized->session = $this->session;
APIWrapper::link($this, $unserialized);
APIWrapper::link($this->wrapper, $this);
2020-02-28 16:02:19 +01:00
AbstractAPIFactory::link($this->wrapper->getFactory(), $this);
if (isset($this->API)) {
$this->storage = $this->API->storage ?? $this->storage;
unset($unserialized);
2020-02-26 11:47:30 +01:00
2020-09-24 11:45:20 +02:00
if ($settings instanceof SettingsSerialization) {
$settings = new SettingsEmpty;
}
yield from $this->API->wakeup($settings, $this->wrapper);
$this->APIFactory();
$this->logger->logger(Lang::$current_lang['madelineproto_ready'], Logger::NOTICE);
2020-09-24 11:45:20 +02:00
return true;
2017-11-08 13:04:40 +01:00
}
}
2020-09-24 11:45:20 +02:00
return false;
}
2020-03-07 21:45:50 +01:00
/**
* Wakeup function.
*
* @return void
*/
public function __wakeup(): void
{
$this->oldInstance = true;
}
2019-12-28 17:34:04 +01:00
/**
* Destruct function.
*
* @internal
*/
2017-04-21 13:14:21 +02:00
public function __destruct()
{
$this->init();
2019-06-13 14:43:30 +02:00
if (!$this->oldInstance) {
2020-07-12 14:55:21 +02:00
$this->logger->logger('Shutting down MadelineProto ('.static::class.')');
2019-06-08 21:01:57 +02:00
if ($this->API) {
$this->API->destructing = true;
2020-02-26 19:17:46 +01:00
$this->API->unreference();
2019-06-08 21:01:57 +02:00
}
$this->destructing = true;
2020-07-11 20:01:54 +02:00
if (isset($this->wrapper)) {
Tools::wait($this->wrapper->serialize());
}
if ($this->unlock) {
($this->unlock)();
}
} else {
2020-02-26 15:59:34 +01:00
$this->logger->logger('Shutting down MadelineProto (old deserialized instance of API)');
2019-06-07 18:33:06 +02:00
}
2016-08-07 23:23:10 +02:00
}
2019-12-28 17:34:04 +01:00
/**
* Init API wrapper.
*
* @return void
*/
private function APIFactory(): void
2016-12-24 17:20:45 +01:00
{
if ($this->API && $this->API->inited()) {
2020-09-22 23:10:56 +02:00
if ($this->API instanceof MTProto) {
foreach ($this->API->getMethodNamespaces() as $namespace) {
if (!$this->{$namespace}) {
$this->{$namespace} = $this->exportNamespace($namespace);
}
Merge alpha into master (async, huge bugfixes and more) (#546) * Implement async and lots of bugfixes * Implement more async * Implement async, implement bugfixes for the connection module, for the datacenter module, huge bugfixes, huge perfomance improvements, media DCs for https, advanced selecting, custom var_dump, totally rewritten IOLoop and response mechanism, promises, improvements to the TL parser, custom mb_substr * Apply fixes from StyleCI * Bugfixes * Apply fixes from StyleCI * Bugfixes, implement combined promises * Apply fixes from StyleCI * Support passing method arguments as callable * Starting to write async upload logic * Apply fixes from StyleCI * Start implementing async file upload * Apply fixes from StyleCI * bugfix * Apply fixes from StyleCI * Start rewriting connection module * Add PHP file docblocks for all classes * Start working on new async stream API * Finish writing stream API * More stream API fixes * Apply fixes from StyleCI * Rewrite DataCenter and Connection modules * Clean up stream API documentation * Fixes * Apply fixes from StyleCI * Add referenced parameter to get length of buffer to read in getReadBuffer API * Moved all MessageHandler code in the Connection module, added a PHP version warning in the phar * Start fixing reads * Fix all protocol stream wrappers * Apply fixes from StyleCI * Implement disconnection, and remove end function * Working async RPC * Implement async file upload * Bugfix * Method recall bugfixes * Bugfixes * Trait bugfixes * Fix FIFO buffer * Bugfixes and speedtests * Async logging * Implement websocket streams * Implement loop API, signal API, clean closing and start changing layer * Small magna, websocket and HTTP fixes * Clean up loop API * Improved stack traces, 2FA and async * Login fixes * Added instructions for manual verification * Small fixes * More app info improvements * More app info improvements * TL and 2FA fixes * Update to layer 89 * More bugfixes * Implement broken media reporting * Remove debug comments * PHP 7.2 backwards compatibility * Bugfixes * Async key generation * Some simplifications * Transport fixes * Cleanup * async API * Performance fixes * Fixes to async API * Bugfixes * Implement one-time async loop * Authorization and logging fixes * Update to layer 91 * 7to5 fix * Null coalesce conversion * Implement socks5 proxy * Implement HTTP proxy * Fixes to HTTP proxy * MTProxy and socks5 fixes * Disable PHP 5 conversion * Proxies have higher priority * Avoid error handling in vendor * Override composer dependencies * Fix travis build * Final composer fixes * Proxy logic fixes * Fix get_updates update handling * Do not use parallel file driver if not supported * Refactor loader and implement HTTP fixes * Suppress errors in loader * HTTP and authorization fixes * HTTP fixes * Improved peer management * Use HTTP protocol on altervista * Small bugfixes * Minor fixes * Docufix * Docufix * Legacy fixes * Fix message queue * Avoid updating if using MTProxy * Improve logs and examples * Trim final newlines while converting parse mode * Reimplement noResponse flag * Async combined event handler and APIFactory fixes * Actually return config * Case-insensitive methods * Bugfix * Apply fixes from StyleCI (#545) * MTProxy fixes * PHP 5 warning * Improved PHP 5 warning * Use <br> along with newlines in web logs * Update docs
2018-12-26 20:51:14 +01:00
}
}
$this->methods = self::getInternalMethodList($this->API);
2016-12-24 17:20:45 +01:00
}
}
/**
* Start MadelineProto and the event handler (enables async).
*
* Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
*
* @param string $eventHandler Event handler class name
*
* @return void
*/
public function startAndLoop(string $eventHandler): void
2020-02-26 14:14:26 +01:00
{
2020-02-26 15:15:37 +01:00
while (true) {
try {
Tools::wait($this->startAndLoopAsync($eventHandler));
return;
} catch (\Throwable $e) {
2020-02-26 15:59:34 +01:00
$this->logger->logger((string) $e, Logger::FATAL_ERROR);
2020-02-26 15:15:37 +01:00
$this->report("Surfaced: $e");
}
}
2020-02-26 14:14:26 +01:00
}
/**
2020-02-26 15:15:37 +01:00
* Start multiple instances of MadelineProto and the event handlers (enables async).
2020-02-26 14:14:26 +01:00
*
2020-02-26 15:15:37 +01:00
* @param API[] $instances Instances of madeline
* @param string[]|string $eventHandler Event handler(s)
2020-02-26 14:14:26 +01:00
*
* @return void
2020-02-26 14:14:26 +01:00
*/
2020-02-26 15:15:37 +01:00
public static function startAndLoopMulti(array $instances, $eventHandler): void
2020-02-26 14:14:26 +01:00
{
2020-02-26 15:15:37 +01:00
if (\is_string($eventHandler)) {
$eventHandler = \array_fill_keys(\array_keys($instances), $eventHandler);
}
2020-02-26 15:59:34 +01:00
$instanceOne = \array_values($instances)[0];
2020-02-26 15:15:37 +01:00
while (true) {
try {
$promises = [];
foreach ($instances as $k => $instance) {
$instance->start(['async' => false]);
2020-03-07 21:45:50 +01:00
$promises []= $instance->startAndLoopAsync($eventHandler[$k]);
2020-02-26 15:15:37 +01:00
}
Tools::wait(Tools::all($promises));
return;
} catch (\Throwable $e) {
$instanceOne->logger((string) $e, Logger::FATAL_ERROR);
$instanceOne->report("Surfaced: $e");
}
}
2020-02-26 14:14:26 +01:00
}
/**
* Start MadelineProto and the event handler (enables async).
*
* Also initializes error reporting, catching and reporting all errors surfacing from the event loop.
*
* @param string $eventHandler Event handler class name
*
* @return \Generator
*/
2020-06-15 20:06:48 +02:00
public function startAndLoopAsync(string $eventHandler): \Generator
{
$errors = [];
$this->async(true);
2020-09-24 11:45:20 +02:00
if ($this->API instanceof Client) {
yield $this->API->stopIpcServer();
yield $this->API->disconnect();
yield from $this->connectToMadelineProto(new SettingsEmpty, true);
}
$started = false;
2020-02-26 15:15:37 +01:00
while (true) {
try {
2020-02-26 14:14:26 +01:00
yield $this->start();
2020-09-24 11:45:20 +02:00
$started = true;
2020-02-26 14:14:26 +01:00
yield $this->setEventHandler($eventHandler);
2020-02-26 15:15:37 +01:00
return yield from $this->API->loop();
} catch (\Throwable $e) {
$errors = [\time() => $errors[\time()] ?? 0];
$errors[\time()]++;
2020-09-24 11:45:20 +02:00
if ($errors[\time()] > 100 && (!$this->inited() || !$started)) {
$this->logger->logger("More than 100 errors in a second and not inited, exiting!", Logger::FATAL_ERROR);
return;
}
echo $e;
2020-02-26 15:59:34 +01:00
$this->logger->logger((string) $e, Logger::FATAL_ERROR);
2020-02-26 12:45:30 +01:00
$this->report("Surfaced: $e");
}
2020-02-26 15:15:37 +01:00
}
}
2020-06-20 13:03:15 +02:00
/**
* Get attribute.
*
* @param string $name Attribute nam
*
* @internal
*
* @return mixed
*/
public function &__get(string $name)
{
if ($name === 'logger') {
if (isset($this->API)) {
return $this->API->logger;
}
return Logger::$default;
}
return $this->storage[$name];
}
/**
* Set an attribute.
*
* @param string $name Name
* @param mixed $value Value
*
* @internal
*
* @return mixed
*/
public function __set(string $name, $value)
{
return $this->storage[$name] = $value;
}
/**
* Whether an attribute exists.
*
* @param string $name Attribute name
*
* @return boolean
*/
public function __isset(string $name): bool
{
return isset($this->storage[$name]);
}
/**
* Unset attribute.
*
* @param string $name Attribute name
*
* @return void
*/
public function __unset(string $name): void
{
unset($this->storage[$name]);
}
2018-02-25 17:50:03 +01:00
}