Some more improvements

This commit is contained in:
Daniil Gentili 2020-10-08 11:27:37 +02:00
parent 787f06a314
commit 662f521409
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
12 changed files with 212 additions and 97 deletions

View File

@ -371,8 +371,8 @@ class API extends InternalDoc
} catch (\Throwable $e) {
$errors = [\time() => $errors[\time()] ?? 0];
$errors[\time()]++;
if ($errors[\time()] > 100 && (!$this->inited() || !$started)) {
$this->logger->logger("More than 100 errors in a second and not inited, exiting!", Logger::FATAL_ERROR);
if ($errors[\time()] > 10 && (!$this->inited() || !$started)) {
$this->logger->logger("More than 10 errors in a second and not inited, exiting!", Logger::FATAL_ERROR);
return;
}
echo $e;

View File

@ -34,7 +34,7 @@ use danog\MadelineProto\Tools;
class WriteLoop extends ResumableSignalLoop
{
const MAX_COUNT = 1020;
const MAX_SIZE = 1 << 15;
private const MAX_SIZE = 1 << 15;
const MAX_IDS = 8192;
use Common;

View File

@ -99,7 +99,7 @@ class MTProto extends AsyncConstruct implements TLCallback
*/
const V = 147;
/**
* String release version.
* Release version.
*
* @var string
*/
@ -137,12 +137,16 @@ class MTProto extends AsyncConstruct implements TLCallback
/**
* Bad message error codes.
*
* @internal
*
* @var array
*/
const BAD_MSG_ERROR_CODES = [16 => 'msg_id too low (most likely, client time is wrong; it would be worthwhile to synchronize it using msg_id notifications and re-send the original message with the “correct” msg_id or wrap it in a container with a new msg_id if the original message had waited too long on the client to be transmitted)', 17 => 'msg_id too high (similar to the previous case, the client time has to be synchronized, and the message re-sent with the correct msg_id)', 18 => 'incorrect two lower order msg_id bits (the server expects client message msg_id to be divisible by 4)', 19 => 'container msg_id is the same as msg_id of a previously received message (this must never happen)', 20 => 'message too old, and it cannot be verified whether the server has received a message with this msg_id or not', 32 => 'msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno)', 33 => 'msg_seqno too high (similarly, there is a message with a higher msg_id but with either a lower or an equal and odd seqno)', 34 => 'an even msg_seqno expected (irrelevant message), but odd received', 35 => 'odd msg_seqno expected (relevant message), but even received', 48 => 'incorrect server salt (in this case, the bad_server_salt response is received with the correct salt, and the message is to be re-sent with it)', 64 => 'invalid container'];
/**
* Localized message info flags.
*
* @internal
*
* @var array
*/
const MSGS_INFO_FLAGS = [1 => 'nothing is known about the message (msg_id too low, the other party may have forgotten it)', 2 => 'message not received (msg_id falls within the range of stored identifiers; however, the other party has certainly not received a message like that)', 3 => 'message not received (msg_id too high; however, the other party has certainly not received it yet)', 4 => 'message received (note that this response is also at the same time a receipt acknowledgment)', 8 => ' and message already acknowledged', 16 => ' and message not requiring acknowledgment', 32 => ' and RPC query contained in message being processed or processing already complete', 64 => ' and content-related response to message already generated', 128 => ' and other party knows for a fact that message is already received'];
@ -164,44 +168,29 @@ class MTProto extends AsyncConstruct implements TLCallback
* @var int
*/
const SECRET_READY = 2;
/**
* @internal
*/
const GETUPDATES_HANDLER = 'getUpdates';
/**
* @internal
*/
const TD_PARAMS_CONVERSION = ['updateNewMessage' => ['_' => 'updateNewMessage', 'disable_notification' => ['message', 'silent'], 'message' => ['message']], 'message' => ['_' => 'message', 'id' => ['id'], 'sender_user_id' => ['from_id'], 'chat_id' => ['peer_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']]];
/**
* @internal
*/
const TD_REVERSE = ['sendMessage' => 'messages.sendMessage'];
/**
* @internal
*/
const TD_IGNORE = ['updateMessageID'];
/**
* @internal
*/
const BOTAPI_PARAMS_CONVERSION = ['disable_web_page_preview' => 'no_webpage', 'disable_notification' => 'silent', 'reply_to_message_id' => 'reply_to_msg_id', 'chat_id' => 'peer', 'text' => 'message'];
// Not content related constructors
const NOT_CONTENT_RELATED = [
//'rpc_result',
//'rpc_error',
'rpc_drop_answer',
'rpc_answer_unknown',
'rpc_answer_dropped_running',
'rpc_answer_dropped',
'get_future_salts',
'future_salt',
'future_salts',
'ping',
'pong',
'ping_delay_disconnect',
'destroy_session',
'destroy_session_ok',
'destroy_session_none',
//'new_session_created',
'msg_container',
'msg_copy',
'gzip_packed',
'http_wait',
'msgs_ack',
'bad_msg_notification',
'bad_server_salt',
'msgs_state_req',
'msgs_state_info',
'msgs_all_info',
'msg_detailed_info',
'msg_new_detailed_info',
'msg_resend_req',
'msg_resend_ans_req',
];
/**
* @internal
*/
const DEFAULT_GETUPDATES_PARAMS = ['offset' => 0, 'limit' => null, 'timeout' => 100];
/**
* Array of references to all instances of MTProto.

View File

@ -369,7 +369,7 @@ trait ResponseHandler
$this->logger->logger('If you intentionally deleted this account, ignore this message.', \danog\MadelineProto\Logger::FATAL_ERROR);
}
$this->API->resetSession();
\danog\MadelineProto\Tools::callFork((function () use (&$request, &$response): \Generator {
\danog\MadelineProto\Tools::callFork((function () use ($request, &$response): \Generator {
yield from $this->API->initAuthorization();
$this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], $request['_'] ?? ''));
})());
@ -378,7 +378,7 @@ trait ResponseHandler
case 'AUTH_KEY_INVALID':
if ($this->API->authorized !== MTProto::LOGGED_IN) {
$this->gotResponseForOutgoingMessageId($request_id);
\danog\MadelineProto\Tools::callFork((function () use (&$request, &$response): \Generator {
\danog\MadelineProto\Tools::callFork((function () use ($request, &$response): \Generator {
yield from $this->API->initAuthorization();
$this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], $request['_'] ?? ''));
})());
@ -403,7 +403,7 @@ trait ResponseHandler
$this->logger->logger('Then login again.', \danog\MadelineProto\Logger::FATAL_ERROR);
$this->logger->logger('If you intentionally deleted this account, ignore this message.', \danog\MadelineProto\Logger::FATAL_ERROR);
$this->API->resetSession();
\danog\MadelineProto\Tools::callFork((function () use (&$request, &$response): \Generator {
\danog\MadelineProto\Tools::callFork((function () use ($request, &$response): \Generator {
yield from $this->API->initAuthorization();
$this->handleReject($request, new \danog\MadelineProto\RPCErrorException($response['error_message'], $response['error_code'], $request['_'] ?? ''));
})());

View File

@ -19,8 +19,6 @@
namespace danog\MadelineProto\MTProtoSession;
use danog\MadelineProto\MTProto;
/**
* Manages sequence number.
*/
@ -55,6 +53,37 @@ trait SeqNoHandler
public function contentRelated($method): bool
{
$method = \is_array($method) && isset($method['_']) ? $method['_'] : $method;
return \is_string($method) ? !\in_array($method, MTProto::NOT_CONTENT_RELATED) : true;
return \is_string($method) ? !\in_array($method, [
//'rpc_result',
//'rpc_error',
'rpc_drop_answer',
'rpc_answer_unknown',
'rpc_answer_dropped_running',
'rpc_answer_dropped',
'get_future_salts',
'future_salt',
'future_salts',
'ping',
'pong',
'ping_delay_disconnect',
'destroy_session',
'destroy_session_ok',
'destroy_session_none',
//'new_session_created',
'msg_container',
'msg_copy',
'gzip_packed',
'http_wait',
'msgs_ack',
'bad_msg_notification',
'bad_server_salt',
'msgs_state_req',
'msgs_state_info',
'msgs_all_info',
'msg_detailed_info',
'msg_new_detailed_info',
'msg_resend_req',
'msg_resend_ans_req',
]) : true;
}
}

View File

@ -68,7 +68,7 @@ class MyTelegramOrgWrapper
/**
* Endpoint.
*/
const MY_TELEGRAM_URL = 'https://my.telegram.org';
private const MY_TELEGRAM_URL = 'https://my.telegram.org';
/**
* Sleep function.
*

View File

@ -28,6 +28,7 @@ use danog\MadelineProto\MTProtoTools\PasswordCalculator;
use danog\MadelineProto\MTProtoTools\ReferenceDatabase;
use danog\MadelineProto\MTProtoTools\UpdatesState;
use danog\MadelineProto\TL\TL;
use danog\MadelineProto\TL\TLCallback;
use danog\MadelineProto\TL\TLConstructors;
use danog\MadelineProto\TL\TLMethods;
use danog\MadelineProto\TON\ADNLConnection;
@ -44,63 +45,70 @@ use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\DocBlockFactory;
use ReflectionClass;
use ReflectionClassConstant;
use ReflectionMethod;
class PhpDocBuilder
{
private const DISALLOW = [
AnnotationsBuilder::class,
APIFactory::class,
APIWrapper::class,
AbstractAPIFactory::class,
Bug74586Exception::class,
Connection::class,
ContextConnector::class,
DataCenter::class,
DataCenterConnection::class,
DoHConnector::class,
DocsBuilder::class,
InternalDoc::class,
Lang::class,
LightState::class,
Magic::class,
PhpDocBuilder::class,
RSA::class,
Serialization::class,
SessionPaths::class,
SettingsEmpty::class,
SettingsAbstract::class,
Snitch::class,
AsyncConstruct::class,
Server::class, // Remove when done
VoIP::class,
Crypt::class,
NothingInTheSocketException::class,
GarbageCollector::class,
MinDatabase::class,
PasswordCalculator::class,
ReferenceDatabase::class,
UpdatesState::class,
TL::class,
TLConstructors::class,
TLMethods::class,
TLCallback::class,
ADNLConnection::class,
TAPIFactory::class,
TInternalDoc::class,
Lite::class,
\ArrayIterator::class,
];
private DocBlockFactory $factory;
public function __construct()
private string $output;
public function __construct(string $output)
{
$this->factory = DocBlockFactory::createInstance();
$this->output = $output;
}
public function run()
{
$classes = ClassFinder::getClassesInNamespace('danog\\MadelineProto', ClassFinder::RECURSIVE_MODE);
foreach ($classes as $class) {
if (\in_array($class, [
AnnotationsBuilder::class,
APIFactory::class,
APIWrapper::class,
AbstractAPIFactory::class,
Bug74586Exception::class,
Connection::class,
ContextConnector::class,
DataCenter::class,
DataCenterConnection::class,
DoHConnector::class,
DocsBuilder::class,
InternalDoc::class,
Lang::class,
LightState::class,
Magic::class,
PhpDocBuilder::class,
RSA::class,
Serialization::class,
SessionPaths::class,
SettingsEmpty::class,
SettingsAbstract::class,
Snitch::class,
AsyncConstruct::class,
Server::class, // Remove when done
VoIP::class,
Crypt::class,
NothingInTheSocketException::class,
GarbageCollector::class,
MinDatabase::class,
PasswordCalculator::class,
ReferenceDatabase::class,
UpdatesState::class,
TL::class,
TLConstructors::class,
TLMethods::class,
ADNLConnection::class,
TAPIFactory::class,
TInternalDoc::class,
Lite::class,
]) || str_starts_with($class, 'danog\\MadelineProto\\Ipc')
if (\in_array($class, self::DISALLOW) || str_starts_with($class, 'danog\\MadelineProto\\Ipc')
|| str_starts_with($class, 'danog\\MadelineProto\\Loop\\Update')
|| str_starts_with($class, 'danog\\MadelineProto\\Loop\\Connection')
|| str_starts_with($class, 'danog\\MadelineProto\\MTProto\\')
@ -117,9 +125,29 @@ class PhpDocBuilder
$this->generate(new ReflectionClass(DbPropertiesTrait::class));
}
/**
* Create directory recursively.
*
* @param string $file
* @return string
*/
private static function createDir(string $file): string
{
$dir = \dirname($file);
if (!\file_exists($dir)) {
$this->createDir($dir);
}
return $file;
}
private function generate(ReflectionClass $class): void
{
$name = $class->getName();
$fName = $this->output;
$fName .= \str_replace(['\\', 'danog\\MadelineProto'], ['/', ''], $name);
$fName .= '.md';
$handle = \fopen(self::createDir($fName), 'w+');
$doc = $class->getDocComment();
if (!$doc) {
throw new Exception("$name has no PHPDOC!");
@ -163,15 +191,48 @@ class PhpDocBuilder
}
}
fwrite($handle, "---\n");
fwrite($handle, "title: $name: $title\n");
fwrite($handle, "description: $description\n");
fwrite($handle, "image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png\n");
fwrite($handle, "---\n");
fwrite($handle, "# $name: $title\n");
fwrite($handle, "[Back to API index](index.md)\n\n");
fwrite($handle, "> Author: $author \n");
$constants = [];
foreach ($class->getConstants() as $key => $value) {
$refl = new ReflectionClassConstant($name, $key);
$doc = $this->factory->create($refl->getDocComment() ?? '');
if (!$refl->isPublic()) {
continue;
}
$description = '';
if ($refl->getDocComment()) {
$docConst = $this->factory->create($refl->getDocComment());
if (\in_array($refl->getDeclaringClass()->getName(), self::DISALLOW)) {
continue;
}
$description .= $docConst->getSummary();
if ($docConst->getDescription()) {
$description .= "\n\n";
$description .= $docConst->getDescription();
}
if ($docConst->getTagsByName('internal')) {
continue;
}
}
$description = \trim($description);
$constants[$key] = [
$value,
$description,
$doc->getDescription()
$description
];
}
$methods = [];
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
}
}
}

