From 23e3c5b12ca1c3ca108f3a6968b0b8d939b385a0 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Sun, 5 Apr 2020 14:57:33 +0200 Subject: [PATCH] Apply misc fixes --- docs | 2 +- src/danog/MadelineProto/API.php | 4 - .../MadelineProto/AnnotationsBuilder.php | 3 +- src/danog/MadelineProto/CombinedAPI.php | 1 - src/danog/MadelineProto/Connection.php | 1 - src/danog/MadelineProto/ContextConnector.php | 2 +- src/danog/MadelineProto/DataCenter.php | 5 +- src/danog/MadelineProto/DocsBuilder.php | 1 - src/danog/MadelineProto/Exception.php | 4 - src/danog/MadelineProto/Logger.php | 10 -- .../Loop/Connection/ReadLoop.php | 11 +- .../Loop/Connection/WriteLoop.php | 11 +- src/danog/MadelineProto/Loop/Impl/Loop.php | 1 - .../Loop/Impl/ResumableSignalLoop.php | 2 - .../MadelineProto/Loop/Update/FeedLoop.php | 1 - .../MadelineProto/Loop/Update/SeqLoop.php | 1 - .../MadelineProto/Loop/Update/UpdateLoop.php | 1 - src/danog/MadelineProto/Lua.php | 3 + src/danog/MadelineProto/MTProto.php | 7 - .../MTProtoSession/CallHandler.php | 7 +- .../MsgIdHandler/MsgIdHandler32.php | 9 +- .../MTProtoSession/SeqNoHandler.php | 2 - .../MadelineProto/MTProtoSession/Session.php | 45 ++++++ .../MTProtoTools/AuthKeyHandler.php | 148 ++++++++---------- .../MadelineProto/MTProtoTools/Crypt.php | 22 +-- .../MadelineProto/MTProtoTools/Files.php | 5 +- .../MTProtoTools/MinDatabase.php | 2 - .../MTProtoTools/PasswordCalculator.php | 3 +- .../MTProtoTools/PeerHandler.php | 41 +++-- .../MTProtoTools/ReferenceDatabase.php | 3 +- src/danog/MadelineProto/Magic.php | 6 +- .../MadelineProto/MyTelegramOrgWrapper.php | 1 - src/danog/MadelineProto/RPCErrorException.php | 8 +- src/danog/MadelineProto/RSA.php | 1 - src/danog/MadelineProto/Serialization.php | 4 +- src/danog/MadelineProto/Shutdown.php | 2 +- .../MadelineProto/Stream/Common/CtrStream.php | 4 - .../Stream/Common/HashedBufferedStream.php | 6 - src/danog/MadelineProto/TL/TL.php | 8 +- src/danog/MadelineProto/TL/TLConstructors.php | 14 +- src/danog/MadelineProto/TL/TLMethods.php | 1 - src/danog/MadelineProto/Tools.php | 4 +- .../MadelineProto/Wrappers/DialogHandler.php | 2 +- 43 files changed, 188 insertions(+), 231 deletions(-) diff --git a/docs b/docs index eda40443..f49ae1bc 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit eda40443bf6215bc8eff7842a5eaaae70b4c4ee3 +Subproject commit f49ae1bcb6ade347ed852d7c588c740d595b09aa diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index 589e34f0..c29ce3dd 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -21,10 +21,6 @@ namespace danog\MadelineProto; use Amp\Promise; -if (!\defined('MADELINEPROTO_TEST')) { - \define('MADELINEPROTO_TEST', 'NOT PONY'); -} - /** * Main API wrapper for MadelineProto. */ diff --git a/src/danog/MadelineProto/AnnotationsBuilder.php b/src/danog/MadelineProto/AnnotationsBuilder.php index 0b09eff2..680cb180 100644 --- a/src/danog/MadelineProto/AnnotationsBuilder.php +++ b/src/danog/MadelineProto/AnnotationsBuilder.php @@ -26,7 +26,6 @@ use phpDocumentor\Reflection\DocBlockFactory; class AnnotationsBuilder { - use Tools; public function __construct(Logger $logger, array $settings, string $output, array $reflectionClasses, string $namespace) { $this->reflectionClasses = $reflectionClasses; @@ -145,6 +144,8 @@ class AnnotationsBuilder } $class = new \ReflectionClass($this->reflectionClasses['MTProto']); $methods = $class->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC); + $class = new \ReflectionClass(Tools::class); + $methods = \array_merge($methods, $class->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC)); foreach ($methods as $key => $method) { $name = $method->getName(); if ($method == 'methodCallAsyncRead') { diff --git a/src/danog/MadelineProto/CombinedAPI.php b/src/danog/MadelineProto/CombinedAPI.php index 2acf9b4b..cf1d589b 100644 --- a/src/danog/MadelineProto/CombinedAPI.php +++ b/src/danog/MadelineProto/CombinedAPI.php @@ -25,7 +25,6 @@ use function Amp\Promise\all; class CombinedAPI { use \danog\Serializable; - use Tools; public $session; public $instance_paths = []; public $instances = []; diff --git a/src/danog/MadelineProto/Connection.php b/src/danog/MadelineProto/Connection.php index 1b9c03af..d060362e 100644 --- a/src/danog/MadelineProto/Connection.php +++ b/src/danog/MadelineProto/Connection.php @@ -44,7 +44,6 @@ use danog\MadelineProto\Stream\Transport\WsStream; class Connection extends Session { use \danog\Serializable; - use Tools; /** * Writer loop. * diff --git a/src/danog/MadelineProto/ContextConnector.php b/src/danog/MadelineProto/ContextConnector.php index 88283979..23dab05f 100644 --- a/src/danog/MadelineProto/ContextConnector.php +++ b/src/danog/MadelineProto/ContextConnector.php @@ -55,7 +55,7 @@ class ContextConnector implements Connector $this->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING); return $result->getSocket(); } catch (\Throwable $e) { - if (\MADELINEPROTO_TEST === 'pony') { + if (\constant("MADELINEPROTO_TEST") === 'pony') { throw $e; } $this->logger->logger('Connection failed: ' . $e, \danog\MadelineProto\Logger::ERROR); diff --git a/src/danog/MadelineProto/DataCenter.php b/src/danog/MadelineProto/DataCenter.php index 866fe99a..a007cc90 100644 --- a/src/danog/MadelineProto/DataCenter.php +++ b/src/danog/MadelineProto/DataCenter.php @@ -59,7 +59,6 @@ use danog\MadelineProto\Stream\Transport\WsStream; */ class DataCenter { - use \danog\MadelineProto\Tools; use \danog\Serializable; /** * All socket connections to DCs. @@ -265,7 +264,7 @@ class DataCenter $this->API->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING); return true; } catch (\Throwable $e) { - if (\MADELINEPROTO_TEST === 'pony') { + if (\constant("MADELINEPROTO_TEST") === 'pony') { throw $e; } $this->API->logger->logger("Connection failed ({$dc_number}): ".$e->getMessage(), \danog\MadelineProto\Logger::ERROR); @@ -489,7 +488,7 @@ class DataCenter if (empty($ctxs)) { unset($this->sockets[$dc_number]); $this->API->logger->logger("No info for DC {$dc_number}", \danog\MadelineProto\Logger::ERROR); - } elseif (\MADELINEPROTO_TEST === 'pony') { + } elseif (\constant("MADELINEPROTO_TEST") === 'pony') { return [$ctxs[0]]; } return $ctxs; diff --git a/src/danog/MadelineProto/DocsBuilder.php b/src/danog/MadelineProto/DocsBuilder.php index 6173528f..4b5ff53b 100644 --- a/src/danog/MadelineProto/DocsBuilder.php +++ b/src/danog/MadelineProto/DocsBuilder.php @@ -26,7 +26,6 @@ class DocsBuilder { use \danog\MadelineProto\DocsBuilder\Methods; use \danog\MadelineProto\DocsBuilder\Constructors; - use Tools; public $td = false; public function __construct($logger, $settings) { diff --git a/src/danog/MadelineProto/Exception.php b/src/danog/MadelineProto/Exception.php index 3c5fed23..f0c809ea 100644 --- a/src/danog/MadelineProto/Exception.php +++ b/src/danog/MadelineProto/Exception.php @@ -22,7 +22,6 @@ namespace danog\MadelineProto; class Exception extends \Exception { use TL\PrettyException; - public static $rollbar = true; public function __toString() { return $this->file === 'MadelineProto' ? $this->message : '\\danog\\MadelineProto\\Exception'.($this->message !== '' ? ': ' : '').$this->message.' in '.$this->file.':'.$this->line.PHP_EOL.\danog\MadelineProto\Magic::$revision.PHP_EOL.'TL Trace:'.PHP_EOL.$this->getTLTrace(); @@ -48,9 +47,6 @@ class Exception extends \Exception if (\strpos($message, 'pg_query') !== false || \strpos($message, 'Undefined variable: ') !== false || \strpos($message, 'socket_write') !== false || \strpos($message, 'socket_read') !== false || \strpos($message, 'Received request to switch to DC ') !== false || \strpos($message, "Couldn't get response") !== false || \strpos($message, 'Re-executing query...') !== false || \strpos($message, "Couldn't find peer by provided") !== false || \strpos($message, 'id.pwrtelegram.xyz') !== false || \strpos($message, 'Please update ') !== false || \strpos($message, 'posix_isatty') !== false) { return; } - if (self::$rollbar && \class_exists('\\Rollbar\\Rollbar')) { - \Rollbar\Rollbar::log(\Rollbar\Payload\Level::error(), $this, \debug_backtrace(0)); - } } /** * Complain about missing extensions. diff --git a/src/danog/MadelineProto/Logger.php b/src/danog/MadelineProto/Logger.php index 47d8787f..6c738126 100644 --- a/src/danog/MadelineProto/Logger.php +++ b/src/danog/MadelineProto/Logger.php @@ -29,7 +29,6 @@ use function Amp\ByteStream\getStdout; */ class Logger { - use Tools; const FOREGROUND = ['default' => 39, 'black' => 30, 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'light_gray' => 37, 'dark_gray' => 90, 'light_red' => 91, 'light_green' => 92, 'light_yellow' => 93, 'light_blue' => 94, 'light_magenta' => 95, 'light_cyan' => 96, 'white' => 97]; const BACKGROUND = ['default' => 49, 'black' => 40, 'red' => 41, 'magenta' => 45, 'yellow' => 43, 'green' => 42, 'blue' => 44, 'cyan' => 46, 'light_gray' => 47, 'dark_gray' => 100, 'light_red' => 101, 'light_green' => 102, 'light_yellow' => 103, 'light_blue' => 104, 'light_magenta' => 105, 'light_cyan' => 106, 'white' => 107]; const SET = ['bold' => 1, 'dim' => 2, 'underlined' => 3, 'blink' => 4, 'reverse' => 5, 'hidden' => 6]; @@ -123,12 +122,6 @@ class Logger */ public static function getLoggerFromSettings(array $settings, string $prefix = ''): self { - if (isset($settings['logger']['rollbar_token']) && $settings['logger']['rollbar_token'] !== '' && \class_exists(\Rollbar\Rollbar::class)) { - @\Rollbar\Rollbar::init(['environment' => 'production', 'root' => __DIR__, 'access_token' => isset($settings['logger']['rollbar_token']) && !\in_array($settings['logger']['rollbar_token'], ['f9fff6689aea4905b58eec73f66c791d', '300afd7ccef346ea84d0c185ae831718', '11a8c2fe4c474328b40a28193f8d63f5', 'beef2d426496462ba34dcaad33d44a14']) || $settings['pwr']['pwr'] ? $settings['logger']['rollbar_token'] : 'c07d9b2f73c2461297b0beaef6c1662f'], false, false); - } else { - Exception::$rollbar = false; - RPCErrorException::$rollbar = false; - } if (!isset($settings['logger']['logger_param']) && isset($settings['logger']['param'])) { $settings['logger']['logger_param'] = $settings['logger']['param']; } @@ -264,9 +257,6 @@ class Logger return; } $prefix = $this->prefix; - if (\danog\MadelineProto\Magic::$has_thread && \is_object(\Thread::getCurrentThread())) { - $prefix .= ' (t)'; - } if ($param instanceof \Throwable) { $param = (string) $param; } elseif (!\is_string($param)) { diff --git a/src/danog/MadelineProto/Loop/Connection/ReadLoop.php b/src/danog/MadelineProto/Loop/Connection/ReadLoop.php index bd591574..fc4ec7aa 100644 --- a/src/danog/MadelineProto/Loop/Connection/ReadLoop.php +++ b/src/danog/MadelineProto/Loop/Connection/ReadLoop.php @@ -26,7 +26,6 @@ use Amp\Websocket\ClosedException; use danog\MadelineProto\Connection; use danog\MadelineProto\Logger; use danog\MadelineProto\Loop\Impl\SignalLoop; -use danog\MadelineProto\MTProtoTools\Crypt; use danog\MadelineProto\NothingInTheSocketException; use danog\MadelineProto\Tools; @@ -37,8 +36,6 @@ use danog\MadelineProto\Tools; */ class ReadLoop extends SignalLoop { - use Tools; - use Crypt; /** * Connection instance. * @@ -140,14 +137,14 @@ class ReadLoop extends SignalLoop $API->logger->logger($e->getReason()); if (\strpos($e->getReason(), ' ') === 0) { $payload = -\substr($e->getReason(), 7); - $API->logger->logger("Received {$payload} from DC " . $datacenter, \danog\MadelineProto\Logger::ERROR); + $API->logger->logger("Received {$payload} from DC ".$datacenter, \danog\MadelineProto\Logger::ERROR); return $payload; } throw $e; } if ($payload_length === 4) { $payload = \danog\MadelineProto\Tools::unpackSignedInt(yield $buffer->bufferRead(4)); - $API->logger->logger("Received {$payload} from DC " . $datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE); + $API->logger->logger("Received {$payload} from DC ".$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE); return $payload; } $connection->reading(true); @@ -210,7 +207,7 @@ class ReadLoop extends SignalLoop throw new \danog\MadelineProto\SecurityException('message_data_length not divisible by 4'); } $message_data = \substr($decrypted_data, 32, $message_data_length); - if ($message_key != \substr(\hash('sha256', \substr($shared->getTempAuthKey()->getAuthKey(), 96, 32) . $decrypted_data, true), 8, 16)) { + if ($message_key != \substr(\hash('sha256', \substr($shared->getTempAuthKey()->getAuthKey(), 96, 32).$decrypted_data, true), 8, 16)) { throw new \danog\MadelineProto\SecurityException('msg_key mismatch'); } $connection->incoming_messages[$message_id] = ['seq_no' => $seq_no]; @@ -224,7 +221,7 @@ class ReadLoop extends SignalLoop $connection->incoming_messages[$message_id]['response'] = -1; $connection->new_incoming[$message_id] = $message_id; //$connection->last_http_wait = 0; - $API->logger->logger('Received payload from DC ' . $datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE); + $API->logger->logger('Received payload from DC '.$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE); } finally { $connection->reading(false); } diff --git a/src/danog/MadelineProto/Loop/Connection/WriteLoop.php b/src/danog/MadelineProto/Loop/Connection/WriteLoop.php index 3ca49615..b34d036e 100644 --- a/src/danog/MadelineProto/Loop/Connection/WriteLoop.php +++ b/src/danog/MadelineProto/Loop/Connection/WriteLoop.php @@ -23,7 +23,6 @@ use Amp\ByteStream\StreamException; use danog\MadelineProto\Connection; use danog\MadelineProto\Logger; use danog\MadelineProto\Loop\Impl\ResumableSignalLoop; -use danog\MadelineProto\MTProtoTools\Crypt; use danog\MadelineProto\Tools; /** @@ -33,8 +32,6 @@ use danog\MadelineProto\Tools; */ class WriteLoop extends ResumableSignalLoop { - use Crypt; - use Tools; /** * Connection instance. * @@ -128,7 +125,7 @@ class WriteLoop extends ResumableSignalLoop $pad_length += 16 * \danog\MadelineProto\Tools::randomInt($modulus = 16); $pad = \danog\MadelineProto\Tools::random($pad_length); $buffer = yield $connection->stream->getWriteBuffer(8 + 8 + 4 + $pad_length + $length); - yield $buffer->bufferWrite("\0\0\0\0\0\0\0\0" . $message_id . \danog\MadelineProto\Tools::packUnsignedInt($length) . $message['serialized_body'] . $pad); + yield $buffer->bufferWrite("\0\0\0\0\0\0\0\0".$message_id.\danog\MadelineProto\Tools::packUnsignedInt($length).$message['serialized_body'].$pad); //var_dump("plain ".bin2hex($message_id)); $connection->httpSent(); $connection->outgoing_messages[$message_id] = $message; @@ -280,15 +277,15 @@ class WriteLoop extends ResumableSignalLoop return true; } unset($messages); - $plaintext = $shared->getTempAuthKey()->getServerSalt() . $connection->session_id . $message_id . \pack('VV', $seq_no, $message_data_length) . $message_data; + $plaintext = $shared->getTempAuthKey()->getServerSalt().$connection->session_id.$message_id.\pack('VV', $seq_no, $message_data_length).$message_data; $padding = \danog\MadelineProto\Tools::posmod(-\strlen($plaintext), 16); if ($padding < 12) { $padding += 16; } $padding = \danog\MadelineProto\Tools::random($padding); - $message_key = \substr(\hash('sha256', \substr($shared->getTempAuthKey()->getAuthKey(), 88, 32) . $plaintext . $padding, true), 8, 16); + $message_key = \substr(\hash('sha256', \substr($shared->getTempAuthKey()->getAuthKey(), 88, 32).$plaintext.$padding, true), 8, 16); list($aes_key, $aes_iv) = $this->aesCalculate($message_key, $shared->getTempAuthKey()->getAuthKey()); - $message = $shared->getTempAuthKey()->getID() . $message_key . $this->igeEncrypt($plaintext . $padding, $aes_key, $aes_iv); + $message = $shared->getTempAuthKey()->getID().$message_key.$this->igeEncrypt($plaintext.$padding, $aes_key, $aes_iv); $buffer = yield $connection->stream->getWriteBuffer($len = \strlen($message)); //$t = \microtime(true); yield $buffer->bufferWrite($message); diff --git a/src/danog/MadelineProto/Loop/Impl/Loop.php b/src/danog/MadelineProto/Loop/Impl/Loop.php index 6bb733f2..09a93614 100644 --- a/src/danog/MadelineProto/Loop/Impl/Loop.php +++ b/src/danog/MadelineProto/Loop/Impl/Loop.php @@ -32,7 +32,6 @@ use danog\MadelineProto\Loop\LoopInterface; */ abstract class Loop implements LoopInterface { - use \danog\MadelineProto\Tools; private $count = 0; /** * MTProto instance. diff --git a/src/danog/MadelineProto/Loop/Impl/ResumableSignalLoop.php b/src/danog/MadelineProto/Loop/Impl/ResumableSignalLoop.php index 34b5e5d4..aea21013 100644 --- a/src/danog/MadelineProto/Loop/Impl/ResumableSignalLoop.php +++ b/src/danog/MadelineProto/Loop/Impl/ResumableSignalLoop.php @@ -24,7 +24,6 @@ use Amp\Loop; use Amp\Promise; use Amp\Success; use danog\MadelineProto\Loop\ResumableLoopInterface; -use danog\MadelineProto\Tools; /** * Resumable signal loop helper trait. @@ -33,7 +32,6 @@ use danog\MadelineProto\Tools; */ abstract class ResumableSignalLoop extends SignalLoop implements ResumableLoopInterface { - use Tools; private $resume; private $pause; protected $resumeWatcher; diff --git a/src/danog/MadelineProto/Loop/Update/FeedLoop.php b/src/danog/MadelineProto/Loop/Update/FeedLoop.php index 0a6bfe62..6e933055 100644 --- a/src/danog/MadelineProto/Loop/Update/FeedLoop.php +++ b/src/danog/MadelineProto/Loop/Update/FeedLoop.php @@ -29,7 +29,6 @@ use danog\MadelineProto\Loop\Impl\ResumableSignalLoop; */ class FeedLoop extends ResumableSignalLoop { - use \danog\MadelineProto\Tools; private $incomingUpdates = []; private $parsedUpdates = []; private $channelId; diff --git a/src/danog/MadelineProto/Loop/Update/SeqLoop.php b/src/danog/MadelineProto/Loop/Update/SeqLoop.php index 40c7c967..8c18685c 100644 --- a/src/danog/MadelineProto/Loop/Update/SeqLoop.php +++ b/src/danog/MadelineProto/Loop/Update/SeqLoop.php @@ -28,7 +28,6 @@ use danog\MadelineProto\Loop\Impl\ResumableSignalLoop; */ class SeqLoop extends ResumableSignalLoop { - use \danog\MadelineProto\Tools; private $incomingUpdates = []; private $feeder; private $pendingWakeups = []; diff --git a/src/danog/MadelineProto/Loop/Update/UpdateLoop.php b/src/danog/MadelineProto/Loop/Update/UpdateLoop.php index 15c9da88..85de83e5 100644 --- a/src/danog/MadelineProto/Loop/Update/UpdateLoop.php +++ b/src/danog/MadelineProto/Loop/Update/UpdateLoop.php @@ -31,7 +31,6 @@ use danog\MadelineProto\RPCErrorException; */ class UpdateLoop extends ResumableSignalLoop { - use \danog\MadelineProto\Tools; private $toPts; private $channelId; private $feeder; diff --git a/src/danog/MadelineProto/Lua.php b/src/danog/MadelineProto/Lua.php index ddff00f6..5f8def07 100644 --- a/src/danog/MadelineProto/Lua.php +++ b/src/danog/MadelineProto/Lua.php @@ -42,6 +42,9 @@ class Lua } public function __wakeup() { + if (!\class_exists(\Lua::class)) { + throw Exception::extension('lua'); + } $this->Lua = new \Lua($this->script); $this->madelineproto_lua = 1; $this->Lua->registerCallback('tdcliFunction', [$this, 'tdcliFunction']); diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 82b55a09..ac34c07d 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -46,7 +46,6 @@ class MTProto extends AsyncConstruct implements TLCallback use \danog\Serializable; use \danog\MadelineProto\MTProtoTools\AuthKeyHandler; use \danog\MadelineProto\MTProtoTools\CallHandler; - use \danog\MadelineProto\MTProtoTools\Crypt; use \danog\MadelineProto\MTProtoTools\PeerHandler; use \danog\MadelineProto\MTProtoTools\UpdateHandler; use \danog\MadelineProto\MTProtoTools\Files; @@ -58,7 +57,6 @@ class MTProto extends AsyncConstruct implements TLCallback use \danog\MadelineProto\TL\Conversion\BotAPIFiles; use \danog\MadelineProto\TL\Conversion\Extension; use \danog\MadelineProto\TL\Conversion\TD; - use \danog\MadelineProto\Tools; use \danog\MadelineProto\VoIP\AuthKeyHandler; use \danog\MadelineProto\Wrappers\DialogHandler; use \danog\MadelineProto\Wrappers\Events; @@ -858,10 +856,6 @@ class MTProto extends AsyncConstruct implements TLCallback Magic::classExists(); // Setup logger $this->setupLogger(); - // We don't like threads - if (Magic::$has_thread && \is_object(\Thread::getCurrentThread())) { - return; - } // Setup language Lang::$current_lang =& Lang::$lang['en']; if (Lang::$lang[$this->settings['app_info']['lang_code'] ?? 'en'] ?? false) { @@ -1218,7 +1212,6 @@ class MTProto extends AsyncConstruct implements TLCallback 'logger_level' => Logger::VERBOSE, 'max_size' => 100 * 1024 * 1024, // Logging level, available logging levels are: ULTRA_VERBOSE, VERBOSE, NOTICE, WARNING, ERROR, FATAL_ERROR. Can be provided as last parameter to the logging function. - 'rollbar_token' => '', ], 'max_tries' => [ 'query' => 5, // How many times should I try to call a method or send an object before throwing an exception diff --git a/src/danog/MadelineProto/MTProtoSession/CallHandler.php b/src/danog/MadelineProto/MTProtoSession/CallHandler.php index 84544900..a8c7dfad 100644 --- a/src/danog/MadelineProto/MTProtoSession/CallHandler.php +++ b/src/danog/MadelineProto/MTProtoSession/CallHandler.php @@ -50,13 +50,12 @@ trait CallHandler foreach ($message_ids as $message_id) { if (isset($this->outgoing_messages[$message_id]['body'])) { if ($datacenter) { - $res = Tools::call($this->API->datacenter->waitGetConnection($datacenter))->onResolve(function ($e, $r) use ($message_id) { - return $r->sendMessage($this->outgoing_messages[$message_id], false); + Tools::call($this->API->datacenter->waitGetConnection($datacenter))->onResolve(function ($e, $r) use ($message_id) { + Tools::callFork($r->sendMessage($this->outgoing_messages[$message_id], false)); }); } else { - $res = $this->sendMessage($this->outgoing_messages[$message_id], false); + Tools::callFork($this->sendMessage($this->outgoing_messages[$message_id], false)); } - \danog\MadelineProto\Tools::callFork($res); $this->ackOutgoingMessageId($message_id); $this->gotResponseForOutgoingMessageId($message_id); } else { diff --git a/src/danog/MadelineProto/MTProtoSession/MsgIdHandler/MsgIdHandler32.php b/src/danog/MadelineProto/MTProtoSession/MsgIdHandler/MsgIdHandler32.php index b29db062..5931396d 100644 --- a/src/danog/MadelineProto/MTProtoSession/MsgIdHandler/MsgIdHandler32.php +++ b/src/danog/MadelineProto/MTProtoSession/MsgIdHandler/MsgIdHandler32.php @@ -20,6 +20,7 @@ namespace danog\MadelineProto\MTProtoSession\MsgIdHandler; use danog\MadelineProto\MTProtoSession\MsgIdHandler; +use tgseclib\Math\BigInteger; /** * Manages message ids. @@ -48,13 +49,13 @@ class MsgIdHandler32 extends MsgIdHandler */ public function checkMessageId($newMessageId, array $aargs): void { - $newMessageId = \is_object($newMessageId) ? $newMessageId : new \tgseclib\Math\BigInteger(\strrev($newMessageId), 256); + $newMessageId = \is_object($newMessageId) ? $newMessageId : new BigInteger(\strrev($newMessageId), 256); - $minMessageId = (new \tgseclib\Math\BigInteger(\time() + $this->session->time_delta - 300))->bitwise_leftShift(32); + $minMessageId = (new BigInteger(\time() + $this->session->time_delta - 300))->bitwise_leftShift(32); if ($minMessageId->compare($newMessageId) > 0) { $this->session->API->logger->logger('Given message id ('.$newMessageId.') is too old compared to the min value ('.$minMessageId.').', \danog\MadelineProto\Logger::WARNING); } - $maxMessageId = (new \tgseclib\Math\BigInteger(\time() + $this->session->time_delta + 30))->bitwise_leftShift(32); + $maxMessageId = (new BigInteger(\time() + $this->session->time_delta + 30))->bitwise_leftShift(32); if ($maxMessageId->compare($newMessageId) < 0) { throw new \danog\MadelineProto\Exception('Given message id ('.$newMessageId.') is too new compared to the max value ('.$maxMessageId.'). Consider syncing your date.'); } @@ -106,7 +107,7 @@ class MsgIdHandler32 extends MsgIdHandler */ public function generateMessageId(): string { - $message_id = (new \tgseclib\Math\BigInteger(\time() + $this->session->time_delta))->bitwise_leftShift(32); + $message_id = (new BigInteger(\time() + $this->session->time_delta))->bitwise_leftShift(32); if ($message_id->compare($key = $this->getMaxId($incoming = false)) <= 0) { $message_id = $key->add(\danog\MadelineProto\Magic::$four); } diff --git a/src/danog/MadelineProto/MTProtoSession/SeqNoHandler.php b/src/danog/MadelineProto/MTProtoSession/SeqNoHandler.php index 9b90a865..b75b7b34 100644 --- a/src/danog/MadelineProto/MTProtoSession/SeqNoHandler.php +++ b/src/danog/MadelineProto/MTProtoSession/SeqNoHandler.php @@ -42,8 +42,6 @@ trait SeqNoHandler $type = isset($this->incoming_messages[$current_msg_id]['content']['_']) ? $this->incoming_messages[$current_msg_id]['content']['_'] : '-'; if (isset($this->incoming_messages[$current_msg_id]['seq_no']) && ($seq_no = $this->generateInSeqNo($this->contentRelated($this->incoming_messages[$current_msg_id]['content']))) !== $this->incoming_messages[$current_msg_id]['seq_no']) { $this->API->logger->logger('SECURITY WARNING: Seqno mismatch (should be ' . $seq_no . ', is ' . $this->incoming_messages[$current_msg_id]['seq_no'] . ', ' . $type . ')', \danog\MadelineProto\Logger::ULTRA_VERBOSE); - } elseif (isset($seq_no)) { - $this->API->logger->logger('Seqno OK (should be ' . $seq_no . ', is ' . $this->incoming_messages[$current_msg_id]['seq_no'] . ', ' . $type . ')', \danog\MadelineProto\Logger::ULTRA_VERBOSE); } } public function generateInSeqNo($contentRelated) diff --git a/src/danog/MadelineProto/MTProtoSession/Session.php b/src/danog/MadelineProto/MTProtoSession/Session.php index 48669a54..02d26a13 100644 --- a/src/danog/MadelineProto/MTProtoSession/Session.php +++ b/src/danog/MadelineProto/MTProtoSession/Session.php @@ -28,14 +28,59 @@ abstract class Session use ResponseHandler; use SeqNoHandler; use CallHandler; + /** + * Incoming message array. + * + * @var array + */ public $incoming_messages = []; + /** + * Outgoing message array. + * + * @var array + */ public $outgoing_messages = []; + /** + * New incoming message ID array. + * + * @var array + */ public $new_incoming = []; + /** + * New outgoing message ID array. + * + * @var array + */ public $new_outgoing = []; + /** + * Pending outgoing messages. + * + * @var array + */ public $pending_outgoing = []; + /** + * Pending outgoing key. + * + * @var string + */ public $pending_outgoing_key = 'a'; + /** + * Time delta with server. + * + * @var integer + */ public $time_delta = 0; + /** + * Call queue. + * + * @var array + */ public $call_queue = []; + /** + * Ack queue. + * + * @var array + */ public $ack_queue = []; /** * Message ID handler. diff --git a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php index cd0fd64a..b832eec0 100644 --- a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php @@ -21,9 +21,11 @@ namespace danog\MadelineProto\MTProtoTools; use Amp\Http\Client\Request; use danog\MadelineProto\DataCenterConnection; +use danog\MadelineProto\MTProto; use danog\MadelineProto\MTProto\AuthKey; use danog\MadelineProto\MTProto\PermAuthKey; use danog\MadelineProto\MTProto\TempAuthKey; +use danog\PrimeModule; use tgseclib\Math\BigInteger; /** @@ -108,69 +110,41 @@ trait AuthKeyHandler * *********************************************************************** * Compute p and q */ - $pq = new \tgseclib\Math\BigInteger((string) $pq_bytes, 256); - $q = new \tgseclib\Math\BigInteger(0); - $p = new \tgseclib\Math\BigInteger(@\danog\PrimeModule::auto_single($pq->__toString())); - if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { - $q = $pq->divide($p)[0]; - if ($p->compare($q) > 0) { - list($p, $q) = [$q, $p]; + $pq = (string) new BigInteger((string) $pq_bytes, 256); + foreach ([ + 'auto_single', + 'native_single_cpp', + 'python_single_alt', + 'python_single', + 'native_single', + 'wolfram' + ] as $method) { + $this->logger->logger("Factorizing with $method"); + + $q = new BigInteger(0); + try { + if ($method === 'wolfram') { + $p = new BigInteger(yield from $this->wolframSingle($pq)); + } else { + $p = new BigInteger(@PrimeModule::$method($pq)); + } + } catch (\Throwable $e) { + $this->logger->logger("While factorizing with $method: $e"); } - } - if (!$pq->equals($p->multiply($q))) { - $this->logger->logger('Automatic factorization failed, trying native CPP module', \danog\MadelineProto\Logger::ERROR); - $p = new \tgseclib\Math\BigInteger(@\danog\PrimeModule::native_single_cpp($pq->__toString())); if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { $q = $pq->divide($p)[0]; if ($p->compare($q) > 0) { list($p, $q) = [$q, $p]; } } - if (!$pq->equals($p->multiply($q))) { - $this->logger->logger('Automatic factorization failed, trying alt py module', \danog\MadelineProto\Logger::ERROR); - $p = new \tgseclib\Math\BigInteger(@\danog\PrimeModule::python_single_alt($pq->__toString())); - if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { - $q = $pq->divide($p)[0]; - if ($p->compare($q) > 0) { - list($p, $q) = [$q, $p]; - } - } - if (!$pq->equals($p->multiply($q))) { - $this->logger->logger('Automatic factorization failed, trying py module', \danog\MadelineProto\Logger::ERROR); - $p = new \tgseclib\Math\BigInteger(@\danog\PrimeModule::python_single($pq->__toString())); - if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { - $q = $pq->divide($p)[0]; - if ($p->compare($q) > 0) { - list($p, $q) = [$q, $p]; - } - } - if (!$pq->equals($p->multiply($q))) { - $this->logger->logger('Automatic factorization failed, trying native module', \danog\MadelineProto\Logger::ERROR); - $p = new \tgseclib\Math\BigInteger(@\danog\PrimeModule::native_single($pq->__toString())); - if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { - $q = $pq->divide($p)[0]; - if ($p->compare($q) > 0) { - list($p, $q) = [$q, $p]; - } - } - if (!$pq->equals($p->multiply($q))) { - $this->logger->logger('Automatic factorization failed, trying wolfram module', \danog\MadelineProto\Logger::ERROR); - $p = new \tgseclib\Math\BigInteger(yield from $this->wolframSingle($pq->__toString())); - if (!$p->equals(\danog\MadelineProto\Magic::$zero)) { - $q = $pq->divide($p)[0]; - if ($p->compare($q) > 0) { - list($p, $q) = [$q, $p]; - } - } - if (!$pq->equals($p->multiply($q))) { - throw new \danog\MadelineProto\SecurityException("Couldn't compute p and q, install prime.madelineproto.xyz to fix. Original pq: {$pq}, computed p: {$p}, computed q: {$q}, computed pq: " . $p->multiply($q)); - } - } - } - } + if ($pq->equals($p->multiply($q))) { + break; } } - $this->logger->logger('Factorization ' . $pq . ' = ' . $p . ' * ' . $q, \danog\MadelineProto\Logger::VERBOSE); + if (!$pq->equals($p->multiply($q))) { + throw new \danog\MadelineProto\SecurityException("Couldn't compute p and q, install prime.madelineproto.xyz to fix. Original pq: {$pq}, computed p: {$p}, computed q: {$q}, computed pq: ".$p->multiply($q)); + } + $this->logger->logger('Factorization '.$pq.' = '.$p.' * '.$q, \danog\MadelineProto\Logger::VERBOSE); /* * *********************************************************************** * Serialize object for req_DH_params @@ -178,7 +152,7 @@ trait AuthKeyHandler $p_bytes = $p->toBytes(); $q_bytes = $q->toBytes(); $new_nonce = \danog\MadelineProto\Tools::random(32); - $data_unserialized = ['_' => 'p_q_inner_data' . ($expires_in < 0 ? '' : '_temp'), '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)]; + $data_unserialized = ['_' => 'p_q_inner_data'.($expires_in < 0 ? '' : '_temp'), '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 from $this->TL->serializeObject(['type' => ''], $data_unserialized, 'p_q_inner_data')); /* * *********************************************************************** @@ -186,7 +160,7 @@ trait AuthKeyHandler */ $sha_digest = \sha1($p_q_inner_data, true); $random_bytes = \danog\MadelineProto\Tools::random(255 - \strlen($p_q_inner_data) - \strlen($sha_digest)); - $to_encrypt = $sha_digest . $p_q_inner_data . $random_bytes; + $to_encrypt = $sha_digest.$p_q_inner_data.$random_bytes; $encrypted_data = $key->encrypt($to_encrypt); $this->logger->logger('Starting Diffie Hellman key exchange', \danog\MadelineProto\Logger::VERBOSE); /* @@ -237,8 +211,8 @@ trait AuthKeyHandler * Get key, iv and decrypt answer */ $encrypted_answer = $server_dh_params['encrypted_answer']; - $tmp_aes_key = \sha1($new_nonce . $server_nonce, true) . \substr(\sha1($server_nonce . $new_nonce, true), 0, 12); - $tmp_aes_iv = \substr(\sha1($server_nonce . $new_nonce, true), 12, 8) . \sha1($new_nonce . $new_nonce, true) . \substr($new_nonce, 0, 4); + $tmp_aes_key = \sha1($new_nonce.$server_nonce, true).\substr(\sha1($server_nonce.$new_nonce, true), 0, 12); + $tmp_aes_iv = \substr(\sha1($server_nonce.$new_nonce, true), 12, 8).\sha1($new_nonce.$new_nonce, true).\substr($new_nonce, 0, 4); $answer_with_hash = $this->igeDecrypt($encrypted_answer, $tmp_aes_key, $tmp_aes_iv); /* * *********************************************************************** @@ -273,9 +247,9 @@ trait AuthKeyHandler if ($server_nonce != $server_DH_inner_data['server_nonce']) { throw new \danog\MadelineProto\SecurityException('wrong server nonce'); } - $g = new \tgseclib\Math\BigInteger($server_DH_inner_data['g']); - $g_a = new \tgseclib\Math\BigInteger((string) $server_DH_inner_data['g_a'], 256); - $dh_prime = new \tgseclib\Math\BigInteger((string) $server_DH_inner_data['dh_prime'], 256); + $g = new BigInteger($server_DH_inner_data['g']); + $g_a = new BigInteger((string) $server_DH_inner_data['g_a'], 256); + $dh_prime = new BigInteger((string) $server_DH_inner_data['dh_prime'], 256); /* * *********************************************************************** * Time delta @@ -287,7 +261,7 @@ trait AuthKeyHandler $this->checkG($g_a, $dh_prime); for ($retry_id = 0; $retry_id <= $this->settings['max_tries']['authorization']; $retry_id++) { $this->logger->logger('Generating b...', \danog\MadelineProto\Logger::VERBOSE); - $b = new \tgseclib\Math\BigInteger(\danog\MadelineProto\Tools::random(256), 256); + $b = new BigInteger(\danog\MadelineProto\Tools::random(256), 256); $this->logger->logger('Generating g_b...', \danog\MadelineProto\Logger::VERBOSE); $g_b = $g->powMod($b, $dh_prime); $this->checkG($g_b, $dh_prime); @@ -318,8 +292,8 @@ trait AuthKeyHandler * *********************************************************************** * encrypt client_DH_inner_data */ - $data_with_sha = \sha1($data, true) . $data; - $data_with_sha_padded = $data_with_sha . \danog\MadelineProto\Tools::random(\danog\MadelineProto\Tools::posmod(-\strlen($data_with_sha), 16)); + $data_with_sha = \sha1($data, true).$data; + $data_with_sha_padded = $data_with_sha.\danog\MadelineProto\Tools::random(\danog\MadelineProto\Tools::posmod(-\strlen($data_with_sha), 16)); $encrypted_data = $this->igeEncrypt($data_with_sha_padded, $tmp_aes_key, $tmp_aes_iv); $this->logger->logger('Executing set_client_DH_params...', \danog\MadelineProto\Logger::VERBOSE); /* @@ -349,9 +323,9 @@ trait AuthKeyHandler $auth_key_str = $auth_key->toBytes(); $auth_key_sha = \sha1($auth_key_str, true); $auth_key_aux_hash = \substr($auth_key_sha, 0, 8); - $new_nonce_hash1 = \substr(\sha1($new_nonce . \chr(1) . $auth_key_aux_hash, true), -16); - $new_nonce_hash2 = \substr(\sha1($new_nonce . \chr(2) . $auth_key_aux_hash, true), -16); - $new_nonce_hash3 = \substr(\sha1($new_nonce . \chr(3) . $auth_key_aux_hash, true), -16); + $new_nonce_hash1 = \substr(\sha1($new_nonce.\chr(1).$auth_key_aux_hash, true), -16); + $new_nonce_hash2 = \substr(\sha1($new_nonce.\chr(2).$auth_key_aux_hash, true), -16); + $new_nonce_hash3 = \substr(\sha1($new_nonce.\chr(3).$auth_key_aux_hash, true), -16); /* * *********************************************************************** * Check if the client's nonce and the server's nonce are the same @@ -403,14 +377,14 @@ trait AuthKeyHandler } } } catch (\danog\MadelineProto\SecurityException $e) { - $this->logger->logger('An exception occurred while generating the authorization key: ' . $e->getMessage() . ' in ' . \basename($e->getFile(), '.php') . ' on line ' . $e->getLine() . '. Retrying...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An exception occurred while generating the authorization key: '.$e->getMessage().' in '.\basename($e->getFile(), '.php').' on line '.$e->getLine().'. Retrying...', \danog\MadelineProto\Logger::WARNING); } catch (\danog\MadelineProto\Exception $e) { - $this->logger->logger('An exception occurred while generating the authorization key: ' . $e->getMessage() . ' in ' . \basename($e->getFile(), '.php') . ' on line ' . $e->getLine() . '. Retrying...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An exception occurred while generating the authorization key: '.$e->getMessage().' in '.\basename($e->getFile(), '.php').' on line '.$e->getLine().'. Retrying...', \danog\MadelineProto\Logger::WARNING); $req_pq = $req_pq === 'req_pq_multi' ? 'req_pq' : 'req_pq_multi'; } catch (\danog\MadelineProto\RPCErrorException $e) { - $this->logger->logger('An RPCErrorException occurred while generating the authorization key: ' . $e->getMessage() . ' Retrying (try number ' . $retry_id_total . ')...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An RPCErrorException occurred while generating the authorization key: '.$e->getMessage().' Retrying (try number '.$retry_id_total.')...', \danog\MadelineProto\Logger::WARNING); } catch (\Throwable $e) { - $this->logger->logger('An exception occurred while generating the authorization key: ' . $e . PHP_EOL . ' Retrying (try number ' . $retry_id_total . ')...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An exception occurred while generating the authorization key: '.$e.PHP_EOL.' Retrying (try number '.$retry_id_total.')...', \danog\MadelineProto\Logger::WARNING); } } if (!$cdn) { @@ -512,8 +486,8 @@ trait AuthKeyHandler $this->logger->logger('DH configuration not modified', \danog\MadelineProto\Logger::VERBOSE); return $this->dh_config; } - $dh_config['p'] = new \tgseclib\Math\BigInteger((string) $dh_config['p'], 256); - $dh_config['g'] = new \tgseclib\Math\BigInteger($dh_config['g']); + $dh_config['p'] = new BigInteger((string) $dh_config['p'], 256); + $dh_config['g'] = new BigInteger($dh_config['g']); $this->checkPG($dh_config['p'], $dh_config['g']); return $this->dh_config = $dh_config; } @@ -542,24 +516,24 @@ trait AuthKeyHandler $message_data = (yield from $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->msgIdHandler->generateMessageId(); $seq_no = 0; - $encrypted_data = \danog\MadelineProto\Tools::random(16) . $message_id . \pack('VV', $seq_no, \strlen($message_data)) . $message_data; + $encrypted_data = \danog\MadelineProto\Tools::random(16).$message_id.\pack('VV', $seq_no, \strlen($message_data)).$message_data; $message_key = \substr(\sha1($encrypted_data, true), -16); $padding = \danog\MadelineProto\Tools::random(\danog\MadelineProto\Tools::posmod(-\strlen($encrypted_data), 16)); list($aes_key, $aes_iv) = $this->oldAesCalculate($message_key, $datacenterConnection->getPermAuthKey()->getAuthKey()); - $encrypted_message = $datacenterConnection->getPermAuthKey()->getID() . $message_key . $this->igeEncrypt($encrypted_data . $padding, $aes_key, $aes_iv); + $encrypted_message = $datacenterConnection->getPermAuthKey()->getID().$message_key.$this->igeEncrypt($encrypted_data.$padding, $aes_key, $aes_iv); $res = yield from $connection->methodCallAsyncRead('auth.bindTempAuthKey', ['perm_auth_key_id' => $perm_auth_key_id, 'nonce' => $nonce, 'expires_at' => $expires_at, 'encrypted_message' => $encrypted_message], ['msg_id' => $message_id]); if ($res === true) { - $this->logger->logger('Bound temporary and permanent authorization keys, DC ' . $datacenter, \danog\MadelineProto\Logger::NOTICE); + $this->logger->logger('Bound temporary and permanent authorization keys, DC '.$datacenter, \danog\MadelineProto\Logger::NOTICE); $datacenterConnection->bind(); $datacenterConnection->flush(); return true; } } catch (\danog\MadelineProto\SecurityException $e) { - $this->logger->logger('An exception occurred while generating the authorization key: ' . $e->getMessage() . ' Retrying (try number ' . $retry_id_total . ')...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An exception occurred while generating the authorization key: '.$e->getMessage().' Retrying (try number '.$retry_id_total.')...', \danog\MadelineProto\Logger::WARNING); } catch (\danog\MadelineProto\Exception $e) { - $this->logger->logger('An exception occurred while generating the authorization key: ' . $e->getMessage() . ' Retrying (try number ' . $retry_id_total . ')...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An exception occurred while generating the authorization key: '.$e->getMessage().' Retrying (try number '.$retry_id_total.')...', \danog\MadelineProto\Logger::WARNING); } catch (\danog\MadelineProto\RPCErrorException $e) { - $this->logger->logger('An RPCErrorException occurred while generating the authorization key: ' . $e->getMessage() . ' Retrying (try number ' . $retry_id_total . ')...', \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('An RPCErrorException occurred while generating the authorization key: '.$e->getMessage().' Retrying (try number '.$retry_id_total.')...', \danog\MadelineProto\Logger::WARNING); } } throw new \danog\MadelineProto\SecurityException('An error occurred while binding temporary and permanent authorization keys.'); @@ -574,11 +548,11 @@ trait AuthKeyHandler private function wolframSingle($what): \Generator { $code = (yield from $this->datacenter->fileGetContents('http://www.wolframalpha.com/api/v1/code')); - $query = 'Do prime factorization of ' . $what; + $query = 'Do prime factorization of '.$what; $params = ['async' => true, 'banners' => 'raw', 'debuggingdata' => false, 'format' => 'moutput', 'formattimeout' => 8, 'input' => $query, 'output' => 'JSON', 'proxycode' => \json_decode($code, true)['code']]; - $url = 'https://www.wolframalpha.com/input/json.jsp?' . \http_build_query($params); + $url = 'https://www.wolframalpha.com/input/json.jsp?'.\http_build_query($params); $request = new Request($url); - $request->setHeader('referer', 'https://www.wolframalpha.com/input/?i=' . \urlencode($query)); + $request->setHeader('referer', 'https://www.wolframalpha.com/input/?i='.\urlencode($query)); $res = \json_decode(yield (yield $this->datacenter->getHTTPClient()->request($request))->getBody()->buffer(), true); if (!isset($res['queryresult']['pods'])) { return false; @@ -737,22 +711,22 @@ trait AuthKeyHandler return false; } $socket = $this->datacenter->getDataCenterConnection($id); - if ($this->authorized === self::LOGGED_IN && !$socket->isAuthorized()) { + if ($this->authorized === MTProto::LOGGED_IN && !$socket->isAuthorized()) { foreach ($this->datacenter->getDataCenterConnections() as $authorized_dc_id => $authorized_socket) { if ($this->authorized_dc !== -1 && $authorized_dc_id !== $this->authorized_dc) { continue; } - if ($authorized_socket->hasTempAuthKey() && $authorized_socket->hasPermAuthKey() && $authorized_socket->isAuthorized() && $this->authorized === self::LOGGED_IN && !$socket->isAuthorized() && !$authorized_socket->isCDN()) { + if ($authorized_socket->hasTempAuthKey() && $authorized_socket->hasPermAuthKey() && $authorized_socket->isAuthorized() && $this->authorized === MTProto::LOGGED_IN && !$socket->isAuthorized() && !$authorized_socket->isCDN()) { try { - $this->logger->logger('Trying to copy authorization from dc ' . $authorized_dc_id . ' to dc ' . $id); + $this->logger->logger('Trying to copy authorization from dc '.$authorized_dc_id.' to dc '.$id); $exported_authorization = yield from $this->methodCallAsyncRead('auth.exportAuthorization', ['dc_id' => \preg_replace('|_.*|', '', $id)], ['datacenter' => $authorized_dc_id]); $authorization = yield from $this->methodCallAsyncRead('auth.importAuthorization', $exported_authorization, ['datacenter' => $id]); $socket->authorized(true); break; } catch (\danog\MadelineProto\Exception $e) { - $this->logger->logger('Failure while syncing authorization from DC ' . $authorized_dc_id . ' to DC ' . $id . ': ' . $e->getMessage(), \danog\MadelineProto\Logger::ERROR); + $this->logger->logger('Failure while syncing authorization from DC '.$authorized_dc_id.' to DC '.$id.': '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR); } catch (\danog\MadelineProto\RPCErrorException $e) { - $this->logger->logger('Failure while syncing authorization from DC ' . $authorized_dc_id . ' to DC ' . $id . ': ' . $e->getMessage(), \danog\MadelineProto\Logger::ERROR); + $this->logger->logger('Failure while syncing authorization from DC '.$authorized_dc_id.' to DC '.$id.': '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR); if ($e->rpc === 'DC_ID_INVALID') { break; } diff --git a/src/danog/MadelineProto/MTProtoTools/Crypt.php b/src/danog/MadelineProto/MTProtoTools/Crypt.php index d094f9db..4192fe01 100644 --- a/src/danog/MadelineProto/MTProtoTools/Crypt.php +++ b/src/danog/MadelineProto/MTProtoTools/Crypt.php @@ -19,7 +19,7 @@ namespace danog\MadelineProto\MTProtoTools; -trait Crypt +abstract class Crypt { /** * AES KDF function for MTProto v2. @@ -35,10 +35,10 @@ trait Crypt public static function aesCalculate(string $msg_key, string $auth_key, bool $to_server = true): array { $x = $to_server ? 0 : 8; - $sha256_a = \hash('sha256', $msg_key . \substr($auth_key, $x, 36), true); - $sha256_b = \hash('sha256', \substr($auth_key, 40 + $x, 36) . $msg_key, true); - $aes_key = \substr($sha256_a, 0, 8) . \substr($sha256_b, 8, 16) . \substr($sha256_a, 24, 8); - $aes_iv = \substr($sha256_b, 0, 8) . \substr($sha256_a, 8, 16) . \substr($sha256_b, 24, 8); + $sha256_a = \hash('sha256', $msg_key.\substr($auth_key, $x, 36), true); + $sha256_b = \hash('sha256', \substr($auth_key, 40 + $x, 36).$msg_key, true); + $aes_key = \substr($sha256_a, 0, 8).\substr($sha256_b, 8, 16).\substr($sha256_a, 24, 8); + $aes_iv = \substr($sha256_b, 0, 8).\substr($sha256_a, 8, 16).\substr($sha256_b, 24, 8); return [$aes_key, $aes_iv]; } /** @@ -55,12 +55,12 @@ trait Crypt public static function oldAesCalculate(string $msg_key, string $auth_key, bool $to_server = true): array { $x = $to_server ? 0 : 8; - $sha1_a = \sha1($msg_key . \substr($auth_key, $x, 32), true); - $sha1_b = \sha1(\substr($auth_key, 32 + $x, 16) . $msg_key . \substr($auth_key, 48 + $x, 16), true); - $sha1_c = \sha1(\substr($auth_key, 64 + $x, 32) . $msg_key, true); - $sha1_d = \sha1($msg_key . \substr($auth_key, 96 + $x, 32), true); - $aes_key = \substr($sha1_a, 0, 8) . \substr($sha1_b, 8, 12) . \substr($sha1_c, 4, 12); - $aes_iv = \substr($sha1_a, 8, 12) . \substr($sha1_b, 0, 8) . \substr($sha1_c, 16, 4) . \substr($sha1_d, 0, 8); + $sha1_a = \sha1($msg_key.\substr($auth_key, $x, 32), true); + $sha1_b = \sha1(\substr($auth_key, 32 + $x, 16).$msg_key.\substr($auth_key, 48 + $x, 16), true); + $sha1_c = \sha1(\substr($auth_key, 64 + $x, 32).$msg_key, true); + $sha1_d = \sha1($msg_key.\substr($auth_key, 96 + $x, 32), true); + $aes_key = \substr($sha1_a, 0, 8).\substr($sha1_b, 8, 12).\substr($sha1_c, 4, 12); + $aes_iv = \substr($sha1_a, 8, 12).\substr($sha1_b, 0, 8).\substr($sha1_c, 16, 4).\substr($sha1_d, 0, 8); return [$aes_key, $aes_iv]; } /** diff --git a/src/danog/MadelineProto/MTProtoTools/Files.php b/src/danog/MadelineProto/MTProtoTools/Files.php index 682d6519..bde485d2 100644 --- a/src/danog/MadelineProto/MTProtoTools/Files.php +++ b/src/danog/MadelineProto/MTProtoTools/Files.php @@ -44,6 +44,7 @@ use danog\MadelineProto\Stream\Common\SimpleBufferedRawStream; use danog\MadelineProto\Stream\ConnectionContext; use danog\MadelineProto\Stream\Transport\PremadeStream; use danog\MadelineProto\Tools; +use tgseclib\Crypt\AES; use const danog\Decoder\TYPES; @@ -744,7 +745,7 @@ trait Files return $res; // Wallpapers case 'wallPaper': - return $this->getDownloadInfo($res['document']); + return $this->getDownloadInfo($messageMedia['document']); // Photos case 'photo': case 'messageMediaPhoto': @@ -1204,7 +1205,7 @@ trait Files if ($fingerprint !== $messageMedia['key_fingerprint']) { throw new \danog\MadelineProto\Exception('Fingerprint mismatch!'); } - $ige = new \tgseclib\Crypt\AES('ige'); + $ige = new AES('ige'); $ige->setIV($messageMedia['iv']); $ige->setKey($messageMedia['key']); $ige->enableContinuousBuffer(); diff --git a/src/danog/MadelineProto/MTProtoTools/MinDatabase.php b/src/danog/MadelineProto/MTProtoTools/MinDatabase.php index 8771cd6a..3114b556 100644 --- a/src/danog/MadelineProto/MTProtoTools/MinDatabase.php +++ b/src/danog/MadelineProto/MTProtoTools/MinDatabase.php @@ -21,14 +21,12 @@ namespace danog\MadelineProto\MTProtoTools; use danog\MadelineProto\MTProto; use danog\MadelineProto\TL\TLCallback; -use danog\MadelineProto\Tools; /** * Manages min peers. */ class MinDatabase implements TLCallback { - use Tools; const SWITCH_CONSTRUCTORS = ['inputChannel', 'inputUser', 'inputPeerUser', 'inputPeerChannel']; const CATCH_PEERS = ['message', 'messageService', 'peerUser', 'peerChannel', 'messageEntityMentionName', 'messageFwdHeader', 'messageActionChatCreate', 'messageActionChatAddUser', 'messageActionChatDeleteUser', 'messageActionChatJoinedByLink']; const ORIGINS = ['message', 'messageService']; diff --git a/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php b/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php index cd2ba0d1..4741fb54 100644 --- a/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php +++ b/src/danog/MadelineProto/MTProtoTools/PasswordCalculator.php @@ -22,7 +22,6 @@ namespace danog\MadelineProto\MTProtoTools; use danog\MadelineProto\Exception; use danog\MadelineProto\Magic; use danog\MadelineProto\SecurityException; -use danog\MadelineProto\Tools; use tgseclib\Math\BigInteger; /** @@ -34,7 +33,7 @@ use tgseclib\Math\BigInteger; class PasswordCalculator { use AuthKeyHandler; - use Tools; + /** * The algorithm to use for calculating the hash of new passwords (a PasswordKdfAlgo object). * diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index 6ba5e2c0..debf2f8f 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -188,9 +188,6 @@ trait PeerHandler } } break; - default: - throw new \danog\MadelineProto\Exception('Invalid chat provided at key ' . $key . ': ' . \var_export($chat, true)); - break; } } private function cachePwrChat($id, $full_fetch, $send) @@ -199,9 +196,9 @@ trait PeerHandler try { yield from $this->getPwrChat($id, $full_fetch, $send); } catch (\danog\MadelineProto\Exception $e) { - $this->logger->logger('While caching: ' . $e->getMessage(), \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('While caching: '.$e->getMessage(), \danog\MadelineProto\Logger::WARNING); } catch (\danog\MadelineProto\RPCErrorException $e) { - $this->logger->logger('While caching: ' . $e->getMessage(), \danog\MadelineProto\Logger::WARNING); + $this->logger->logger('While caching: '.$e->getMessage(), \danog\MadelineProto\Logger::WARNING); } })()); } @@ -409,7 +406,7 @@ trait PeerHandler case 'updateEditChannelMessage': return $this->getId($id['message']); default: - throw new \danog\MadelineProto\Exception('Invalid constructor given ' . \var_export($id, true)); + throw new \danog\MadelineProto\Exception('Invalid constructor given '.\var_export($id, true)); } } if (\is_string($id)) { @@ -418,7 +415,7 @@ trait PeerHandler return $this->toSupergroup($matches[1]); } if (\preg_match('/^chat#(\\d*)/', $id, $matches)) { - $id = '-' . $matches[1]; + $id = '-'.$matches[1]; } if (\preg_match('/^user#(\\d*)/', $id, $matches)) { return $matches[1]; @@ -527,12 +524,12 @@ trait PeerHandler if (!isset($this->settings['pwr']['requests']) || $this->settings['pwr']['requests'] === true && $recursive) { $dbres = []; try { - $dbres = \json_decode(yield from $this->datacenter->fileGetContents('https://id.pwrtelegram.xyz/db/getusername?id=' . $id), true); + $dbres = \json_decode(yield from $this->datacenter->fileGetContents('https://id.pwrtelegram.xyz/db/getusername?id='.$id), true); } catch (\Throwable $e) { $this->logger->logger($e); } if (isset($dbres['ok']) && $dbres['ok']) { - yield from $this->resolveUsername('@' . $dbres['result']); + yield from $this->resolveUsername('@'.$dbres['result']); return yield from $this->getInfo($id, false); } } @@ -646,7 +643,7 @@ trait PeerHandler case 'channelForbidden': throw new \danog\MadelineProto\Exception('This peer is not present in the internal peer database'); default: - throw new \danog\MadelineProto\Exception('Invalid constructor given ' . \var_export($constructor, true)); + throw new \danog\MadelineProto\Exception('Invalid constructor given '.\var_export($constructor, true)); } if ($folder_id) { $res['FolderPeer'] = ['_' => 'folderPeer', 'peer' => $res['Peer'], 'folder_id' => $folder_id]; @@ -832,7 +829,7 @@ trait PeerHandler foreach ($filters as $filter) { yield from $this->recurseAlphabetSearchParticipants($full['InputChannel'], $filter, $q, $total_count, $res); } - $this->logger->logger('Fetched ' . \count($res['participants']) . " out of {$total_count}"); + $this->logger->logger('Fetched '.\count($res['participants'])." out of {$total_count}"); $res['participants'] = \array_values($res['participants']); } if (!$fullfetch) { @@ -877,7 +874,7 @@ trait PeerHandler return false; } for ($x = 'a'; $x !== 'aa' && $total_count > \count($res['participants']); $x++) { - yield from $this->recurseAlphabetSearchParticipants($channel, $filter, $q . $x, $total_count, $res); + yield from $this->recurseAlphabetSearchParticipants($channel, $filter, $q.$x, $total_count, $res); } } private function fetchParticipants($channel, $filter, $q, $total_count, &$res): \Generator @@ -925,15 +922,15 @@ trait PeerHandler if (isset($participant['rank'])) { $newres['rank'] = $participant['rank']; } + if (isset($participant['admin_rights'])) { + $newres['admin_rights'] = $participant['admin_rights']; + } + if (isset($participant['banned_rights'])) { + $newres['banned_rights'] = $participant['banned_rights']; + } switch ($participant['_']) { case 'channelParticipantSelf': $newres['role'] = 'user'; - if (isset($newres['admin_rights'])) { - $newres['admin_rights'] = $full['Chat']['admin_rights']; - } - if (isset($newres['banned_rights'])) { - $newres['banned_rights'] = $full['Chat']['banned_rights']; - } break; case 'channelParticipant': $newres['role'] = 'user'; @@ -950,7 +947,7 @@ trait PeerHandler } $res['participants'][$participant['user_id']] = $newres; } - $this->logger->logger('Fetched ' . \count($gres['participants']) . " channel participants with filter {$filter}, query {$q}, offset {$offset}, limit {$limit}, hash {$hash}: " . ($cached ? 'cached' : 'not cached') . ', ' . ($offset + \count($gres['participants'])) . ' participants out of ' . $gres['count'] . ', in total fetched ' . \count($res['participants']) . ' out of ' . $total_count); + $this->logger->logger('Fetched '.\count($gres['participants'])." channel participants with filter {$filter}, query {$q}, offset {$offset}, limit {$limit}, hash {$hash}: ".($cached ? 'cached' : 'not cached').', '.($offset + \count($gres['participants'])).' participants out of '.$gres['count'].', in total fetched '.\count($res['participants']).' out of '.$total_count); $offset += \count($gres['participants']); } while (\count($gres['participants'])); if ($offset === $limit) { @@ -1002,7 +999,7 @@ trait PeerHandler //$path = '/tmp/ids'.hash('sha256', $payload); //file_put_contents($path, $payload); $id = isset($this->authorization['user']['username']) ? $this->authorization['user']['username'] : $this->authorization['user']['id']; - $request = new Request('https://id.pwrtelegram.xyz/db' . $this->settings['pwr']['db_token'] . '/addnewmadeline?d=pls&from=' . $id, 'POST'); + $request = new Request('https://id.pwrtelegram.xyz/db'.$this->settings['pwr']['db_token'].'/addnewmadeline?d=pls&from='.$id, 'POST'); $request->setHeader('content-type', 'application/json'); $request->setBody($payload); $result = yield (yield $this->datacenter->getHTTPClient()->request($request))->getBody()->buffer(); @@ -1010,7 +1007,7 @@ trait PeerHandler $this->qres = []; $this->last_stored = \time() + 10; } catch (\danog\MadelineProto\Exception $e) { - $this->logger->logger('======= COULD NOT STORE IN DB DUE TO ' . $e->getMessage() . ' =============', \danog\MadelineProto\Logger::VERBOSE); + $this->logger->logger('======= COULD NOT STORE IN DB DUE TO '.$e->getMessage().' =============', \danog\MadelineProto\Logger::VERBOSE); } } /** @@ -1026,7 +1023,7 @@ trait PeerHandler $this->caching_simple_username[$username] = true; $res = yield from $this->methodCallAsyncRead('contacts.resolveUsername', ['username' => \str_replace('@', '', $username)], ['datacenter' => $this->datacenter->curdc]); } catch (\danog\MadelineProto\RPCErrorException $e) { - $this->logger->logger('Username resolution failed with error ' . $e->getMessage(), \danog\MadelineProto\Logger::ERROR); + $this->logger->logger('Username resolution failed with error '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR); if (\strpos($e->rpc, 'FLOOD_WAIT_') === 0 || $e->rpc === 'AUTH_KEY_UNREGISTERED' || $e->rpc === 'USERNAME_INVALID') { throw $e; } diff --git a/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php b/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php index 801dbed2..32900778 100644 --- a/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php +++ b/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php @@ -22,14 +22,13 @@ namespace danog\MadelineProto\MTProtoTools; use danog\MadelineProto\Exception; use danog\MadelineProto\MTProto; use danog\MadelineProto\TL\TLCallback; -use danog\MadelineProto\Tools; /** * Manages upload and download of files. */ class ReferenceDatabase implements TLCallback { - use Tools; + // Reference from a document const DOCUMENT_LOCATION = 0; // Reference from a photo diff --git a/src/danog/MadelineProto/Magic.php b/src/danog/MadelineProto/Magic.php index 22a720f7..1ebfd9b5 100644 --- a/src/danog/MadelineProto/Magic.php +++ b/src/danog/MadelineProto/Magic.php @@ -25,7 +25,6 @@ use Amp\DoH\Rfc8484StubResolver; use Amp\Loop; use Amp\Loop\Driver; use ReflectionClass; -use function Amp\ByteStream\getInputBufferStream; use function Amp\ByteStream\getStdin; use function Amp\Dns\resolver; use function Amp\Promise\wait; @@ -236,7 +235,7 @@ class Magic throw Exception::extension($extension); } } - self::$has_thread = \class_exists('\\Thread') && \method_exists('\\Thread', 'getCurrentThread'); + self::$has_thread = \class_exists(\Thread::class) && \method_exists(\Thread::class, 'getCurrentThread'); self::$BIG_ENDIAN = \pack('L', 1) === \pack('N', 1); self::$bigint = PHP_INT_SIZE < 8; self::$ipv6 = (bool) \strlen(@\file_get_contents('http://ipv6.google.com', false, \stream_context_create(['http' => ['timeout' => 1]]))) > 0; @@ -390,10 +389,9 @@ class Magic public static function shutdown(int $code = 0) { self::$signaled = true; - if (\defined(STDIN::class)) { + if (\defined('STDIN')) { getStdin()->unreference(); } - getInputBufferStream()->unreference(); if ($code !== 0) { $driver = Loop::get(); $reflectionClass = new ReflectionClass(Driver::class); diff --git a/src/danog/MadelineProto/MyTelegramOrgWrapper.php b/src/danog/MadelineProto/MyTelegramOrgWrapper.php index f6a6ee54..b915ca1e 100644 --- a/src/danog/MadelineProto/MyTelegramOrgWrapper.php +++ b/src/danog/MadelineProto/MyTelegramOrgWrapper.php @@ -27,7 +27,6 @@ use Amp\Http\Client\Request; */ class MyTelegramOrgWrapper { - use Tools; private $logged = false; private $hash = ''; private $number; diff --git a/src/danog/MadelineProto/RPCErrorException.php b/src/danog/MadelineProto/RPCErrorException.php index c8578614..80d67aad 100644 --- a/src/danog/MadelineProto/RPCErrorException.php +++ b/src/danog/MadelineProto/RPCErrorException.php @@ -23,8 +23,7 @@ class RPCErrorException extends \Exception { use TL\PrettyException; private $fetched = false; - public static $rollbar = true; - public static $descriptions = ['RPC_MCGET_FAIL' => 'Telegram is having internal issues, please try again later.', 'RPC_CALL_FAIL' => 'Telegram is having internal issues, please try again later.', 'USER_PRIVACY_RESTRICTED' => "The user's privacy settings do not allow you to do this", 'CHANNEL_PRIVATE' => "You haven't joined this channel/supergroup", 'USER_IS_BOT' => "Bots can't send messages to other bots", 'BOT_METHOD_INVALID' => 'This method cannot be run by a bot', 'PHONE_CODE_EXPIRED' => 'The phone code you provided has expired, this may happen if it was sent to any chat on telegram (if the code is sent through a telegram chat (not the official account) to avoid it append or prepend to the code some chars)', 'USERNAME_INVALID' => 'The provided username is not valid', 'ACCESS_TOKEN_INVALID' => 'The provided token is not valid', 'ACTIVE_USER_REQUIRED' => 'The method is only available to already activated users', 'FIRSTNAME_INVALID' => 'The first name is invalid', 'LASTNAME_INVALID' => 'The last name is invalid', 'PHONE_NUMBER_INVALID' => 'The phone number is invalid', 'PHONE_CODE_HASH_EMPTY' => 'phone_code_hash is missing', 'PHONE_CODE_EMPTY' => 'phone_code is missing', 'PHONE_CODE_EXPIRED' => 'The confirmation code has expired', 'API_ID_INVALID' => 'The api_id/api_hash combination is invalid', 'PHONE_NUMBER_OCCUPIED' => 'The phone number is already in use', 'PHONE_NUMBER_UNOCCUPIED' => 'The phone number is not yet being used', 'USERS_TOO_FEW' => 'Not enough users (to create a chat, for example)', 'USERS_TOO_MUCH' => 'The maximum number of users has been exceeded (to create a chat, for example)', 'TYPE_CONSTRUCTOR_INVALID' => 'The type constructor is invalid', 'FILE_PART_INVALID' => 'The file part number is invalid', 'FILE_PARTS_INVALID' => 'The number of file parts is invalid', 'MD5_CHECKSUM_INVALID' => 'The MD5 checksums do not match', 'PHOTO_INVALID_DIMENSIONS' => 'The photo dimensions are invalid', 'FIELD_NAME_INVALID' => 'The field with the name FIELD_NAME is invalid', 'FIELD_NAME_EMPTY' => 'The field with the name FIELD_NAME is missing', 'MSG_WAIT_FAILED' => 'A waiting call returned an error', 'USERNAME_NOT_OCCUPIED' => 'The provided username is not occupied', 'PHONE_NUMBER_BANNED' => 'The provided phone number is banned from telegram', 'AUTH_KEY_UNREGISTERED' => 'The authorization key has expired', 'INVITE_HASH_EXPIRED' => 'The invite link has expired', 'USER_DEACTIVATED' => 'The user was deactivated', 'USER_ALREADY_PARTICIPANT' => 'The user is already in the group', 'MESSAGE_ID_INVALID' => 'The provided message id is invalid', 'PEER_ID_INVALID' => 'The provided peer id is invalid', 'CHAT_ID_INVALID' => 'The provided chat id is invalid', 'MESSAGE_DELETE_FORBIDDEN' => "You can't delete one of the messages you tried to delete, most likely because it is a service message.", 'CHAT_ADMIN_REQUIRED' => 'You must be an admin in this chat to do this', -429 => 'Too many requests', 'PEER_FLOOD' => "You are spamreported, you can't do this"]; + public static $descriptions = ['RPC_MCGET_FAIL' => 'Telegram is having internal issues, please try again later.', 'RPC_CALL_FAIL' => 'Telegram is having internal issues, please try again later.', 'USER_PRIVACY_RESTRICTED' => "The user's privacy settings do not allow you to do this", 'CHANNEL_PRIVATE' => "You haven't joined this channel/supergroup", 'USER_IS_BOT' => "Bots can't send messages to other bots", 'BOT_METHOD_INVALID' => 'This method cannot be run by a bot', 'PHONE_CODE_EXPIRED' => 'The phone code you provided has expired, this may happen if it was sent to any chat on telegram (if the code is sent through a telegram chat (not the official account) to avoid it append or prepend to the code some chars)', 'USERNAME_INVALID' => 'The provided username is not valid', 'ACCESS_TOKEN_INVALID' => 'The provided token is not valid', 'ACTIVE_USER_REQUIRED' => 'The method is only available to already activated users', 'FIRSTNAME_INVALID' => 'The first name is invalid', 'LASTNAME_INVALID' => 'The last name is invalid', 'PHONE_NUMBER_INVALID' => 'The phone number is invalid', 'PHONE_CODE_HASH_EMPTY' => 'phone_code_hash is missing', 'PHONE_CODE_EMPTY' => 'phone_code is missing', 'API_ID_INVALID' => 'The api_id/api_hash combination is invalid', 'PHONE_NUMBER_OCCUPIED' => 'The phone number is already in use', 'PHONE_NUMBER_UNOCCUPIED' => 'The phone number is not yet being used', 'USERS_TOO_FEW' => 'Not enough users (to create a chat, for example)', 'USERS_TOO_MUCH' => 'The maximum number of users has been exceeded (to create a chat, for example)', 'TYPE_CONSTRUCTOR_INVALID' => 'The type constructor is invalid', 'FILE_PART_INVALID' => 'The file part number is invalid', 'FILE_PARTS_INVALID' => 'The number of file parts is invalid', 'MD5_CHECKSUM_INVALID' => 'The MD5 checksums do not match', 'PHOTO_INVALID_DIMENSIONS' => 'The photo dimensions are invalid', 'FIELD_NAME_INVALID' => 'The field with the name FIELD_NAME is invalid', 'FIELD_NAME_EMPTY' => 'The field with the name FIELD_NAME is missing', 'MSG_WAIT_FAILED' => 'A waiting call returned an error', 'USERNAME_NOT_OCCUPIED' => 'The provided username is not occupied', 'PHONE_NUMBER_BANNED' => 'The provided phone number is banned from telegram', 'AUTH_KEY_UNREGISTERED' => 'The authorization key has expired', 'INVITE_HASH_EXPIRED' => 'The invite link has expired', 'USER_DEACTIVATED' => 'The user was deactivated', 'USER_ALREADY_PARTICIPANT' => 'The user is already in the group', 'MESSAGE_ID_INVALID' => 'The provided message id is invalid', 'PEER_ID_INVALID' => 'The provided peer id is invalid', 'CHAT_ID_INVALID' => 'The provided chat id is invalid', 'MESSAGE_DELETE_FORBIDDEN' => "You can't delete one of the messages you tried to delete, most likely because it is a service message.", 'CHAT_ADMIN_REQUIRED' => 'You must be an admin in this chat to do this', -429 => 'Too many requests', 'PEER_FLOOD' => "You are spamreported, you can't do this"]; public static $errorMethodMap = []; private $caller = ''; public static function localizeMessage($method, $code, $error) @@ -69,9 +68,7 @@ class RPCErrorException extends \Exception $additional = $level['args']; } } - if (!self::$rollbar || !\class_exists(\Rollbar\Rollbar::class)) { - return; - } + /* if (\in_array($this->rpc, ['CHANNEL_PRIVATE', -404, -429, 'USERNAME_NOT_OCCUPIED', 'ACCESS_TOKEN_INVALID', 'AUTH_KEY_UNREGISTERED', 'SESSION_PASSWORD_NEEDED', 'PHONE_NUMBER_UNOCCUPIED', 'PEER_ID_INVALID', 'CHAT_ID_INVALID', 'USERNAME_INVALID', 'CHAT_WRITE_FORBIDDEN', 'CHAT_ADMIN_REQUIRED', 'PEER_FLOOD'])) { return; } @@ -79,5 +76,6 @@ class RPCErrorException extends \Exception return; } $message === 'Telegram is having internal issues, please try again later.' ? \Rollbar\Rollbar::log(\Rollbar\Payload\Level::critical(), $message) : \Rollbar\Rollbar::log(\Rollbar\Payload\Level::error(), $this, $additional); + */ } } diff --git a/src/danog/MadelineProto/RSA.php b/src/danog/MadelineProto/RSA.php index 1bd9ef0d..6c155551 100644 --- a/src/danog/MadelineProto/RSA.php +++ b/src/danog/MadelineProto/RSA.php @@ -26,7 +26,6 @@ use danog\MadelineProto\TL\TL; */ class RSA { - use \danog\MadelineProto\Tools; use \danog\Serializable; /** * Exponent. diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php index 7a8c1cdb..aeea8c50 100644 --- a/src/danog/MadelineProto/Serialization.php +++ b/src/danog/MadelineProto/Serialization.php @@ -43,7 +43,7 @@ class Serialization public static function realpaths(string $file): array { $file = Absolute::absolute($file); - return ['file' => $file, 'lockfile' => $file . '.lock', 'tempfile' => $file . '.temp.session']; + return ['file' => $file, 'lockfile' => $file.'.lock', 'tempfile' => $file.'.temp.session']; } /** * Unserialize legacy session. @@ -80,7 +80,7 @@ class Serialization if ($e->getFile() === 'MadelineProto' && $e->getLine() === 1) { throw $e; } - if (\MADELINEPROTO_TEST === 'pony') { + if (\constant("MADELINEPROTO_TEST") === 'pony') { throw $e; } \class_exists('\\Volatile'); diff --git a/src/danog/MadelineProto/Shutdown.php b/src/danog/MadelineProto/Shutdown.php index 573dfc3e..19a9dc17 100644 --- a/src/danog/MadelineProto/Shutdown.php +++ b/src/danog/MadelineProto/Shutdown.php @@ -59,7 +59,7 @@ class Shutdown * @param callable $callback The callback to set * @param null|string $id The optional callback ID * - * @return The callback ID + * @return int The callback ID */ public static function addCallback($callback, $id = null) { diff --git a/src/danog/MadelineProto/Stream/Common/CtrStream.php b/src/danog/MadelineProto/Stream/Common/CtrStream.php index 813d395b..0b652ca0 100644 --- a/src/danog/MadelineProto/Stream/Common/CtrStream.php +++ b/src/danog/MadelineProto/Stream/Common/CtrStream.php @@ -109,8 +109,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface * * @param Promise $promise Promise that resolves with a string when new data is available or `null` if the stream has closed. * - * @throws PendingReadError Thrown if another read operation is still pending. - * * @return \Generator That resolves with a string when the provided promise is resolved and the data is decrypted */ public function bufferReadGenerator(int $length): \Generator @@ -122,8 +120,6 @@ class CtrStream implements BufferedProxyStreamInterface, BufferInterface * * @param string $data Bytes to write. * - * @throws ClosedException If the stream has already been closed. - * * @return Promise Succeeds once the data has been successfully written to the stream. */ public function bufferWrite(string $data): Promise diff --git a/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php b/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php index c715664a..a2a17162 100644 --- a/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php +++ b/src/danog/MadelineProto/Stream/Common/HashedBufferedStream.php @@ -140,8 +140,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf * * @param int $length Read and hash $length bytes * - * @throws PendingReadError Thrown if another read operation is still pending. - * * @return \Generator That resolves with a string when the provided promise is resolved and the data is added to the hashing context */ public function bufferReadGenerator(int $length): \Generator @@ -241,8 +239,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf /** * Reads data from the stream. * - * @throws PendingReadError Thrown if another read operation is still pending. - * * @return Promise Resolves with a string when new data is available or `null` if the stream has closed. */ public function bufferRead(int $length): Promise @@ -257,8 +253,6 @@ class HashedBufferedStream implements BufferedProxyStreamInterface, BufferInterf * * @param string $data Bytes to write. * - * @throws ClosedException If the stream has already been closed. - * * @return Promise Succeeds once the data has been successfully written to the stream. */ public function bufferWrite(string $data): Promise diff --git a/src/danog/MadelineProto/TL/TL.php b/src/danog/MadelineProto/TL/TL.php index 79dd0e8a..ce12ea54 100644 --- a/src/danog/MadelineProto/TL/TL.php +++ b/src/danog/MadelineProto/TL/TL.php @@ -648,10 +648,10 @@ class TL /** * Serialize parameters. * - * @param array $tl TL object definition - * @param arrayLike $arguments Arguments - * @param string $ctx Context - * @param integer $layer Layer + * @param array $tl TL object definition + * @param array $arguments Arguments + * @param string $ctx Context + * @param integer $layer Layer * * @return \Generator */ diff --git a/src/danog/MadelineProto/TL/TLConstructors.php b/src/danog/MadelineProto/TL/TLConstructors.php index af53d784..3774c054 100644 --- a/src/danog/MadelineProto/TL/TLConstructors.php +++ b/src/danog/MadelineProto/TL/TLConstructors.php @@ -22,7 +22,6 @@ namespace danog\MadelineProto\TL; class TLConstructors { use \danog\Serializable; - use \danog\MadelineProto\Tools; use TLParams; public $by_id = []; public $by_predicate_and_layer = []; @@ -36,8 +35,8 @@ class TLConstructors if (isset($this->by_id[$json_dict['id']]) && (!isset($this->by_id[$json_dict['id']]['layer']) || $this->by_id[$json_dict['id']]['layer'] > $json_dict['layer'])) { return false; } - $predicate = (string) (($scheme_type === 'mtproto' && $json_dict['predicate'] === 'message' ? 'MT' : '') . $json_dict['predicate']); - $this->by_id[$json_dict['id']] = ['predicate' => $predicate, 'params' => $json_dict['params'], 'type' => ($scheme_type === 'mtproto' && $json_dict['type'] === 'Message' ? 'MT' : '') . $json_dict['type']]; + $predicate = (string) (($scheme_type === 'mtproto' && $json_dict['predicate'] === 'message' ? 'MT' : '').$json_dict['predicate']); + $this->by_id[$json_dict['id']] = ['predicate' => $predicate, 'params' => $json_dict['params'], 'type' => ($scheme_type === 'mtproto' && $json_dict['type'] === 'Message' ? 'MT' : '').$json_dict['type']]; if ($scheme_type === 'secret') { $this->by_id[$json_dict['id']]['layer'] = $json_dict['layer']; $this->layers[$json_dict['layer']] = $json_dict['layer']; @@ -45,7 +44,7 @@ class TLConstructors } else { $json_dict['layer'] = ''; } - $this->by_predicate_and_layer[$predicate . $json_dict['layer']] = $json_dict['id']; + $this->by_predicate_and_layer[$predicate.$json_dict['layer']] = $json_dict['id']; $this->parseParams($json_dict['id'], $scheme_type === 'mtproto'); } public function findByType($type) @@ -61,13 +60,14 @@ class TLConstructors public function findByPredicate($predicate, $layer = -1) { if ($layer !== -1) { + $chosenid = null; foreach ($this->layers as $alayer) { if ($alayer <= $layer) { - if (isset($this->by_predicate_and_layer[$predicate . $alayer])) { - $chosenid = $this->by_predicate_and_layer[$predicate . $alayer]; + if (isset($this->by_predicate_and_layer[$predicate.$alayer])) { + $chosenid = $this->by_predicate_and_layer[$predicate.$alayer]; } } elseif (!isset($chosenid)) { - $chosenid = $this->by_predicate_and_layer[$predicate . $alayer]; + $chosenid = $this->by_predicate_and_layer[$predicate.$alayer]; } } if (!isset($chosenid)) { diff --git a/src/danog/MadelineProto/TL/TLMethods.php b/src/danog/MadelineProto/TL/TLMethods.php index 19fd05e4..6bcd2fa8 100644 --- a/src/danog/MadelineProto/TL/TLMethods.php +++ b/src/danog/MadelineProto/TL/TLMethods.php @@ -22,7 +22,6 @@ namespace danog\MadelineProto\TL; class TLMethods { use \danog\Serializable; - use \danog\MadelineProto\Tools; use TLParams; public $by_id = []; public $by_method = []; diff --git a/src/danog/MadelineProto/Tools.php b/src/danog/MadelineProto/Tools.php index 2229af66..0c6f65e4 100644 --- a/src/danog/MadelineProto/Tools.php +++ b/src/danog/MadelineProto/Tools.php @@ -41,7 +41,7 @@ use function Amp\Promise\wait; /** * Some tools. */ -trait Tools +abstract class Tools { /** * Sanify TL obtained from JSON for TL serialization. @@ -614,7 +614,7 @@ trait Tools /** * Check if is array or similar (traversable && countable && arrayAccess). * - * @param arraylike $var Value to check + * @param mixed $var Value to check * * @return boolean */ diff --git a/src/danog/MadelineProto/Wrappers/DialogHandler.php b/src/danog/MadelineProto/Wrappers/DialogHandler.php index 58cb3507..c9d80767 100644 --- a/src/danog/MadelineProto/Wrappers/DialogHandler.php +++ b/src/danog/MadelineProto/Wrappers/DialogHandler.php @@ -26,7 +26,7 @@ trait DialogHandler * * @param boolean $force Whether to refetch all dialogs ignoring cache * - * @return \Generator> + * @return \Generator> */ public function getDialogs(bool $force = true): \Generator {