mirror of
https://github.com/danog/MadelineProto.git
synced 2025-01-23 02:11:14 +01:00
Remove non-IPC fallback, improve IPC logic
This commit is contained in:
parent
b2446fd4d7
commit
76446a2d82
2
docs
2
docs
@ -1 +1 @@
|
|||||||
Subproject commit 31abc3950cba076c9db6c79f209203ac6cd35cad
|
Subproject commit 84c66b69ecdb6407ce254f1d901a253f6b6c00a0
|
@ -159,5 +159,7 @@
|
|||||||
|
|
||||||
"account_banned": "!!!!!!! WARNING !!!!!!!\nTelegram's flood prevention system suspended this account.\nTo continue, manual verification is required.\nSend an email to recover@telegram.org, asking to unban the phone number %s, and shortly describe what will you do with this phone number.\nThen login again.\nIf you intentionally deleted this account, ignore this message.",
|
"account_banned": "!!!!!!! WARNING !!!!!!!\nTelegram's flood prevention system suspended this account.\nTo continue, manual verification is required.\nSend an email to recover@telegram.org, asking to unban the phone number %s, and shortly describe what will you do with this phone number.\nThen login again.\nIf you intentionally deleted this account, ignore this message.",
|
||||||
|
|
||||||
"plugin_path_does_not_exist": "Plugin path %s does not exist!"
|
"plugin_path_does_not_exist": "Plugin path %s does not exist!",
|
||||||
|
|
||||||
|
"could_not_connect_to_MadelineProto": "Could not connect to MadelineProto, please enable proc_open or disable webserver path rewrites to fix!"
|
||||||
}
|
}
|
||||||
|
14
src/API.php
14
src/API.php
@ -311,7 +311,7 @@ final class API extends AbstractAPI
|
|||||||
$this->session,
|
$this->session,
|
||||||
$settings,
|
$settings,
|
||||||
$forceFull
|
$forceFull
|
||||||
)->await(Tools::getTimeoutCancellation(30.0));
|
)->await(Tools::getTimeoutCancellation(3.0));
|
||||||
} catch (CancelledException $e) {
|
} catch (CancelledException $e) {
|
||||||
if (!$e->getPrevious() instanceof TimeoutException) {
|
if (!$e->getPrevious() instanceof TimeoutException) {
|
||||||
throw $e;
|
throw $e;
|
||||||
@ -322,16 +322,10 @@ final class API extends AbstractAPI
|
|||||||
|
|
||||||
if ($unserialized === 0) {
|
if ($unserialized === 0) {
|
||||||
// Timeout
|
// Timeout
|
||||||
Logger::log('!!! Could not connect to MadelineProto, please check and report the logs for more details. !!!', Logger::FATAL_ERROR);
|
throw new Exception(Lang::$current_lang['could_not_connect_to_MadelineProto']);
|
||||||
if (!$tryReconnect || (\defined('MADELINEPROTO_TEST') && \constant('MADELINEPROTO_TEST') === 'testing')) {
|
|
||||||
throw new Exception('Could not connect to MadelineProto, please check the MadelineProto.log file to debug!');
|
|
||||||
}
|
|
||||||
Logger::log('!!! Reconnecting using slower method. !!!', Logger::FATAL_ERROR);
|
|
||||||
// IPC server error, try fetching full session
|
|
||||||
return $this->connectToMadelineProto($settings, true, false);
|
|
||||||
} elseif ($unserialized instanceof Throwable) {
|
} elseif ($unserialized instanceof Throwable) {
|
||||||
// IPC server error, try fetching full session
|
// IPC server error
|
||||||
return $this->connectToMadelineProto($settings, true);
|
throw $unserialized;
|
||||||
} elseif ($unserialized instanceof ChannelledSocket) {
|
} elseif ($unserialized instanceof ChannelledSocket) {
|
||||||
// Success, IPC client
|
// Success, IPC client
|
||||||
$this->wrapper->setAPI(new Client($unserialized, $this->session, Logger::$default));
|
$this->wrapper->setAPI(new Client($unserialized, $this->session, Logger::$default));
|
||||||
|
@ -53,7 +53,7 @@ abstract class AbstractMessage extends Update implements SimpleFilters
|
|||||||
$this->id = $rawMessage['id'];
|
$this->id = $rawMessage['id'];
|
||||||
$this->chatId = $info['bot_api_id'];
|
$this->chatId = $info['bot_api_id'];
|
||||||
$this->senderId = isset($rawMessage['from_id'])
|
$this->senderId = isset($rawMessage['from_id'])
|
||||||
? $this->API->getIdInternal($rawMessage['from_id'])
|
? $this->getClient()->getIdInternal($rawMessage['from_id'])
|
||||||
: $this->chatId;
|
: $this->chatId;
|
||||||
$this->date = $rawMessage['date'];
|
$this->date = $rawMessage['date'];
|
||||||
$this->mentioned = $rawMessage['mentioned'];
|
$this->mentioned = $rawMessage['mentioned'];
|
||||||
@ -131,14 +131,14 @@ abstract class AbstractMessage extends Update implements SimpleFilters
|
|||||||
}
|
}
|
||||||
return $this->replyCache;
|
return $this->replyCache;
|
||||||
}
|
}
|
||||||
$messages = $this->API->methodCallAsyncRead(
|
$messages = $this->getClient()->methodCallAsyncRead(
|
||||||
API::isSupergroup($this->chatId) ? 'channels.getMessages' : 'messages.getMessages',
|
API::isSupergroup($this->chatId) ? 'channels.getMessages' : 'messages.getMessages',
|
||||||
[
|
[
|
||||||
'channel' => $this->chatId,
|
'channel' => $this->chatId,
|
||||||
'id' => [['_' => 'inputMessageReplyTo', 'id' => $this->id]]
|
'id' => [['_' => 'inputMessageReplyTo', 'id' => $this->id]]
|
||||||
]
|
]
|
||||||
)['messages'];
|
)['messages'];
|
||||||
$this->replyCache = $messages ? $this->API->wrapMessage($messages[0]) : null;
|
$this->replyCache = $messages ? $this->getClient()->wrapMessage($messages[0]) : null;
|
||||||
$this->replyCached = true;
|
$this->replyCached = true;
|
||||||
if (!$this->replyCache instanceof $class) {
|
if (!$this->replyCache instanceof $class) {
|
||||||
return null;
|
return null;
|
||||||
@ -153,7 +153,7 @@ abstract class AbstractMessage extends Update implements SimpleFilters
|
|||||||
*/
|
*/
|
||||||
public function delete(bool $revoke = true): void
|
public function delete(bool $revoke = true): void
|
||||||
{
|
{
|
||||||
$this->API->methodCallAsyncRead(
|
$this->getClient()->methodCallAsyncRead(
|
||||||
API::isSupergroup($this->chatId) ? 'channels.deleteMessages' : 'messages.deleteMessages',
|
API::isSupergroup($this->chatId) ? 'channels.deleteMessages' : 'messages.deleteMessages',
|
||||||
[
|
[
|
||||||
'channel' => $this->chatId,
|
'channel' => $this->chatId,
|
||||||
@ -191,7 +191,7 @@ abstract class AbstractMessage extends Update implements SimpleFilters
|
|||||||
bool $noWebpage = false,
|
bool $noWebpage = false,
|
||||||
bool $updateStickersetsOrder = false,
|
bool $updateStickersetsOrder = false,
|
||||||
): Message {
|
): Message {
|
||||||
return $this->API->sendMessage(
|
return $this->getClient()->sendMessage(
|
||||||
peer: $this->chatId,
|
peer: $this->chatId,
|
||||||
message: $message,
|
message: $message,
|
||||||
parseMode: $parseMode,
|
parseMode: $parseMode,
|
||||||
|
@ -82,7 +82,7 @@ abstract class Media extends IpcCapable implements JsonSerializable
|
|||||||
*/
|
*/
|
||||||
public function getDownloadLink(?string $scriptUrl = null): string
|
public function getDownloadLink(?string $scriptUrl = null): string
|
||||||
{
|
{
|
||||||
return $this->API->getDownloadLink($this, $scriptUrl);
|
return $this->getClient()->getDownloadLink($this, $scriptUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
@ -95,13 +95,13 @@ abstract class Message extends AbstractMessage
|
|||||||
$this->fwdInfo = new ForwardedInfo(
|
$this->fwdInfo = new ForwardedInfo(
|
||||||
$fwdFrom['date'],
|
$fwdFrom['date'],
|
||||||
isset($fwdFrom['from_id'])
|
isset($fwdFrom['from_id'])
|
||||||
? $this->API->getIdInternal($fwdFrom['from_id'])
|
? $this->getClient()->getIdInternal($fwdFrom['from_id'])
|
||||||
: null,
|
: null,
|
||||||
$fwdFrom['from_name'] ?? null,
|
$fwdFrom['from_name'] ?? null,
|
||||||
$fwdFrom['channel_post'] ?? null,
|
$fwdFrom['channel_post'] ?? null,
|
||||||
$fwdFrom['post_author'] ?? null,
|
$fwdFrom['post_author'] ?? null,
|
||||||
isset($fwdFrom['saved_from_peer'])
|
isset($fwdFrom['saved_from_peer'])
|
||||||
? $this->API->getIdInternal($fwdFrom['saved_from_peer'])
|
? $this->getClient()->getIdInternal($fwdFrom['saved_from_peer'])
|
||||||
: null,
|
: null,
|
||||||
$fwdFrom['saved_from_msg_id'] ?? null
|
$fwdFrom['saved_from_msg_id'] ?? null
|
||||||
);
|
);
|
||||||
|
@ -27,6 +27,7 @@ use Amp\Ipc\Sync\ChannelledSocket;
|
|||||||
use danog\MadelineProto\Exception;
|
use danog\MadelineProto\Exception;
|
||||||
use danog\MadelineProto\FileCallbackInterface;
|
use danog\MadelineProto\FileCallbackInterface;
|
||||||
use danog\MadelineProto\Logger;
|
use danog\MadelineProto\Logger;
|
||||||
|
use danog\MadelineProto\MTProto;
|
||||||
use danog\MadelineProto\MTProtoTools\FilesLogic;
|
use danog\MadelineProto\MTProtoTools\FilesLogic;
|
||||||
use danog\MadelineProto\SessionPaths;
|
use danog\MadelineProto\SessionPaths;
|
||||||
use danog\MadelineProto\Tools;
|
use danog\MadelineProto\Tools;
|
||||||
@ -55,9 +56,9 @@ final class Client extends ClientAbstract
|
|||||||
/**
|
/**
|
||||||
* Returns an instance of a client by session name.
|
* Returns an instance of a client by session name.
|
||||||
*/
|
*/
|
||||||
public static function giveInstanceBySession(string $session): Client
|
public static function giveInstanceBySession(string $session): Client|MTProto
|
||||||
{
|
{
|
||||||
return self::$instances[$session];
|
return self::$instances[$session] ?? MTProto::giveInstanceBySession($session);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,7 +15,7 @@ final class EventHandlerProxy extends IpcCapable
|
|||||||
}
|
}
|
||||||
public function __call(string $name, array $arguments): mixed
|
public function __call(string $name, array $arguments): mixed
|
||||||
{
|
{
|
||||||
return $this->API->callPluginMethod(
|
return $this->getClient()->callPluginMethod(
|
||||||
$this->__plugin,
|
$this->__plugin,
|
||||||
$name,
|
$name,
|
||||||
$arguments
|
$arguments
|
||||||
@ -23,18 +23,18 @@ final class EventHandlerProxy extends IpcCapable
|
|||||||
}
|
}
|
||||||
public function __get(string $name): mixed
|
public function __get(string $name): mixed
|
||||||
{
|
{
|
||||||
return $this->API->getPluginProperty($this->__plugin, $name);
|
return $this->getClient()->getPluginProperty($this->__plugin, $name);
|
||||||
}
|
}
|
||||||
public function __set(string $name, mixed $value): void
|
public function __set(string $name, mixed $value): void
|
||||||
{
|
{
|
||||||
$this->API->setPluginProperty($this->__plugin, $name, $value);
|
$this->getClient()->setPluginProperty($this->__plugin, $name, $value);
|
||||||
}
|
}
|
||||||
public function __isset(string $name): bool
|
public function __isset(string $name): bool
|
||||||
{
|
{
|
||||||
return $this->API->issetPluginProperty($this->__plugin, $name);
|
return $this->getClient()->issetPluginProperty($this->__plugin, $name);
|
||||||
}
|
}
|
||||||
public function __unset(string $name): void
|
public function __unset(string $name): void
|
||||||
{
|
{
|
||||||
$this->API->unsetPluginProperty($this->__plugin, $name);
|
$this->getClient()->unsetPluginProperty($this->__plugin, $name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,35 +11,30 @@ use danog\MadelineProto\MTProto;
|
|||||||
*/
|
*/
|
||||||
abstract class IpcCapable
|
abstract class IpcCapable
|
||||||
{
|
{
|
||||||
private readonly string $session;
|
protected readonly string $session;
|
||||||
protected MTProto|Client|null $API;
|
private MTProto|Client|null $API;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
protected function __construct(
|
protected function __construct(MTProto $API)
|
||||||
MTProto|Client $API,
|
{
|
||||||
) {
|
|
||||||
$this->API = $API;
|
$this->API = $API;
|
||||||
if ($API instanceof MTProto) {
|
$this->session = $API->getSessionName();
|
||||||
$this->session = $API->wrapper->getSession()->getSessionDirectoryPath();
|
|
||||||
} else {
|
|
||||||
$this->session = $API->getSession()->getSessionDirectoryPath();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
public function __sleep()
|
final public function __sleep()
|
||||||
{
|
{
|
||||||
$vars = \get_object_vars($this);
|
$vars = \get_object_vars($this);
|
||||||
unset($vars['API']);
|
unset($vars['API']);
|
||||||
return \array_keys($vars);
|
return \array_keys($vars);
|
||||||
}
|
}
|
||||||
/** @internal */
|
|
||||||
public function __wakeup(): void
|
final protected function getClient(): MTProto|Client
|
||||||
{
|
{
|
||||||
$this->API = Client::giveInstanceBySession($this->session);
|
return $this->API ??= Client::giveInstanceBySession($this->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __debugInfo()
|
final public function __debugInfo()
|
||||||
{
|
{
|
||||||
$vars = \get_object_vars($this);
|
$vars = \get_object_vars($this);
|
||||||
unset($vars['API']);
|
unset($vars['API']);
|
||||||
|
@ -419,6 +419,16 @@ final class MTProto implements TLCallback, LoggerGetter
|
|||||||
'session' => ['innerMadelineProto' => true, 'enableCache' => false],
|
'session' => ['innerMadelineProto' => true, 'enableCache' => false],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an instance of a client by session name.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public static function giveInstanceBySession(string $session): MTProto
|
||||||
|
{
|
||||||
|
return self::$references[$session];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize session, returning object to serialize to db.
|
* Serialize session, returning object to serialize to db.
|
||||||
*
|
*
|
||||||
@ -482,8 +492,8 @@ final class MTProto implements TLCallback, LoggerGetter
|
|||||||
public function __construct(Settings|SettingsEmpty $settings, ?APIWrapper $wrapper = null)
|
public function __construct(Settings|SettingsEmpty $settings, ?APIWrapper $wrapper = null)
|
||||||
{
|
{
|
||||||
if ($wrapper) {
|
if ($wrapper) {
|
||||||
self::$references[\spl_object_hash($this)] = $this;
|
|
||||||
$this->wrapper = $wrapper;
|
$this->wrapper = $wrapper;
|
||||||
|
self::$references[$this->getSessionName()] = $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$initDeferred = new DeferredFuture;
|
$initDeferred = new DeferredFuture;
|
||||||
@ -974,10 +984,10 @@ final class MTProto implements TLCallback, LoggerGetter
|
|||||||
// Setup one-time stuffs
|
// Setup one-time stuffs
|
||||||
Magic::start(light: false);
|
Magic::start(light: false);
|
||||||
|
|
||||||
// Set reference to itself
|
|
||||||
self::$references[\spl_object_hash($this)] = $this;
|
|
||||||
// Set API wrapper
|
// Set API wrapper
|
||||||
$this->wrapper = $wrapper;
|
$this->wrapper = $wrapper;
|
||||||
|
// Set reference to itself
|
||||||
|
self::$references[$this->getSessionName()] = $this;
|
||||||
|
|
||||||
$deferred = new DeferredFuture;
|
$deferred = new DeferredFuture;
|
||||||
$this->initPromise = $deferred->getFuture();
|
$this->initPromise = $deferred->getFuture();
|
||||||
@ -1072,8 +1082,8 @@ final class MTProto implements TLCallback, LoggerGetter
|
|||||||
$this->logger = new Logger(new \danog\MadelineProto\Settings\Logger);
|
$this->logger = new Logger(new \danog\MadelineProto\Settings\Logger);
|
||||||
}
|
}
|
||||||
$this->logger->logger('Will unreference instance');
|
$this->logger->logger('Will unreference instance');
|
||||||
if (isset(self::$references[\spl_object_hash($this)])) {
|
if (isset(self::$references[$this->getSessionName()])) {
|
||||||
unset(self::$references[\spl_object_hash($this)]);
|
unset(self::$references[$this->getSessionName()]);
|
||||||
}
|
}
|
||||||
$this->stopLoops();
|
$this->stopLoops();
|
||||||
if (isset($this->seqUpdater)) {
|
if (isset($this->seqUpdater)) {
|
||||||
|
@ -35,6 +35,7 @@ use Revolt\EventLoop;
|
|||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
use const LOCK_EX;
|
use const LOCK_EX;
|
||||||
|
|
||||||
use function Amp\File\exists;
|
use function Amp\File\exists;
|
||||||
use function Amp\Ipc\connect;
|
use function Amp\Ipc\connect;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ declare(strict_types=1);
|
|||||||
namespace danog\MadelineProto\TL\Types;
|
namespace danog\MadelineProto\TL\Types;
|
||||||
|
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
use danog\MadelineProto\Ipc\Client;
|
use danog\MadelineProto\Ipc\IpcCapable;
|
||||||
use danog\MadelineProto\MTProto;
|
use danog\MadelineProto\MTProto;
|
||||||
use JsonSerializable;
|
use JsonSerializable;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ use JsonSerializable;
|
|||||||
*
|
*
|
||||||
* @implements ArrayAccess<array-key, mixed>
|
* @implements ArrayAccess<array-key, mixed>
|
||||||
*/
|
*/
|
||||||
final class Button implements JsonSerializable, ArrayAccess
|
final class Button extends IpcCapable implements JsonSerializable, ArrayAccess
|
||||||
{
|
{
|
||||||
/** Button label */
|
/** Button label */
|
||||||
public readonly string $label;
|
public readonly string $label;
|
||||||
@ -40,15 +40,6 @@ final class Button implements JsonSerializable, ArrayAccess
|
|||||||
* @var array<array-key, mixed>
|
* @var array<array-key, mixed>
|
||||||
*/
|
*/
|
||||||
private array $button = [];
|
private array $button = [];
|
||||||
/**
|
|
||||||
* Session name.
|
|
||||||
*/
|
|
||||||
private string $session = '';
|
|
||||||
/**
|
|
||||||
* MTProto instance.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private MTProto|Client|null $API = null;
|
|
||||||
/**
|
/**
|
||||||
* Message ID.
|
* Message ID.
|
||||||
*/
|
*/
|
||||||
@ -69,6 +60,7 @@ final class Button implements JsonSerializable, ArrayAccess
|
|||||||
*/
|
*/
|
||||||
public function __construct(MTProto $API, array $message, array $button)
|
public function __construct(MTProto $API, array $message, array $button)
|
||||||
{
|
{
|
||||||
|
parent::__construct($API);
|
||||||
if (!isset($message['from_id']) // No other option
|
if (!isset($message['from_id']) // No other option
|
||||||
// It's a channel/chat, 100% what we need
|
// It's a channel/chat, 100% what we need
|
||||||
|| $message['peer_id']['_'] !== 'peerUser'
|
|| $message['peer_id']['_'] !== 'peerUser'
|
||||||
@ -82,15 +74,6 @@ final class Button implements JsonSerializable, ArrayAccess
|
|||||||
$this->label = $button['text'];
|
$this->label = $button['text'];
|
||||||
$this->button = $button;
|
$this->button = $button;
|
||||||
$this->id = $message['id'];
|
$this->id = $message['id'];
|
||||||
$this->API = $API;
|
|
||||||
$this->session = $API->getWrapper()->getSession()->getSessionDirectoryPath();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Sleep function.
|
|
||||||
*/
|
|
||||||
public function __sleep(): array
|
|
||||||
{
|
|
||||||
return ['button', 'peer', 'id', 'session'];
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Click on button.
|
* Click on button.
|
||||||
@ -99,18 +82,17 @@ final class Button implements JsonSerializable, ArrayAccess
|
|||||||
*/
|
*/
|
||||||
public function click(bool $donotwait = true)
|
public function click(bool $donotwait = true)
|
||||||
{
|
{
|
||||||
$this->API ??= Client::giveInstanceBySession($this->session);
|
|
||||||
switch ($this->button['_']) {
|
switch ($this->button['_']) {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
case 'keyboardButtonUrl':
|
case 'keyboardButtonUrl':
|
||||||
return $this->button['url'];
|
return $this->button['url'];
|
||||||
case 'keyboardButton':
|
case 'keyboardButton':
|
||||||
return $this->API->clickInternal($donotwait, 'messages.sendMessage', ['peer' => $this->peer, 'message' => $this->button['text'], 'reply_to_msg_id' => $this->id]);
|
return $this->getClient()->clickInternal($donotwait, 'messages.sendMessage', ['peer' => $this->peer, 'message' => $this->button['text'], 'reply_to_msg_id' => $this->id]);
|
||||||
case 'keyboardButtonCallback':
|
case 'keyboardButtonCallback':
|
||||||
return $this->API->clickInternal($donotwait, 'messages.getBotCallbackAnswer', ['peer' => $this->peer, 'msg_id' => $this->id, 'data' => $this->button['data']]);
|
return $this->getClient()->clickInternal($donotwait, 'messages.getBotCallbackAnswer', ['peer' => $this->peer, 'msg_id' => $this->id, 'data' => $this->button['data']]);
|
||||||
case 'keyboardButtonGame':
|
case 'keyboardButtonGame':
|
||||||
return $this->API->clickInternal($donotwait, 'messages.getBotCallbackAnswer', ['peer' => $this->peer, 'msg_id' => $this->id, 'game' => true]);
|
return $this->getClient()->clickInternal($donotwait, 'messages.getBotCallbackAnswer', ['peer' => $this->peer, 'msg_id' => $this->id, 'game' => true]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ use BaconQrCode\Renderer\ImageRenderer;
|
|||||||
use BaconQrCode\Renderer\PlainTextRenderer;
|
use BaconQrCode\Renderer\PlainTextRenderer;
|
||||||
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||||
use BaconQrCode\Writer;
|
use BaconQrCode\Writer;
|
||||||
use danog\MadelineProto\Ipc\Client;
|
use danog\MadelineProto\Ipc\IpcCapable;
|
||||||
use danog\MadelineProto\MTProto;
|
use danog\MadelineProto\MTProto;
|
||||||
use danog\MadelineProto\Tools;
|
use danog\MadelineProto\Tools;
|
||||||
use JsonSerializable;
|
use JsonSerializable;
|
||||||
@ -38,27 +38,17 @@ use JsonSerializable;
|
|||||||
/**
|
/**
|
||||||
* Represents a login QR code.
|
* Represents a login QR code.
|
||||||
*/
|
*/
|
||||||
final class LoginQrCode implements JsonSerializable
|
final class LoginQrCode extends IpcCapable implements JsonSerializable
|
||||||
{
|
{
|
||||||
private string $session;
|
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private MTProto|Client $API,
|
MTProto $API,
|
||||||
/** @var non-empty-string The [QR code login link](https://core.telegram.org/api/links#qr-code-login-links) */
|
/** @var non-empty-string The [QR code login link](https://core.telegram.org/api/links#qr-code-login-links) */
|
||||||
public readonly string $link,
|
public readonly string $link,
|
||||||
/** @var positive-int The expiry date of the link */
|
/** @var positive-int The expiry date of the link */
|
||||||
public readonly int $expiry
|
public readonly int $expiry
|
||||||
) {
|
) {
|
||||||
$this->session = $API->getWrapper()->getSession()->getSessionDirectoryPath();
|
parent::__construct($API);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public function __sleep(): array
|
|
||||||
{
|
|
||||||
return ['link', 'expiry', 'session'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@ -95,8 +85,7 @@ final class LoginQrCode implements JsonSerializable
|
|||||||
|
|
||||||
public function getLoginCancellation(): Cancellation
|
public function getLoginCancellation(): Cancellation
|
||||||
{
|
{
|
||||||
$this->API ??= Client::giveInstanceBySession($this->session);
|
return $this->getClient()->getQrLoginCancellation();
|
||||||
return $this->API->getQrLoginCancellation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +115,7 @@ final class LoginQrCode implements JsonSerializable
|
|||||||
(new DeferredFuture)->getFuture()->await($cancellation);
|
(new DeferredFuture)->getFuture()->await($cancellation);
|
||||||
} catch (CancelledException) {
|
} catch (CancelledException) {
|
||||||
$customCancellation?->throwIfRequested();
|
$customCancellation?->throwIfRequested();
|
||||||
return $this->API->qrLogin();
|
return $this->getClient()->qrLogin();
|
||||||
}
|
}
|
||||||
throw new AssertionError("Unreachable!");
|
throw new AssertionError("Unreachable!");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user