Refactoring and encapsulation
This commit is contained in:
parent
d8dc41e6c3
commit
2720c50ca0
@ -20,17 +20,23 @@
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use Amp\Promise;
|
||||
use danog\MadelineProto\TL\TL;
|
||||
use phpDocumentor\Reflection\DocBlockFactory;
|
||||
|
||||
class AnnotationsBuilder
|
||||
{
|
||||
use \danog\MadelineProto\TL\TL;
|
||||
use Tools;
|
||||
|
||||
public function __construct($logger, $settings)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->constructTL($settings['tl_schema']);
|
||||
$this->TL = new TL(new class($logger) {
|
||||
public function __construct($logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
});
|
||||
$this->TL->init($settings['tl_schema']);
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
@ -62,7 +68,7 @@ class AnnotationsBuilder
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->getMethodNamespaces() as $namespace) {
|
||||
foreach ($this->TL->getMethodNamespaces() as $namespace) {
|
||||
$content = \preg_replace('/(class( \\w+[,]?){0,}\\n{\\n)/', '${1}'." /**\n"." * @internal this is a internal property generated by build_docs.php, don't change manually\n"." *\n"." * @var {$namespace}\n"." */\n"." public \${$namespace};\n", $content);
|
||||
}
|
||||
\file_put_contents($filename, $content);
|
||||
@ -87,12 +93,12 @@ class AnnotationsBuilder
|
||||
$handle = \fopen(\dirname(__FILE__).'/InternalDoc.php', 'w');
|
||||
|
||||
$internalDoc = [];
|
||||
foreach ($this->methods->by_id as $id => $data) {
|
||||
foreach ($this->TL->getMethods()->by_id as $id => $data) {
|
||||
if (!\strpos($data['method'], '.')) {
|
||||
continue;
|
||||
}
|
||||
list($namespace, $method) = \explode('.', $data['method']);
|
||||
if (!\in_array($namespace, $this->getMethodNamespaces())) {
|
||||
if (!\in_array($namespace, $this->TL->getMethodNamespaces())) {
|
||||
continue;
|
||||
}
|
||||
$internalDoc[$namespace][$method]['title'] = Lang::$current_lang["method_{$data['method']}"] ?? '';
|
||||
|
@ -439,9 +439,9 @@ class Connection extends Session
|
||||
}
|
||||
|
||||
if ($message['method']) {
|
||||
$body = yield $this->API->serializeMethod($message['_'], $body);
|
||||
$body = yield $this->API->getTL()->serializeMethod($message['_'], $body);
|
||||
} else {
|
||||
$body = yield $this->API->serializeObject(['type' => $message['_']], $body, $message['_']);
|
||||
$body = yield $this->API->getTL()->serializeObject(['type' => $message['_']], $body, $message['_']);
|
||||
}
|
||||
if ($refreshNext) {
|
||||
$this->API->referenceDatabase->refreshNext(false);
|
||||
|
@ -19,10 +19,11 @@
|
||||
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use danog\MadelineProto\TL\TL;
|
||||
|
||||
// This code was written a few years ago: it is garbage, and has to be rewritten
|
||||
class DocsBuilder
|
||||
{
|
||||
use \danog\MadelineProto\TL\TL;
|
||||
use \danog\MadelineProto\DocsBuilder\Methods;
|
||||
use \danog\MadelineProto\DocsBuilder\Constructors;
|
||||
use Tools;
|
||||
@ -32,10 +33,14 @@ class DocsBuilder
|
||||
{
|
||||
$this->logger = $logger;
|
||||
\set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
|
||||
$this->constructTL($settings['tl_schema']);
|
||||
$this->TL = new TL(new class($logger) {
|
||||
public function __construct($logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
});
|
||||
$this->TL->init($settings['tl_schema']);
|
||||
if (isset($settings['tl_schema']['td']) && !isset($settings['tl_schema']['telegram'])) {
|
||||
$this->constructors = $this->td_constructors;
|
||||
$this->methods = $this->td_methods;
|
||||
$this->td = true;
|
||||
}
|
||||
$this->settings = $settings;
|
||||
|
@ -35,15 +35,15 @@ trait Constructors
|
||||
$this->docs_constructors = [];
|
||||
$this->logger->logger('Generating constructors documentation...', \danog\MadelineProto\Logger::NOTICE);
|
||||
$got = [];
|
||||
foreach ($this->constructors->by_predicate_and_layer as $predicate => $id) {
|
||||
$data = $this->constructors->by_id[$id];
|
||||
foreach ($this->TL->getConstructors($this->td)->by_predicate_and_layer as $predicate => $id) {
|
||||
$data = $this->TL->getConstructors($this->td)->by_id[$id];
|
||||
if (isset($got[$id])) {
|
||||
$data['layer'] = '';
|
||||
}
|
||||
$got[$id] = '';
|
||||
/*
|
||||
if (preg_match('/%/', $type)) {
|
||||
$type = $this->constructors->findByType(str_replace('%', '', $type))['predicate'];
|
||||
$type = $this->TL->getConstructors($this->td)->findByType(str_replace('%', '', $type))['predicate'];
|
||||
}*/
|
||||
$layer = isset($data['layer']) && $data['layer'] !== '' ? '_'.$data['layer'] : '';
|
||||
$type = \str_replace(['.', '<', '>'], ['_', '_of_', ''], $data['type']);
|
||||
@ -69,7 +69,7 @@ trait Constructors
|
||||
$type_or_bare_type = \ctype_upper(Tools::end(\explode('.', $param[$type_or_subtype]))[0]) || \in_array($param[$type_or_subtype], ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int53', 'int', 'long', 'int128', 'int256', 'int512']) ? 'types' : 'constructors';
|
||||
$param[$type_or_subtype] = \str_replace(['.', 'true', 'false'], ['_', 'Bool', 'Bool'], $param[$type_or_subtype]);
|
||||
if (\preg_match('/%/', $param[$type_or_subtype])) {
|
||||
$param[$type_or_subtype] = $this->constructors->findByType(\str_replace('%', '', $param[$type_or_subtype]))['predicate'];
|
||||
$param[$type_or_subtype] = $this->TL->getConstructors($this->td)->findByType(\str_replace('%', '', $param[$type_or_subtype]))['predicate'];
|
||||
}
|
||||
if (\substr($param[$type_or_subtype], -1) === '>') {
|
||||
$param[$type_or_subtype] = \substr($param[$type_or_subtype], 0, -1);
|
||||
@ -87,14 +87,14 @@ trait Constructors
|
||||
| Name | Type | Required |
|
||||
|----------|---------------|----------|
|
||||
';
|
||||
if (!isset($this->td_descriptions['constructors'][$data['predicate']])) {
|
||||
if (!isset($this->TL->getDescriptions()['constructors'][$data['predicate']])) {
|
||||
$this->addToLang('object_'.$data['predicate']);
|
||||
if (\danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']] !== '') {
|
||||
$this->td_descriptions['constructors'][$data['predicate']]['description'] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']];
|
||||
$this->TL->getDescriptions()['constructors'][$data['predicate']]['description'] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate']];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->td_descriptions['constructors'][$data['predicate']]) && !empty($data['params'])) {
|
||||
if (isset($this->TL->getDescriptions()['constructors'][$data['predicate']]) && !empty($data['params'])) {
|
||||
$table = '### Attributes:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
@ -126,7 +126,7 @@ trait Constructors
|
||||
}
|
||||
}*/
|
||||
if (\preg_match('/%/', $ptype)) {
|
||||
$ptype = $this->constructors->findByType(\str_replace('%', '', $ptype))['predicate'];
|
||||
$ptype = $this->TL->getConstructors($this->td)->findByType(\str_replace('%', '', $ptype))['predicate'];
|
||||
}
|
||||
$type_or_bare_type = (\ctype_upper(Tools::end(\explode('_', $ptype))[0]) || \in_array($ptype, ['!X', 'X', 'bytes', 'true', 'false', 'double', 'string', 'Bool', 'int53', 'int', 'long', 'int128', 'int256', 'int512'])) && $ptype !== 'MTmessage' ? 'types' : 'constructors';
|
||||
if (\substr($ptype, -1) === '>') {
|
||||
@ -156,16 +156,16 @@ trait Constructors
|
||||
if (\in_array($ptype, ['InputEncryptedFile']) && !isset($this->settings['td'])) {
|
||||
$human_ptype = 'File path or '.$ptype;
|
||||
}
|
||||
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || $this->constructors->findByPredicate(\lcfirst($param['type']).'Empty') || ($data['type'] === 'InputMedia' && $param['name'] === 'mime_type') || ($data['type'] === 'DocumentAttribute' && \in_array($param['name'], ['w', 'h', 'duration'])) ? 'Optional' : 'Yes').'|';
|
||||
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || $this->TL->getConstructors($this->td)->findByPredicate(\lcfirst($param['type']).'Empty') || ($data['type'] === 'InputMedia' && $param['name'] === 'mime_type') || ($data['type'] === 'DocumentAttribute' && \in_array($param['name'], ['w', 'h', 'duration'])) ? 'Optional' : 'Yes').'|';
|
||||
|
||||
if (!isset($this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']])) {
|
||||
if (!isset($this->TL->getDescriptions()['constructors'][$data['predicate']]['params'][$param['name']])) {
|
||||
$this->addToLang('object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']);
|
||||
if (isset($this->td_descriptions['constructors'][$data['predicate']]['description'])) {
|
||||
$this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']];
|
||||
if (isset($this->TL->getDescriptions()['constructors'][$data['predicate']]['description'])) {
|
||||
$this->TL->getDescriptions()['constructors'][$data['predicate']]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['object_'.$data['predicate'].'_param_'.$param['name'].'_type_'.$param['type']];
|
||||
}
|
||||
}
|
||||
if (isset($this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']])) {
|
||||
$table .= $this->td_descriptions['constructors'][$data['predicate']]['params'][$param['name']].'|';
|
||||
if (isset($this->TL->getDescriptions()['constructors'][$data['predicate']]['params'][$param['name']])) {
|
||||
$table .= $this->TL->getDescriptions()['constructors'][$data['predicate']]['params'][$param['name']].'|';
|
||||
}
|
||||
$table .= PHP_EOL;
|
||||
$pptype = \in_array($ptype, ['string', 'bytes']) ? "'".$ptype."'" : $ptype;
|
||||
@ -183,7 +183,7 @@ trait Constructors
|
||||
$params = "['_' => '".$data['predicate']."'".$params.']';
|
||||
$lua_params = "{_='".$data['predicate']."'".$lua_params.'}';
|
||||
$pwr_params = '{"_": "'.$data['predicate'].'"'.$pwr_params.'}';
|
||||
$description = isset($this->td_descriptions['constructors'][$data['predicate']]) ? $this->td_descriptions['constructors'][$data['predicate']]['description'] : $constructor.' attributes, type and example';
|
||||
$description = isset($this->TL->getDescriptions()['constructors'][$data['predicate']]) ? $this->TL->getDescriptions()['constructors'][$data['predicate']]['description'] : $constructor.' attributes, type and example';
|
||||
$header = '---
|
||||
title: '.$data['predicate'].'
|
||||
description: '.$description.'
|
||||
@ -199,8 +199,8 @@ image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png
|
||||
|
||||
|
||||
';
|
||||
if (isset($this->td_descriptions['constructors'][$data['predicate']])) {
|
||||
$header .= $this->td_descriptions['constructors'][$data['predicate']]['description'].PHP_EOL.PHP_EOL;
|
||||
if (isset($this->TL->getDescriptions()['constructors'][$data['predicate']])) {
|
||||
$header .= $this->TL->getDescriptions()['constructors'][$data['predicate']]['description'].PHP_EOL.PHP_EOL;
|
||||
}
|
||||
$type = '### Type: ['.\str_replace('_', '\\_', $php_type).'](../types/'.$php_type.'.md)
|
||||
|
||||
|
@ -54,7 +54,7 @@ trait Methods
|
||||
$this->docs_methods = [];
|
||||
$this->human_docs_methods = [];
|
||||
$this->logger->logger('Generating methods documentation...', \danog\MadelineProto\Logger::NOTICE);
|
||||
foreach ($this->methods->by_id as $id => $data) {
|
||||
foreach ($this->TL->getMethods($this->td)->by_id as $id => $data) {
|
||||
$method = $data['method'];
|
||||
$php_method = \str_replace('.', '->', $data['method']);
|
||||
$type = \str_replace(['.', '<', '>'], ['_', '_of_', ''], $data['type']);
|
||||
@ -170,9 +170,9 @@ trait Methods
|
||||
}
|
||||
|
||||
if (isset($this->td_descriptions['methods'][$data['method']])) {
|
||||
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.$this->td_descriptions['methods'][$data['method']]['params'][$param['name']].' | '.(isset($param['pow']) || (($id = $this->constructors->findByPredicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->constructors->findByPredicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|';
|
||||
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.$this->td_descriptions['methods'][$data['method']]['params'][$param['name']].' | '.(isset($param['pow']) || (($id = $this->TL->getConstructors($this->td)->findByPredicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->TL->getConstructors($this->td)->findByPredicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|';
|
||||
} else {
|
||||
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || (($id = $this->constructors->findByPredicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->constructors->findByPredicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|';
|
||||
$table .= '|'.\str_replace('_', '\\_', $param['name']).'|'.(isset($param['subtype']) ? 'Array of ' : '').'['.\str_replace('_', '\\_', $human_ptype).'](../'.$type_or_bare_type.'/'.$ptype.'.md) | '.(isset($param['pow']) || (($id = $this->TL->getConstructors($this->td)->findByPredicate(\lcfirst($param['type']).'Empty')) && $id['type'] === $param['type']) || (($id = $this->TL->getConstructors($this->td)->findByPredicate('input'.$param['type'].'Empty')) && $id['type'] === $param['type']) ? 'Optional' : 'Yes').'|';
|
||||
}
|
||||
$table .= PHP_EOL;
|
||||
$pptype = \in_array($ptype, ['string', 'bytes']) ? "'".$ptype."'" : $ptype;
|
||||
|
@ -20,12 +20,12 @@
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
/**
|
||||
* Event handler
|
||||
* Event handler.
|
||||
*/
|
||||
class EventHandler extends InternalDoc
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param API|null $MadelineProto MadelineProto instance
|
||||
*/
|
||||
|
@ -4040,6 +4040,33 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$param, $level, $file, $extra]);
|
||||
}
|
||||
/**
|
||||
* Get TL namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethodNamespaces(array $extra = []): array
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Get namespaced methods (method => namespace).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethodsNamespaced(array $extra = []): array
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Get TL serializer.
|
||||
*
|
||||
* @return TL
|
||||
*/
|
||||
public function getTL(array $extra = []): danog\MadelineProto\TL\TL
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Get async HTTP client.
|
||||
*
|
||||
@ -4078,11 +4105,6 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
public function hasAllAuth(array $extra = []): bool
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Get correct settings array for the latest version.
|
||||
*
|
||||
@ -4139,7 +4161,20 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$datacenter, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether all datacenters are authorized.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasAllAuth(array $extra = []): bool
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Whether we're initing authorization.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isInitingAuthorization(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
@ -4689,57 +4724,79 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$message_media, $callable, $cb, $parallelize, $offset, $end, $part_size, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept secret chat.
|
||||
*
|
||||
* @param array $params Secret chat ID
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function acceptSecretChat($params, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$params, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request secret chat.
|
||||
*
|
||||
* @param mixed $user User to start secret chat with
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function requestSecretChat($user, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$user, $extra]);
|
||||
}
|
||||
|
||||
public function completeSecretChat($params, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$params, $extra]);
|
||||
}
|
||||
|
||||
public function notifyLayer($chat, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rekey secret chat.
|
||||
*
|
||||
* @param mixed $chat Secret chat to rekey
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function rekey($chat, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
}
|
||||
|
||||
public function acceptRekey($chat, $params, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $params, $extra]);
|
||||
}
|
||||
|
||||
public function commitRekey($chat, $params, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $params, $extra]);
|
||||
}
|
||||
|
||||
public function completeRekey($chat, $params, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $params, $extra]);
|
||||
}
|
||||
|
||||
public function secretChatStatus($chat, array $extra = [])
|
||||
/**
|
||||
* Get secret chat status.
|
||||
*
|
||||
* @param int $chat Chat ID
|
||||
*
|
||||
* @return int One of MTProto::SECRET_EMPTY, MTProto::SECRET_REQUESTED, MTProto::SECRET_READY
|
||||
*/
|
||||
public function secretChatStatus(int $chat, array $extra = []): int
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
}
|
||||
|
||||
public function getSecretChat($chat, array $extra = [])
|
||||
/**
|
||||
* Get secret chat.
|
||||
*
|
||||
* @param array|int $chat Secret chat ID
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSecretChat($chat, array $extra = []): array
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether secret chat exists.
|
||||
*
|
||||
* @param array|int $chat Secret chat ID
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasSecretChat($chat, array $extra = []): bool
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
}
|
||||
/**
|
||||
* Discard secret chat.
|
||||
*
|
||||
* @param array|int $chat Secret chat ID
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function discardSecretChat($chat, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
@ -4790,63 +4847,6 @@ class InternalDoc extends APIFactory
|
||||
return $this->__call(__FUNCTION__, [$chat, $extra]);
|
||||
}
|
||||
|
||||
public function constructTL($files, $objects = [
|
||||
], array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$files, $objects, $extra]);
|
||||
}
|
||||
|
||||
public function getMethodNamespaces(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
public function getMethodsNamespaced(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
public function updateCallbacks($objects, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$objects, $extra]);
|
||||
}
|
||||
|
||||
public function deserializeBool($id, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$id, $extra]);
|
||||
}
|
||||
|
||||
public function serializeObject($type, $object, $ctx, $layer = -1, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$type, $object, $ctx, $layer, $extra]);
|
||||
}
|
||||
|
||||
public function serializeMethod($method, $arguments, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$method, $arguments, $extra]);
|
||||
}
|
||||
|
||||
public function serializeParams($tl, $arguments, $ctx, $layer = -1, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$tl, $arguments, $ctx, $layer, $extra]);
|
||||
}
|
||||
|
||||
public function getLength($stream, $type = [
|
||||
'type' => '',
|
||||
], array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$stream, $type, $extra]);
|
||||
}
|
||||
/**
|
||||
* :type stream: io.BytesIO object.
|
||||
*/
|
||||
public function deserialize($stream, $type = [
|
||||
'type' => '',
|
||||
], array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$stream, $type, $extra]);
|
||||
}
|
||||
|
||||
public function htmlEntityDecode($stuff, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$stuff, $extra]);
|
||||
@ -5442,6 +5442,19 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
/**
|
||||
* Accesses a private variable from an object.
|
||||
*
|
||||
* @param object $obj Object
|
||||
* @param string $var Attribute name
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
public function getVar($obj, string $var, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$obj, $var, $extra]);
|
||||
}
|
||||
|
||||
public function requestCall($user, array $extra = [])
|
||||
{
|
||||
@ -5483,28 +5496,58 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dialog peers.
|
||||
*
|
||||
* @param boolean $force Whether to refetch all dialogs ignoring cache
|
||||
*
|
||||
* @return \Generator<array<Peer>>
|
||||
*/
|
||||
public function getDialogs($force = true, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$force, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full info of all dialogs.
|
||||
*
|
||||
* @param boolean $force Whether to refetch all dialogs ignoring cache
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function getFullDialogs($force = true, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$force, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set event handler.
|
||||
*
|
||||
* @param string|EventHandler $event_handler Event handler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEventHandler($event_handler, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$event_handler, $extra]);
|
||||
}
|
||||
|
||||
public function getEventHandler(array $extra = [])
|
||||
/**
|
||||
* Get event handler.
|
||||
*
|
||||
* @return EventHandler
|
||||
*/
|
||||
public function getEventHandler(array $extra = []): EventHandler
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
public function eventUpdateHandler($update, array $extra = [])
|
||||
/**
|
||||
* Event update handler.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @internal Internal event handler
|
||||
*/
|
||||
public function eventUpdateHandler(array $update, array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$update, $extra]);
|
||||
}
|
||||
@ -5645,17 +5688,31 @@ class InternalDoc extends APIFactory
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$template, $extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for terms of service update.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function checkTos(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept terms of service update.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function acceptTos(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decline terms of service update.
|
||||
*
|
||||
* THIS WILL DELETE YOUR ACCOUNT!
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function declineTos(array $extra = [])
|
||||
{
|
||||
return $this->__call(__FUNCTION__, [$extra]);
|
||||
|
@ -182,7 +182,7 @@ class WriteLoop extends ResumableSignalLoop
|
||||
$temporary_keys = [];
|
||||
if (\count($to_ack = $connection->ack_queue)) {
|
||||
foreach (\array_chunk($connection->ack_queue, 8192) as $acks) {
|
||||
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'msgs_ack', 'serialized_body' => yield $this->API->serializeObject(['type' => 'msgs_ack'], ['msg_ids' => $acks], 'msgs_ack'), 'contentRelated' => false, 'unencrypted' => false, 'method' => false];
|
||||
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'msgs_ack', 'serialized_body' => yield $this->API->getTL()->serializeObject(['type' => 'msgs_ack'], ['msg_ids' => $acks], 'msgs_ack'), 'contentRelated' => false, 'unencrypted' => false, 'method' => false];
|
||||
$temporary_keys[$connection->pending_outgoing_key] = true;
|
||||
$API->logger->logger("Adding msgs_ack {$connection->pending_outgoing_key}", Logger::ULTRA_VERBOSE);
|
||||
$connection->pending_outgoing_key++;
|
||||
@ -200,7 +200,7 @@ class WriteLoop extends ResumableSignalLoop
|
||||
}
|
||||
if ($shared->isHttp() && !$has_http_wait) {
|
||||
$API->logger->logger("Adding http_wait {$connection->pending_outgoing_key}", Logger::ULTRA_VERBOSE);
|
||||
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'http_wait', 'serialized_body' => yield $this->API->serializeObject(['type' => ''], ['_' => 'http_wait', 'max_wait' => 30000, 'wait_after' => 0, 'max_delay' => 0], 'http_wait'), 'contentRelated' => true, 'unencrypted' => false, 'method' => true];
|
||||
$connection->pending_outgoing[$connection->pending_outgoing_key] = ['_' => 'http_wait', 'serialized_body' => yield $this->API->getTL()->serializeObject(['type' => ''], ['_' => 'http_wait', 'max_wait' => 30000, 'wait_after' => 0, 'max_delay' => 0], 'http_wait'), 'contentRelated' => true, 'unencrypted' => false, 'method' => true];
|
||||
$temporary_keys[$connection->pending_outgoing_key] = true;
|
||||
$connection->pending_outgoing_key++;
|
||||
}
|
||||
@ -240,11 +240,11 @@ class WriteLoop extends ResumableSignalLoop
|
||||
if (!$shared->getTempAuthKey()->isInited() && $message['_'] !== 'auth.bindTempAuthKey' && !$inited) {
|
||||
$inited = true;
|
||||
$API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $message['_']), \danog\MadelineProto\Logger::NOTICE);
|
||||
$MTmessage['body'] = yield $API->serializeMethod(
|
||||
$MTmessage['body'] = yield $API->getTL()->serializeMethod(
|
||||
'invokeWithLayer',
|
||||
[
|
||||
'layer' => $API->settings['tl_schema']['layer'],
|
||||
'query' => yield $API->serializeMethod(
|
||||
'query' => yield $API->getTL()->serializeMethod(
|
||||
'initConnection',
|
||||
[
|
||||
'api_id' => $API->settings['app_info']['api_id'],
|
||||
@ -266,7 +266,7 @@ class WriteLoop extends ResumableSignalLoop
|
||||
if (!isset($connection->call_queue[$message['queue']])) {
|
||||
$connection->call_queue[$message['queue']] = [];
|
||||
}
|
||||
$MTmessage['body'] = yield $API->serializeMethod('invokeAfterMsgs', ['msg_ids' => $connection->call_queue[$message['queue']], 'query' => $MTmessage['body']]);
|
||||
$MTmessage['body'] = yield $API->getTL()->serializeMethod('invokeAfterMsgs', ['msg_ids' => $connection->call_queue[$message['queue']], 'query' => $MTmessage['body']]);
|
||||
|
||||
$connection->call_queue[$message['queue']][$message_id] = $message_id;
|
||||
if (\count($connection->call_queue[$message['queue']]) > $API->settings['msg_array_limit']['call_queue']) {
|
||||
@ -278,7 +278,7 @@ class WriteLoop extends ResumableSignalLoop
|
||||
// TODO
|
||||
/* if ($API->settings['requests']['gzip_encode_if_gt'] !== -1 && ($l = strlen($MTmessage['body'])) > $API->settings['requests']['gzip_encode_if_gt']) {
|
||||
if (($g = strlen($gzipped = gzencode($MTmessage['body']))) < $l) {
|
||||
$MTmessage['body'] = yield $API->serializeObject(['type' => 'gzip_packed'], ['packed_data' => $gzipped], 'gzipped data');
|
||||
$MTmessage['body'] = yield $API->getTL()->serializeObject(['type' => 'gzip_packed'], ['packed_data' => $gzipped], 'gzipped data');
|
||||
$API->logger->logger('Using GZIP compression for ' . $message['_'] . ', saved ' . ($l - $g) . ' bytes of data, reduced call size by ' . $g * 100 / $l . '%', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
}
|
||||
unset($gzipped);
|
||||
@ -317,7 +317,7 @@ class WriteLoop extends ResumableSignalLoop
|
||||
//var_dumP("container ".bin2hex($message_id));
|
||||
$keys[$connection->pending_outgoing_key++] = $message_id;
|
||||
|
||||
$message_data = yield $API->serializeObject(['type' => ''], ['_' => 'msg_container', 'messages' => $messages], 'container');
|
||||
$message_data = yield $API->getTL()->serializeObject(['type' => ''], ['_' => 'msg_container', 'messages' => $messages], 'container');
|
||||
|
||||
$message_data_length = \strlen($message_data);
|
||||
$seq_no = $connection->generateOutSeqNo(false);
|
||||
|
@ -31,6 +31,7 @@ use danog\MadelineProto\MTProtoTools\CombinedUpdatesState;
|
||||
use danog\MadelineProto\MTProtoTools\MinDatabase;
|
||||
use danog\MadelineProto\MTProtoTools\ReferenceDatabase;
|
||||
use danog\MadelineProto\MTProtoTools\UpdatesState;
|
||||
use danog\MadelineProto\TL\TL;
|
||||
use danog\MadelineProto\TL\TLCallback;
|
||||
|
||||
/**
|
||||
@ -49,7 +50,6 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
use \danog\MadelineProto\SecretChats\MessageHandler;
|
||||
use \danog\MadelineProto\SecretChats\ResponseHandler;
|
||||
use \danog\MadelineProto\SecretChats\SeqNoHandler;
|
||||
use \danog\MadelineProto\TL\TL;
|
||||
use \danog\MadelineProto\TL\Conversion\BotAPI;
|
||||
use \danog\MadelineProto\TL\Conversion\BotAPIFiles;
|
||||
use \danog\MadelineProto\TL\Conversion\Extension;
|
||||
@ -163,10 +163,24 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
64 => ' and content-related response to message already generated',
|
||||
128 => ' and other party knows for a fact that message is already received'
|
||||
];
|
||||
const REQUESTED = 0;
|
||||
const ACCEPTED = 1;
|
||||
const CONFIRMED = 2;
|
||||
const READY = 3;
|
||||
/**
|
||||
* Secret chat was not found.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const SECRET_EMPTY = 0;
|
||||
/**
|
||||
* Secret chat was requested.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const SECRET_REQUESTED = 1;
|
||||
/**
|
||||
* Secret chat was found.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const SECRET_READY = 2;
|
||||
const TD_PARAMS_CONVERSION = ['updateNewMessage' => ['_' => 'updateNewMessage', 'disable_notification' => ['message', 'silent'], 'message' => ['message']], 'message' => ['_' => 'message', 'id' => ['id'], 'sender_user_id' => ['from_id'], 'chat_id' => ['to_id', 'choose_chat_id_from_botapi'], 'send_state' => ['choose_incoming_or_sent'], 'can_be_edited' => ['choose_can_edit'], 'can_be_deleted' => ['choose_can_delete'], 'is_post' => ['post'], 'date' => ['date'], 'edit_date' => ['edit_date'], 'forward_info' => ['fwd_info', 'choose_forward_info'], 'reply_to_message_id' => ['reply_to_msg_id'], 'ttl' => ['choose_ttl'], 'ttl_expires_in' => ['choose_ttl_expires_in'], 'via_bot_user_id' => ['via_bot_id'], 'views' => ['views'], 'content' => ['choose_message_content'], 'reply_markup' => ['reply_markup']], 'messages.sendMessage' => ['chat_id' => ['peer'], 'reply_to_message_id' => ['reply_to_msg_id'], 'disable_notification' => ['silent'], 'from_background' => ['background'], 'input_message_content' => ['choose_message_content'], 'reply_markup' => ['reply_markup']]];
|
||||
const TD_REVERSE = ['sendMessage' => 'messages.sendMessage'];
|
||||
const TD_IGNORE = ['updateMessageID'];
|
||||
@ -419,6 +433,13 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
*/
|
||||
public $logger;
|
||||
|
||||
/**
|
||||
* TL serializer.
|
||||
*
|
||||
* @var \danog\MadelineProto\TL\TL
|
||||
*/
|
||||
private $TL;
|
||||
|
||||
/**
|
||||
* Constructor function.
|
||||
*
|
||||
@ -449,19 +470,17 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
$this->logger->logger(Lang::$current_lang['load_rsa'], Logger::ULTRA_VERBOSE);
|
||||
$this->rsa_keys = [];
|
||||
foreach ($this->settings['authorization']['rsa_keys'] as $key) {
|
||||
$key = yield (new RSA())->load($key);
|
||||
$key = yield (new RSA())->load($this->TL, $key);
|
||||
$this->rsa_keys[$key->fp] = $key;
|
||||
}
|
||||
/*
|
||||
* ***********************************************************************
|
||||
* Define some needed numbers for BigInteger
|
||||
*/
|
||||
// (re)-initialize TL
|
||||
$this->logger->logger(Lang::$current_lang['TL_translation'], Logger::ULTRA_VERBOSE);
|
||||
$callbacks = [$this, $this->referenceDatabase];
|
||||
if (!($this->authorization['user']['bot'] ?? false)) {
|
||||
$callbacks []= $this->minDatabase;
|
||||
}
|
||||
$this->constructTL($this->settings['tl_schema']['src'], $callbacks);
|
||||
$this->TL->init($this->settings['tl_schema']['src'], $callbacks);
|
||||
|
||||
yield $this->connectToAllDcs();
|
||||
$this->startLoops();
|
||||
$this->datacenter->curdc = 2;
|
||||
@ -495,72 +514,66 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
}
|
||||
return [
|
||||
// Databases
|
||||
'chats',
|
||||
'full_chats',
|
||||
'referenceDatabase',
|
||||
'minDatabase',
|
||||
'channel_participants',
|
||||
'chats',
|
||||
'full_chats',
|
||||
'referenceDatabase',
|
||||
'minDatabase',
|
||||
'channel_participants',
|
||||
|
||||
// Misc caching
|
||||
'dialog_params',
|
||||
'last_stored',
|
||||
'qres',
|
||||
'supportUser',
|
||||
'dialog_params',
|
||||
'last_stored',
|
||||
'qres',
|
||||
'supportUser',
|
||||
'tos',
|
||||
|
||||
// Event handler
|
||||
'event_handler',
|
||||
'event_handler_instance',
|
||||
'event_handler',
|
||||
'event_handler_instance',
|
||||
'loop_callback',
|
||||
'updates',
|
||||
'updates_key',
|
||||
'updates',
|
||||
'updates_key',
|
||||
|
||||
'hook_url',
|
||||
|
||||
// Web login template
|
||||
'web_template',
|
||||
'web_template',
|
||||
|
||||
// Settings
|
||||
'settings',
|
||||
'config',
|
||||
'settings',
|
||||
'config',
|
||||
|
||||
// Authorization keys
|
||||
'datacenter',
|
||||
'datacenter',
|
||||
|
||||
// Authorization state
|
||||
'authorization',
|
||||
'authorized',
|
||||
'authorized_dc',
|
||||
'authorization',
|
||||
'authorized',
|
||||
'authorized_dc',
|
||||
|
||||
// Authorization cache
|
||||
'rsa_keys',
|
||||
'dh_config',
|
||||
'rsa_keys',
|
||||
'dh_config',
|
||||
|
||||
// Update state
|
||||
'got_state',
|
||||
'channels_state',
|
||||
'msg_ids',
|
||||
'got_state',
|
||||
'channels_state',
|
||||
'msg_ids',
|
||||
|
||||
// Version
|
||||
'v',
|
||||
'v',
|
||||
|
||||
// TL (we don't need this)
|
||||
'constructors',
|
||||
'td_constructors',
|
||||
'methods',
|
||||
'td_methods',
|
||||
'td_descriptions',
|
||||
'tl_callbacks',
|
||||
// TL
|
||||
'TL',
|
||||
|
||||
// Secret chats
|
||||
'secret_chats',
|
||||
'encrypted_layer',
|
||||
'temp_requested_secret_chats',
|
||||
'temp_rekeyed_secret_chats',
|
||||
'secret_chats',
|
||||
'temp_requested_secret_chats',
|
||||
'temp_rekeyed_secret_chats',
|
||||
|
||||
// Object storage
|
||||
'storage',
|
||||
];
|
||||
'storage',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -576,7 +589,7 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
if (!($this->authorization['user']['bot'] ?? false)) {
|
||||
$callbacks []= $this->minDatabase;
|
||||
}
|
||||
$this->updateCallbacks($callbacks);
|
||||
$this->TL->updateCallbacks($callbacks);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -598,6 +611,37 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
return isset($this->logger) ? $this->logger->logger($param, $level, $file) : Logger::$default->logger($param, $level, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TL namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethodNamespaces(): array
|
||||
{
|
||||
return $this->TL->getMethodNamespaces();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get namespaced methods (method => namespace).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethodsNamespaced(): array
|
||||
{
|
||||
return $this->TL->getMethodsNamespaced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TL serializer.
|
||||
*
|
||||
* @return TL
|
||||
*/
|
||||
public function getTL(): TL
|
||||
{
|
||||
return $this->TL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get async HTTP client.
|
||||
*
|
||||
@ -736,9 +780,18 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
if (!isset($this->minDatabase)) {
|
||||
$this->minDatabase = new MinDatabase($this);
|
||||
}
|
||||
if (!isset($this->TL)) {
|
||||
$this->TL = new TL($this);
|
||||
$this->logger->logger(Lang::$current_lang['TL_translation'], Logger::ULTRA_VERBOSE);
|
||||
$callbacks = [$this, $this->referenceDatabase];
|
||||
if (!($this->authorization['user']['bot'] ?? false)) {
|
||||
$callbacks []= $this->minDatabase;
|
||||
}
|
||||
$this->TL->init($this->settings['tl_schema']['src'], $callbacks);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Upgrade MadelineProto instance
|
||||
* Upgrade MadelineProto instance.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
@ -863,7 +916,7 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
if (!($this->authorization['user']['bot'] ?? false)) {
|
||||
$callbacks []= $this->minDatabase;
|
||||
}
|
||||
$this->updateCallbacks($callbacks);
|
||||
$this->TL->updateCallbacks($callbacks);
|
||||
|
||||
$this->settings['connection_settings']['all']['ipv6'] = Magic::$ipv6;
|
||||
if ($this->authorized === true) {
|
||||
@ -1350,6 +1403,11 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
return $this->datacenter->isHttp($datacenter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether all datacenters are authorized.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasAllAuth(): bool
|
||||
{
|
||||
if ($this->isInitingAuthorization()) {
|
||||
@ -1365,6 +1423,11 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we're initing authorization.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isInitingAuthorization()
|
||||
{
|
||||
return $this->initing_authorization;
|
||||
@ -1563,8 +1626,7 @@ class MTProto extends AsyncConstruct implements TLCallback
|
||||
{
|
||||
try {
|
||||
foreach ((yield $this->methodCallAsyncRead('help.getCdnConfig', [], ['datacenter' => $datacenter]))['public_keys'] as $curkey) {
|
||||
$tempkey = new \danog\MadelineProto\RSA($curkey['public_key']);
|
||||
$this->cdn_rsa_keys[$tempkey->fp] = $tempkey;
|
||||
$this->cdn_rsa_keys[$tempkey->fp] = yield (new RSA)->load($this->TL, $curkey['public_key']);
|
||||
}
|
||||
} catch (\danog\MadelineProto\TL\Exception $e) {
|
||||
$this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
|
@ -186,7 +186,7 @@ trait AuthKeyHandler
|
||||
$q_bytes = $q->toBytes();
|
||||
$new_nonce = \danog\MadelineProto\Tools::random(32);
|
||||
$data_unserialized = ['pq' => $pq_bytes, 'p' => $p_bytes, 'q' => $q_bytes, 'nonce' => $nonce, 'server_nonce' => $server_nonce, 'new_nonce' => $new_nonce, 'expires_in' => $expires_in, 'dc' => \preg_replace('|_.*|', '', $datacenter)];
|
||||
$p_q_inner_data = yield $this->serializeObject(['type' => 'p_q_inner_data'.($expires_in < 0 ? '' : '_temp')], $data_unserialized, 'p_q_inner_data');
|
||||
$p_q_inner_data = yield $this->TL->serializeObject(['type' => 'p_q_inner_data'.($expires_in < 0 ? '' : '_temp')], $data_unserialized, 'p_q_inner_data');
|
||||
/*
|
||||
* ***********************************************************************
|
||||
* Encrypt serialized object
|
||||
@ -265,12 +265,12 @@ trait AuthKeyHandler
|
||||
* int $server_time
|
||||
* ]
|
||||
*/
|
||||
$server_DH_inner_data = $this->deserialize($answer, ['type' => '']);
|
||||
$server_DH_inner_data = $this->TL->deserialize($answer, ['type' => '']);
|
||||
/*
|
||||
* ***********************************************************************
|
||||
* Do some checks
|
||||
*/
|
||||
$server_DH_inner_data_length = $this->getLength($answer);
|
||||
$server_DH_inner_data_length = $this->TL->getLength($answer);
|
||||
if (\sha1(\substr($answer, 0, $server_DH_inner_data_length), true) != $answer_hash) {
|
||||
throw new \danog\MadelineProto\SecurityException('answer_hash mismatch.');
|
||||
}
|
||||
@ -320,7 +320,7 @@ trait AuthKeyHandler
|
||||
* string $g_b : g^b mod dh_prime
|
||||
* ]
|
||||
*/
|
||||
$data = yield $this->serializeObject(['type' => 'client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str], 'client_DH_inner_data');
|
||||
$data = yield $this->TL->serializeObject(['type' => 'client_DH_inner_data'], ['nonce' => $nonce, 'server_nonce' => $server_nonce, 'retry_id' => $retry_id, 'g_b' => $g_b_str], 'client_DH_inner_data');
|
||||
/*
|
||||
* ***********************************************************************
|
||||
* encrypt client_DH_inner_data
|
||||
@ -550,7 +550,7 @@ trait AuthKeyHandler
|
||||
$temp_auth_key_id = $datacenterConnection->getTempAuthKey()->getID();
|
||||
$perm_auth_key_id = $datacenterConnection->getPermAuthKey()->getID();
|
||||
$temp_session_id = $connection->session_id;
|
||||
$message_data = yield $this->serializeObject(['type' => 'bind_auth_key_inner'], ['nonce' => $nonce, 'temp_auth_key_id' => $temp_auth_key_id, 'perm_auth_key_id' => $perm_auth_key_id, 'temp_session_id' => $temp_session_id, 'expires_at' => $expires_at], 'bindTempAuthKey_inner');
|
||||
$message_data = yield $this->TL->serializeObject(['type' => 'bind_auth_key_inner'], ['nonce' => $nonce, 'temp_auth_key_id' => $temp_auth_key_id, 'perm_auth_key_id' => $perm_auth_key_id, 'temp_session_id' => $temp_session_id, 'expires_at' => $expires_at], 'bindTempAuthKey_inner');
|
||||
$message_id = $connection->generateMessageId();
|
||||
$seq_no = 0;
|
||||
$encrypted_data = \danog\MadelineProto\Tools::random(16).$message_id.\pack('VV', $seq_no, \strlen($message_data)).$message_data;
|
||||
|
@ -18,41 +18,43 @@
|
||||
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use danog\MadelineProto\TL\TL;
|
||||
|
||||
/**
|
||||
* RSA class
|
||||
* RSA class.
|
||||
*/
|
||||
class RSA
|
||||
{
|
||||
use \danog\MadelineProto\TL\TL;
|
||||
use \danog\MadelineProto\Tools;
|
||||
use \danog\Serializable;
|
||||
/**
|
||||
* Exponent
|
||||
* Exponent.
|
||||
*
|
||||
* @var \phpseclib\Math\BigInteger
|
||||
*/
|
||||
public $e;
|
||||
/**
|
||||
* Modulus
|
||||
* Modulus.
|
||||
*
|
||||
* @var \phpseclib\Math\BigInteger
|
||||
*/
|
||||
public $n;
|
||||
/**
|
||||
* Fingerprint
|
||||
* Fingerprint.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $fp;
|
||||
|
||||
/**
|
||||
* Load RSA key
|
||||
* Load RSA key.
|
||||
*
|
||||
* @param TL $TL TL serializer
|
||||
* @param string $rsa_key RSA key
|
||||
*
|
||||
*
|
||||
* @return \Generator<self>
|
||||
*/
|
||||
public function load(string $rsa_key): \Generator
|
||||
public function load(TL $TL, string $rsa_key): \Generator
|
||||
{
|
||||
\danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['rsa_init'], Logger::ULTRA_VERBOSE);
|
||||
\danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['loading_key'], Logger::ULTRA_VERBOSE);
|
||||
@ -60,13 +62,13 @@ class RSA
|
||||
$this->n = Tools::getVar($key, 'modulus');
|
||||
$this->e = Tools::getVar($key, 'exponent');
|
||||
\danog\MadelineProto\Logger::log(\danog\MadelineProto\Lang::$current_lang['computing_fingerprint'], Logger::ULTRA_VERBOSE);
|
||||
$this->fp = \substr(\sha1((yield $this->serializeObject(['type' => 'bytes'], $this->n->toBytes(), 'key')).(yield $this->serializeObject(['type' => 'bytes'], $this->e->toBytes(), 'key')), true), -8);
|
||||
$this->fp = \substr(\sha1((yield $TL->serializeObject(['type' => 'bytes'], $this->n->toBytes(), 'key')).(yield $TL->serializeObject(['type' => 'bytes'], $this->e->toBytes(), 'key')), true), -8);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep function
|
||||
* Sleep function.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@ -76,10 +78,10 @@ class RSA
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt data
|
||||
* Encrypt data.
|
||||
*
|
||||
* @param string $data Data to encrypt
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encrypt($data): string
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
namespace danog\MadelineProto\SecretChats;
|
||||
|
||||
use danog\MadelineProto\MTProto;
|
||||
|
||||
/**
|
||||
* Manages secret chats.
|
||||
*
|
||||
@ -26,10 +28,27 @@ namespace danog\MadelineProto\SecretChats;
|
||||
*/
|
||||
trait AuthKeyHandler
|
||||
{
|
||||
/**
|
||||
* Temporary requested secret chats.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $temp_requested_secret_chats = [];
|
||||
/**
|
||||
* Secret chats.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $secret_chats = [];
|
||||
|
||||
public function acceptSecretChat($params)
|
||||
/**
|
||||
* Accept secret chat.
|
||||
*
|
||||
* @param array $params Secret chat ID
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function acceptSecretChat($params): \Generator
|
||||
{
|
||||
//$this->logger->logger($params['id'],$this->secretChatStatus($params['id']));
|
||||
if ($this->secretChatStatus($params['id']) !== 0) {
|
||||
@ -56,7 +75,14 @@ trait AuthKeyHandler
|
||||
$this->logger->logger('Secret chat '.$params['id'].' accepted successfully!', \danog\MadelineProto\Logger::NOTICE);
|
||||
}
|
||||
|
||||
public function requestSecretChat($user)
|
||||
/**
|
||||
* Request secret chat.
|
||||
*
|
||||
* @param mixed $user User to start secret chat with
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function requestSecretChat($user): \Generator
|
||||
{
|
||||
$user = yield $this->getInfo($user);
|
||||
if (!isset($user['InputUser'])) {
|
||||
@ -78,7 +104,14 @@ trait AuthKeyHandler
|
||||
return $res['id'];
|
||||
}
|
||||
|
||||
public function completeSecretChat($params)
|
||||
/**
|
||||
* Complete secret chat.
|
||||
*
|
||||
* @param array $params Secret chat
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
private function completeSecretChat($params): \Generator
|
||||
{
|
||||
if ($this->secretChatStatus($params['id']) !== 1) {
|
||||
//$this->logger->logger($this->secretChatStatus($params['id']));
|
||||
@ -105,14 +138,26 @@ trait AuthKeyHandler
|
||||
$this->logger->logger('Secret chat '.$params['id'].' completed successfully!', \danog\MadelineProto\Logger::NOTICE);
|
||||
}
|
||||
|
||||
public function notifyLayer($chat)
|
||||
private function notifyLayer($chat): \Generator
|
||||
{
|
||||
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->encrypted_layer]]], ['datacenter' => $this->datacenter->curdc]);
|
||||
yield $this->methodCallAsyncRead('messages.sendEncryptedService', ['peer' => $chat, 'message' => ['_' => 'decryptedMessageService', 'action' => ['_' => 'decryptedMessageActionNotifyLayer', 'layer' => $this->TL->getSecretLayer()]]], ['datacenter' => $this->datacenter->curdc]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary rekeyed secret chats.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $temp_rekeyed_secret_chats = [];
|
||||
|
||||
public function rekey($chat)
|
||||
/**
|
||||
* Rekey secret chat.
|
||||
*
|
||||
* @param mixed $chat Secret chat to rekey
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function rekey($chat): \Generator
|
||||
{
|
||||
if ($this->secret_chats[$chat]['rekeying'][0] !== 0) {
|
||||
return;
|
||||
@ -133,7 +178,15 @@ trait AuthKeyHandler
|
||||
return $e;
|
||||
}
|
||||
|
||||
public function acceptRekey($chat, $params)
|
||||
/**
|
||||
* Accept rekeying.
|
||||
*
|
||||
* @param mixed $chat Chat
|
||||
* @param array $params Parameters
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
private function acceptRekey($chat, array $params): \Generator
|
||||
{
|
||||
if ($this->secret_chats[$chat]['rekeying'][0] !== 0) {
|
||||
$my_exchange_id = new \phpseclib\Math\BigInteger($this->secret_chats[$chat]['rekeying'][1], -256);
|
||||
@ -166,7 +219,15 @@ trait AuthKeyHandler
|
||||
$this->updaters[false]->resume();
|
||||
}
|
||||
|
||||
public function commitRekey($chat, $params)
|
||||
/**
|
||||
* Commit rekeying of secret chat.
|
||||
*
|
||||
* @param mixed $chat Chat
|
||||
* @param array $params Parameters
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
private function commitRekey($chat, array $params): \Generator
|
||||
{
|
||||
if ($this->secret_chats[$chat]['rekeying'][0] !== 1 || !isset($this->temp_rekeyed_secret_chats[$params['exchange_id']])) {
|
||||
$this->secret_chats[$chat]['rekeying'] = [0];
|
||||
@ -196,7 +257,15 @@ trait AuthKeyHandler
|
||||
$this->updaters[false]->resume();
|
||||
}
|
||||
|
||||
public function completeRekey($chat, $params)
|
||||
/**
|
||||
* Complete rekeying.
|
||||
*
|
||||
* @param mixed $chat Chat
|
||||
* @param array $params Parameters
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
private function completeRekey($chat, array $params): \Generator
|
||||
{
|
||||
if ($this->secret_chats[$chat]['rekeying'][0] !== 2 || !isset($this->temp_rekeyed_secret_chats['fingerprint'])) {
|
||||
return;
|
||||
@ -219,27 +288,59 @@ trait AuthKeyHandler
|
||||
return true;
|
||||
}
|
||||
|
||||
public function secretChatStatus($chat)
|
||||
/**
|
||||
* Get secret chat status.
|
||||
*
|
||||
* @param int $chat Chat ID
|
||||
*
|
||||
* @return int One of MTProto::SECRET_EMPTY, MTProto::SECRET_REQUESTED, MTProto::SECRET_READY
|
||||
*/
|
||||
public function secretChatStatus(int $chat): int
|
||||
{
|
||||
if (isset($this->secret_chats[$chat])) {
|
||||
return 2;
|
||||
return MTProto::SECRET_READY;
|
||||
}
|
||||
if (isset($this->temp_requested_secret_chats[$chat])) {
|
||||
return 1;
|
||||
return MTProto::SECRET_REQUESTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return MTProto::SECRET_EMPTY;
|
||||
}
|
||||
|
||||
public function getSecretChat($chat)
|
||||
/**
|
||||
* Get secret chat.
|
||||
*
|
||||
* @param array|int $chat Secret chat ID
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSecretChat($chat): array
|
||||
{
|
||||
return $this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat];
|
||||
}
|
||||
|
||||
public function discardSecretChat($chat)
|
||||
/**
|
||||
* Check whether secret chat exists.
|
||||
*
|
||||
* @param array|int $chat Secret chat ID
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasSecretChat($chat): bool
|
||||
{
|
||||
return isset($this->secret_chats[\is_array($chat) ? $chat['chat_id'] : $chat]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard secret chat.
|
||||
*
|
||||
* @param array|int $chat Secret chat ID
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function discardSecretChat($chat): \Generator
|
||||
{
|
||||
$this->logger->logger('Discarding secret chat '.$chat.'...', \danog\MadelineProto\Logger::VERBOSE);
|
||||
//$this->logger->logger(debug_backtrace(0)[0]);
|
||||
if (isset($this->secret_chats[$chat])) {
|
||||
unset($this->secret_chats[$chat]);
|
||||
}
|
||||
|
@ -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 = yield $this->serializeObject(['type' => $constructor = $this->secret_chats[$chat_id]['layer'] === 8 ? 'DecryptedMessage' : 'DecryptedMessageLayer'], $message, $constructor, $this->secret_chats[$chat_id]['layer']);
|
||||
$message = yield $this->TL->serializeObject(['type' => $constructor = $this->secret_chats[$chat_id]['layer'] === 8 ? 'DecryptedMessage' : 'DecryptedMessageLayer'], $message, $constructor, $this->secret_chats[$chat_id]['layer']);
|
||||
$message = \danog\MadelineProto\Tools::packUnsignedInt(\strlen($message)).$message;
|
||||
if ($this->secret_chats[$chat_id]['mtproto'] === 2) {
|
||||
$padding = \danog\MadelineProto\Tools::posmod(-\strlen($message), 16);
|
||||
@ -111,7 +111,7 @@ trait MessageHandler
|
||||
$this->secret_chats[$message['message']['chat_id']]['mtproto'] = 2;
|
||||
}
|
||||
}
|
||||
$deserialized = $this->deserialize($message_data, ['type' => '']);
|
||||
$deserialized = $this->TL->deserialize($message_data, ['type' => '']);
|
||||
$this->secret_chats[$message['message']['chat_id']]['ttr']--;
|
||||
if (($this->secret_chats[$message['message']['chat_id']]['ttr'] <= 0 || \time() - $this->secret_chats[$message['message']['chat_id']]['updated'] > 7 * 24 * 60 * 60) && $this->secret_chats[$message['message']['chat_id']]['rekeying'][0] === 0) {
|
||||
yield $this->rekey($message['message']['chat_id']);
|
||||
|
@ -374,7 +374,7 @@ trait BotAPI
|
||||
$data['document']['_'] = 'bot_'.$type_name;
|
||||
$res['file_size'] = $data['document']['size'];
|
||||
$res['mime_type'] = $data['document']['mime_type'];
|
||||
$res['file_id'] = \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode((yield $this->serializeObject(['type' => 'File'], $data['document'], 'File')).\chr(2)));
|
||||
$res['file_id'] = \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode((yield $this->TL->serializeObject(['type' => 'File'], $data['document'], 'File')).\chr(2)));
|
||||
|
||||
return [$type_name => $res, 'caption' => isset($data['caption']) ? $data['caption'] : ''];
|
||||
default:
|
||||
|
@ -29,7 +29,7 @@ trait BotAPIFiles
|
||||
$photoSize['location']['secret'] = $photo['location']['secret'] ?? 0;
|
||||
$photoSize['location']['dc_id'] = $photo['dc_id'] ?? 0;
|
||||
$photoSize['location']['_'] = $thumbnail ? 'bot_thumbnail' : 'bot_photo';
|
||||
$data = (yield $this->serializeObject(['type' => 'File'], $photoSize['location'], 'File')).\chr(2);
|
||||
$data = (yield $this->TL->serializeObject(['type' => 'File'], $photoSize['location'], 'File')).\chr(2);
|
||||
|
||||
return [
|
||||
'file_id' => \danog\MadelineProto\Tools::base64urlEncode(\danog\MadelineProto\Tools::rleEncode($data)),
|
||||
@ -47,7 +47,7 @@ trait BotAPIFiles
|
||||
if ($file_id[\strlen($file_id) - 1] !== \chr(2)) {
|
||||
throw new Exception(\danog\MadelineProto\Lang::$current_lang['last_byte_invalid']);
|
||||
}
|
||||
$deserialized = $this->deserialize($file_id);
|
||||
$deserialized = $this->TL->deserialize($file_id);
|
||||
$res = ['type' => \str_replace('bot_', '', $deserialized['_'])];
|
||||
switch ($deserialized['_']) {
|
||||
case 'bot_thumbnail':
|
||||
|
@ -22,69 +22,123 @@ namespace danog\MadelineProto\TL;
|
||||
use danog\MadelineProto\MTProto;
|
||||
|
||||
/**
|
||||
* TL serialization
|
||||
* TL serialization.
|
||||
*/
|
||||
class TL
|
||||
{
|
||||
/**
|
||||
* Highest available secret chat layer version
|
||||
* Highest available secret chat layer version.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $encrypted_layer = -1;
|
||||
private $encrypted_layer = -1;
|
||||
/**
|
||||
* Constructors
|
||||
* Constructors.
|
||||
*
|
||||
* @var TLConstructor
|
||||
*/
|
||||
public $constructors;
|
||||
private $constructors;
|
||||
/**
|
||||
* Methods
|
||||
* Methods.
|
||||
*
|
||||
* @var TLMethods
|
||||
* @var TLMethod
|
||||
*/
|
||||
public $methods;
|
||||
private $methods;
|
||||
/**
|
||||
* TD Constructors
|
||||
* TD Constructors.
|
||||
*
|
||||
* @var TLConstructors
|
||||
*/
|
||||
public $td_constructors;
|
||||
private $td_constructors;
|
||||
/**
|
||||
* TD Methods
|
||||
* TD Methods.
|
||||
*
|
||||
* @var TLMethods
|
||||
* @var TLMethod
|
||||
*/
|
||||
public $td_methods;
|
||||
private $td_methods;
|
||||
/**
|
||||
* Descriptions
|
||||
* Descriptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $td_descriptions;
|
||||
private $td_descriptions;
|
||||
/**
|
||||
* TL callbacks
|
||||
* TL callbacks.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tl_callbacks = [];
|
||||
private $tl_callbacks = [];
|
||||
/**
|
||||
* API instance
|
||||
* API instance.
|
||||
*
|
||||
* @var \danog\MadelineProto\MTProto
|
||||
*/
|
||||
private $API;
|
||||
/**
|
||||
* Constructor function
|
||||
* Constructor function.
|
||||
*
|
||||
* @param MTProto $API API instance
|
||||
*/
|
||||
public function __construct(MTProto $API) {
|
||||
public function __construct($API = null)
|
||||
{
|
||||
$this->API = $API;
|
||||
}
|
||||
public function constructTL($files, $objects = [])
|
||||
|
||||
/**
|
||||
* Get secret chat layer version.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getSecretLayer(): int
|
||||
{
|
||||
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['TL_loading'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
return $this->encrypted_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constructors.
|
||||
*
|
||||
* @param int $td Whether to get TD or normal methods
|
||||
*
|
||||
* @return TLConstructor
|
||||
*/
|
||||
public function getConstructors(bool $td = false): TLConstructor
|
||||
{
|
||||
return $td ? $this->td_constructors : $this->constructors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get methods.
|
||||
*
|
||||
* @param int $td Whether to get TD or normal methods
|
||||
*
|
||||
* @return TLMethod
|
||||
*/
|
||||
public function getMethods(bool $td = false): TLMethod
|
||||
{
|
||||
return $td ? $this->td_methods : $this->methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TL descriptions.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDescriptions(): array
|
||||
{
|
||||
return $this->td_descriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize TL parser.
|
||||
*
|
||||
* @param array $files Scheme files
|
||||
* @param TLCallback[] $objects TL Callback objects
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init(array $files, array $objects = [])
|
||||
{
|
||||
$this->API->logger->logger(\danog\MadelineProto\Lang::$current_lang['TL_loading'], \danog\MadelineProto\Logger::VERBOSE);
|
||||
$this->updateCallbacks($objects);
|
||||
$this->constructors = new TLConstructor();
|
||||
$this->methods = new TLMethod();
|
||||
@ -92,7 +146,7 @@ class TL
|
||||
$this->td_methods = new TLMethod();
|
||||
$this->td_descriptions = ['types' => [], 'constructors' => [], 'methods' => []];
|
||||
foreach ($files as $scheme_type => $file) {
|
||||
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['file_parsing'], \basename($file)), \danog\MadelineProto\Logger::VERBOSE);
|
||||
$this->API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['file_parsing'], \basename($file)), \danog\MadelineProto\Logger::VERBOSE);
|
||||
$filec = \file_get_contents(\danog\MadelineProto\Absolute::absolute($file));
|
||||
$TL_dict = \json_decode($filec, true);
|
||||
if ($TL_dict === null) {
|
||||
@ -165,7 +219,7 @@ class TL
|
||||
if (\preg_match('/^[^\s]+#([a-f0-9]*)/i', $line, $matches)) {
|
||||
$nid = \str_pad($matches[1], 8, '0', \STR_PAD_LEFT);
|
||||
if ($id !== $nid && $scheme_type !== 'botAPI') {
|
||||
$this->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['crc32_mismatch'], $id, $nid, $line), \danog\MadelineProto\Logger::ERROR);
|
||||
$this->API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['crc32_mismatch'], $id, $nid, $line), \danog\MadelineProto\Logger::ERROR);
|
||||
}
|
||||
$id = $nid;
|
||||
}
|
||||
@ -210,15 +264,14 @@ class TL
|
||||
if (empty($TL_dict) || empty($TL_dict['constructors']) || !isset($TL_dict['methods'])) {
|
||||
throw new Exception(\danog\MadelineProto\Lang::$current_lang['src_file_invalid'].$file);
|
||||
}
|
||||
$orig = $this->encrypted_layer;
|
||||
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['translating_obj'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$this->API->logger->logger(\danog\MadelineProto\Lang::$current_lang['translating_obj'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
foreach ($TL_dict['constructors'] as $elem) {
|
||||
if ($scheme_type === 'secret') {
|
||||
$this->encrypted_layer = \max($this->encrypted_layer, $elem['layer']);
|
||||
}
|
||||
$this->{($scheme_type === 'td' ? 'td_' : '').'constructors'}->add($elem, $scheme_type);
|
||||
}
|
||||
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['translating_methods'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
$this->API->logger->logger(\danog\MadelineProto\Lang::$current_lang['translating_methods'], \danog\MadelineProto\Logger::ULTRA_VERBOSE);
|
||||
foreach ($TL_dict['methods'] as $elem) {
|
||||
$this->{($scheme_type === 'td' ? 'td_' : '').'methods'}->add($elem);
|
||||
if ($scheme_type === 'secret') {
|
||||
@ -253,7 +306,12 @@ class TL
|
||||
}
|
||||
}
|
||||
|
||||
public function getMethodNamespaces()
|
||||
/**
|
||||
* Get TL namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethodNamespaces(): array
|
||||
{
|
||||
$res = [];
|
||||
foreach ($this->methods->method_namespace as $pair) {
|
||||
@ -264,16 +322,28 @@ class TL
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function getMethodsNamespaced()
|
||||
/**
|
||||
* Get namespaced methods (method => namespace).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethodsNamespaced(): array
|
||||
{
|
||||
return $this->methods->method_namespace;
|
||||
}
|
||||
|
||||
public function updateCallbacks($objects)
|
||||
/**
|
||||
* Update TL callbacks.
|
||||
*
|
||||
* @param TLCallback[] $objects TL callbacks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateCallbacks(array $objects)
|
||||
{
|
||||
$this->tl_callbacks = [];
|
||||
foreach ($objects as $object) {
|
||||
if (!isset(\class_implements(\get_class($object))['danog\\MadelineProto\\TL\\TLCallback'])) {
|
||||
if (!isset(\class_implements(\get_class($object))[TLCallback::class])) {
|
||||
throw new Exception('Invalid callback object provided!');
|
||||
}
|
||||
$new = [
|
||||
@ -298,8 +368,14 @@ class TL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function deserializeBool($id)
|
||||
/**
|
||||
* Deserialize bool.
|
||||
*
|
||||
* @param string $id Constructor ID
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function deserializeBool(string $id): bool
|
||||
{
|
||||
$tl_elem = $this->constructors->findById($id);
|
||||
if ($tl_elem === false) {
|
||||
@ -309,7 +385,17 @@ class TL
|
||||
return $tl_elem['predicate'] === 'boolTrue';
|
||||
}
|
||||
|
||||
public function serializeObject($type, $object, $ctx, $layer = -1)
|
||||
/**
|
||||
* Serialize TL object.
|
||||
*
|
||||
* @param array $type TL type definition
|
||||
* @param mixed $object Object to serialize
|
||||
* @param string $ctx Context
|
||||
* @param integer $layer Layer version
|
||||
*
|
||||
* @return \Generator<string>
|
||||
*/
|
||||
public function serializeObject(array $type, $object, $ctx, int $layer = -1): \Generator
|
||||
{
|
||||
switch ($type['type']) {
|
||||
case 'int':
|
||||
@ -464,7 +550,7 @@ class TL
|
||||
$predicate = $object['_'];
|
||||
$constructorData = $this->constructors->findByPredicate($predicate, $layer);
|
||||
if ($constructorData === false) {
|
||||
$this->logger->logger($object, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
$this->API->logger->logger($object, \danog\MadelineProto\Logger::FATAL_ERROR);
|
||||
|
||||
throw new Exception(\sprintf(\danog\MadelineProto\Lang::$current_lang['type_extract_error'], $predicate));
|
||||
}
|
||||
@ -486,7 +572,15 @@ class TL
|
||||
return $concat.yield $this->serializeParams($constructorData, $object, '', $layer);
|
||||
}
|
||||
|
||||
public function serializeMethod($method, $arguments)
|
||||
/**
|
||||
* Serialize method.
|
||||
*
|
||||
* @param string $method Method name
|
||||
* @param mixed $arguments Arguments
|
||||
*
|
||||
* @return \Generator<string>
|
||||
*/
|
||||
public function serializeMethod(string $method, $arguments): \Generator
|
||||
{
|
||||
if ($method === 'messages.importChatInvite' && isset($arguments['hash']) && \is_string($arguments['hash']) && \preg_match('@(?:t|telegram)\.(?:me|dog)/(joinchat/)?([a-z0-9_-]*)@i', $arguments['hash'], $matches)) {
|
||||
if ($matches[1] === '') {
|
||||
@ -523,7 +617,7 @@ class TL
|
||||
) &&
|
||||
$this->settings['upload']['allow_automatic_upload']
|
||||
) {
|
||||
$arguments['file'] = yield $this->uploadEncrypted($arguments['file']);
|
||||
$arguments['file'] = yield $this->API->uploadEncrypted($arguments['file']);
|
||||
}
|
||||
if (isset($arguments['file']['key'])) {
|
||||
$arguments['message']['media']['key'] = $arguments['file']['key'];
|
||||
@ -533,7 +627,7 @@ class TL
|
||||
}
|
||||
}
|
||||
} elseif (\in_array($method, ['messages.addChatUser', 'messages.deleteChatUser', 'messages.editChatAdmin', 'messages.editChatPhoto', 'messages.editChatTitle', 'messages.getFullChat', 'messages.exportChatInvite', 'messages.editChatAdmin', 'messages.migrateChat']) && isset($arguments['chat_id']) && (!\is_numeric($arguments['chat_id']) || $arguments['chat_id'] < 0)) {
|
||||
$res = yield $this->getInfo($arguments['chat_id']);
|
||||
$res = yield $this->API->getInfo($arguments['chat_id']);
|
||||
if ($res['type'] !== 'chat') {
|
||||
throw new \danog\MadelineProto\Exception('chat_id is not a chat id (only normal groups allowed, not supergroups)!');
|
||||
}
|
||||
@ -566,10 +660,20 @@ class TL
|
||||
return $tl['id'].yield $this->serializeParams($tl, $arguments, $method);
|
||||
}
|
||||
|
||||
public function serializeParams($tl, $arguments, $ctx, $layer = -1)
|
||||
/**
|
||||
* Serialize parameters.
|
||||
*
|
||||
* @param array $tl TL object definition
|
||||
* @param arrayLike $arguments Arguments
|
||||
* @param string $ctx Context
|
||||
* @param integer $layer Layer
|
||||
*
|
||||
* @return \Generator<string>
|
||||
*/
|
||||
private function serializeParams(array $tl, $arguments, $ctx, int $layer = -1): \Generator
|
||||
{
|
||||
$serialized = '';
|
||||
$arguments = yield $this->botAPIToMTProto($arguments);
|
||||
$arguments = yield $this->API->botAPIToMTProto($arguments);
|
||||
$flags = 0;
|
||||
foreach ($tl['params'] as $cur_flag) {
|
||||
if (isset($cur_flag['pow'])) {
|
||||
@ -595,7 +699,7 @@ class TL
|
||||
foreach ($tl['params'] as $current_argument) {
|
||||
if (!isset($arguments[$current_argument['name']])) {
|
||||
if (isset($current_argument['pow']) && (\in_array($current_argument['type'], ['true', 'false']) || ($flags & $current_argument['pow']) === 0)) {
|
||||
//$this->logger->logger('Skipping '.$current_argument['name'].' of type '.$current_argument['type');
|
||||
//$this->API->logger->logger('Skipping '.$current_argument['name'].' of type '.$current_argument['type');
|
||||
continue;
|
||||
}
|
||||
if ($current_argument['name'] === 'random_bytes') {
|
||||
@ -603,7 +707,7 @@ class TL
|
||||
continue;
|
||||
}
|
||||
if ($current_argument['name'] === 'data' && isset($tl['method']) && \in_array($tl['method'], ['messages.sendEncrypted', 'messages.sendEncryptedFile', 'messages.sendEncryptedService']) && isset($arguments['message'])) {
|
||||
$serialized .= yield $this->serializeObject($current_argument, yield $this->encryptSecretMessage($arguments['peer']['chat_id'], $arguments['message']), 'data');
|
||||
$serialized .= yield $this->serializeObject($current_argument, yield $this->API->encryptSecretMessage($arguments['peer']['chat_id'], $arguments['message']), 'data');
|
||||
continue;
|
||||
}
|
||||
if ($current_argument['name'] === 'random_id') {
|
||||
@ -691,27 +795,35 @@ class TL
|
||||
)
|
||||
&& $this->settings['upload']['allow_automatic_upload']
|
||||
) {
|
||||
$arguments[$current_argument['name']] = yield $this->upload($arguments[$current_argument['name']]);
|
||||
$arguments[$current_argument['name']] = yield $this->API->upload($arguments[$current_argument['name']]);
|
||||
}
|
||||
|
||||
if ($current_argument['type'] === 'InputEncryptedChat' && (!\is_array($arguments[$current_argument['name']]) || isset($arguments[$current_argument['name']]['_']) && $this->constructors->findByPredicate($arguments[$current_argument['name']]['_'])['type'] !== $current_argument['type'])) {
|
||||
if (\is_array($arguments[$current_argument['name']])) {
|
||||
$arguments[$current_argument['name']] = (yield $this->getInfo($arguments[$current_argument['name']]))['InputEncryptedChat'];
|
||||
$arguments[$current_argument['name']] = (yield $this->API->getInfo($arguments[$current_argument['name']]))['InputEncryptedChat'];
|
||||
} else {
|
||||
if (!isset($this->secret_chats[$arguments[$current_argument['name']]])) {
|
||||
if (!$this->API->hasSecretChat($arguments[$current_argument['name']])) {
|
||||
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['sec_peer_not_in_db']);
|
||||
}
|
||||
$arguments[$current_argument['name']] = $this->secret_chats[$arguments[$current_argument['name']]]['InputEncryptedChat'];
|
||||
$arguments[$current_argument['name']] = $this->API->getSecretChat($arguments[$current_argument['name']])['InputEncryptedChat'];
|
||||
}
|
||||
}
|
||||
//$this->logger->logger('Serializing '.$current_argument['name'].' of type '.$current_argument['type');
|
||||
//$this->API->logger->logger('Serializing '.$current_argument['name'].' of type '.$current_argument['type');
|
||||
$serialized .= yield $this->serializeObject($current_argument, $arguments[$current_argument['name']], $current_argument['name'], $layer);
|
||||
}
|
||||
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
public function getLength($stream, $type = ['type' => ''])
|
||||
/**
|
||||
* Get length of TL payload.
|
||||
*
|
||||
* @param resource $stream Stream
|
||||
* @param array $type Type identifier
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLength($stream, $type = ['type' => '']): int
|
||||
{
|
||||
if (\is_string($stream)) {
|
||||
$res = \fopen('php://memory', 'rw+b');
|
||||
@ -726,8 +838,14 @@ class TL
|
||||
return \ftell($stream);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* :type stream: io.BytesIO object.
|
||||
* Deserialize TL object.
|
||||
*
|
||||
* @param resource $stream Stream
|
||||
* @param array $type Type identifier
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function deserialize($stream, $type = ['type' => ''])
|
||||
{
|
||||
|
@ -96,7 +96,14 @@ class TLConstructor
|
||||
return false;
|
||||
}
|
||||
|
||||
public function findById($id)
|
||||
/**
|
||||
* Find constructor by ID.
|
||||
*
|
||||
* @param string $id Constructor ID
|
||||
*
|
||||
* @return array|false
|
||||
*/
|
||||
public function findById(string $id)
|
||||
{
|
||||
if (isset($this->by_id[$id])) {
|
||||
$constructor = $this->by_id[$id];
|
||||
|
@ -826,7 +826,7 @@ trait Tools
|
||||
*
|
||||
* @param object $obj Object
|
||||
* @param string $var Attribute name
|
||||
*
|
||||
*
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
|
@ -22,10 +22,10 @@ namespace danog\MadelineProto\Wrappers;
|
||||
trait DialogHandler
|
||||
{
|
||||
/**
|
||||
* Get dialog peers
|
||||
* Get dialog peers.
|
||||
*
|
||||
* @param boolean $force Whether to refetch all dialogs ignoring cache
|
||||
*
|
||||
*
|
||||
* @return \Generator<array<Peer>>
|
||||
*/
|
||||
public function getDialogs($force = true): \Generator
|
||||
@ -47,10 +47,10 @@ trait DialogHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full info of all dialogs
|
||||
* Get full info of all dialogs.
|
||||
*
|
||||
* @param boolean $force Whether to refetch all dialogs ignoring cache
|
||||
*
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function getFullDialogs($force = true): \Generator
|
||||
|
@ -22,34 +22,34 @@ namespace danog\MadelineProto\Wrappers;
|
||||
use EventHandler;
|
||||
|
||||
/**
|
||||
* Event handler
|
||||
* Event handler.
|
||||
*/
|
||||
trait Events
|
||||
{
|
||||
/**
|
||||
* Event handler class name
|
||||
* Event handler class name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $event_handler;
|
||||
/**
|
||||
* Event handler instance
|
||||
* Event handler instance.
|
||||
*
|
||||
* @var \danog\MadelineProto\EventHandler
|
||||
*/
|
||||
private $event_handler_instance;
|
||||
/**
|
||||
* Event handler method list
|
||||
* Event handler method list.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
private $event_handler_methods = [];
|
||||
|
||||
/**
|
||||
* Set event handler
|
||||
* Set event handler.
|
||||
*
|
||||
* @param string|EventHandler $event_handler Event handler
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEventHandler($event_handler)
|
||||
@ -91,7 +91,7 @@ trait Events
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event handler
|
||||
* Get event handler.
|
||||
*
|
||||
* @return EventHandler
|
||||
*/
|
||||
@ -101,12 +101,12 @@ trait Events
|
||||
}
|
||||
|
||||
/**
|
||||
* Event update handler
|
||||
* Event update handler.
|
||||
*
|
||||
* @param array $update Update
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*
|
||||
* @internal Internal event handler
|
||||
*/
|
||||
public function eventUpdateHandler(array $update)
|
||||
|
@ -44,7 +44,7 @@ trait Login
|
||||
yield $this->logout();
|
||||
}
|
||||
$callbacks = [$this, $this->referenceDatabase];
|
||||
$this->updateCallbacks($callbacks);
|
||||
$this->TL->updateCallbacks($callbacks);
|
||||
|
||||
$this->logger->logger(\danog\MadelineProto\Lang::$current_lang['login_bot'], \danog\MadelineProto\Logger::NOTICE);
|
||||
$this->authorization = yield $this->methodCallAsyncRead('auth.importBotAuthorization', ['bot_auth_token' => $token, 'api_id' => $this->settings['app_info']['api_id'], 'api_hash' => $this->settings['app_info']['api_hash']], ['datacenter' => $this->datacenter->curdc]);
|
||||
@ -159,7 +159,7 @@ trait Login
|
||||
if (!($this->authorization['user']['bot'] ?? false)) {
|
||||
$callbacks []= $this->minDatabase;
|
||||
}
|
||||
$this->updateCallbacks($callbacks);
|
||||
$this->TL->updateCallbacks($callbacks);
|
||||
|
||||
$this->startUpdateSystem();
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace danog\MadelineProto\Wrappers;
|
||||
trait TOS
|
||||
{
|
||||
/**
|
||||
* Check for terms of service update
|
||||
* Check for terms of service update.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
@ -52,7 +52,7 @@ trait TOS
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept terms of service update
|
||||
* Accept terms of service update.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
@ -67,8 +67,8 @@ trait TOS
|
||||
}
|
||||
|
||||
/**
|
||||
* Decline terms of service update
|
||||
*
|
||||
* Decline terms of service update.
|
||||
*
|
||||
* THIS WILL DELETE YOUR ACCOUNT!
|
||||
*
|
||||
* @return \Generator
|
||||
|
Loading…
Reference in New Issue
Block a user