View File

@ -169,6 +169,10 @@ class Logger extends SettingsAbstract
*/
public function setExtra($extra): self
{
if ($this->type === MadelineProtoLogger::CALLABLE_LOGGER && !is_callable($extra)) {
$this->setType(MadelineProtoLogger::NO_LOGGER);
return $this;
}
$this->extra = $extra;
return $this;

View File

@ -37,7 +37,7 @@ use danog\MadelineProto\Stream\RawStreamInterface;
class BufferedRawStream implements BufferedStreamInterface, BufferInterface, RawStreamInterface
{
use RawStream;
const MAX_SIZE = 10 * 1024 * 1024;
private const MAX_SIZE = 10 * 1024 * 1024;
protected $stream;
protected $memory_stream;
private $append = '';

View File

@ -35,7 +35,7 @@ use danog\MadelineProto\Stream\RawStreamInterface;
*/
class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
const REPS = [0 => 'succeeded', 1 => 'general SOCKS server failure', 2 => 'connection not allowed by ruleset', 3 => 'Network unreachable', 4 => 'Host unreachable', 5 => 'Connection refused', 6 => 'TTL expired', 7 => 'Command not supported', 8 => 'Address type not supported'];
private const REPS = [0 => 'succeeded', 1 => 'general SOCKS server failure', 2 => 'connection not allowed by ruleset', 3 => 'Network unreachable', 4 => 'Host unreachable', 5 => 'Connection refused', 6 => 'TTL expired', 7 => 'Command not supported', 8 => 'Address type not supported'];
use RawStream;
/**
* Stream.

File diff suppressed because one or more lines are too long

View File

@ -25,18 +25,50 @@ namespace danog\MadelineProto\TL;
interface TLCallback
{
/**
*
* Called after serializing a method
*
* @internal
*
* @var int
*/
const METHOD_CALLBACK = 0;
/**
* Called before serializing a method
*
* @internal
*
* @var int
*/
const METHOD_BEFORE_CALLBACK = 1;
/**
* Called after serializing a constructor
*
* @internal
*
* @var int
*/
const CONSTRUCTOR_CALLBACK = 2;
/**
* Called before serializing a constructor
*
* @internal
*
* @var int
*/
const CONSTRUCTOR_BEFORE_CALLBACK = 3;
/**
* Called on constructor serialization
*
* @internal
*
* @var int
*/
const CONSTRUCTOR_SERIALIZE_CALLBACK = 4;
/**
* Called if objects of the specified type cannot be serialized.
*
* @internal
*
* @var int
*/
const TYPE_MISMATCH_CALLBACK = 5;