From 400590edd24382e2940fcf4ed0546cf372c5474c Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Mon, 10 Jul 2023 19:56:44 +0200 Subject: [PATCH] Localize errors --- langs/en.json | 7 +++++++ src/EventHandler.php | 25 ++++++++++++++++--------- src/Exception.php | 33 +++++++++++++++------------------ src/MTProto.php | 27 +++++++++++++++++++++------ src/PluginEventHandler.php | 7 +++++++ src/TL/TL.php | 2 +- 6 files changed, 67 insertions(+), 34 deletions(-) diff --git a/langs/en.json b/langs/en.json index e68c750f8..c62d2af73 100644 --- a/langs/en.json +++ b/langs/en.json @@ -1,4 +1,11 @@ { + "noReportPeers": "Warning: no report peers are set, please add the following method to your event handler", + "manualAdminActionRequired": "!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", + "mmapError": "The maximum number of mmap'ed regions was reached (%s): please increase the vm.max_map_count kernel config to 262144 to fix.\nTo fix, run the following command as root: echo 262144 | sudo tee /proc/sys/vm/max_map_count\nTo persist the change across reboots: echo vm.max_map_count=262144 | sudo tee /etc/sysctl.d/40-madelineproto.conf\nOn Windows and WSL, increasing the size of the pagefile might help; please switch to native Linux if the issue persists.", + "extensionRequired": "MadelineProto requires the %s extension to run. %s", + "extensionRequiredInstallWithApt": "Try running sudo apt-get install %s.", + "extensionRequiredInstallWithCustomInstructions": "Follow the instructions at %s to install it.", + "extensionRecommended": "Warning: the %s extension is not installed, please install it to speed up MadelineProto!", "go": "Go", "apiChooseManualAutoTip": "Note that you can also provide the API ID\/hash directly in the code using the settings: %s", "apiChooseManualAutoTipWeb": "Note that you can also provide the API ID\/hash directly in the code using the settings<\/a>.", diff --git a/src/EventHandler.php b/src/EventHandler.php index 368977f38..158b20f05 100644 --- a/src/EventHandler.php +++ b/src/EventHandler.php @@ -346,7 +346,7 @@ abstract class EventHandler extends AbstractAPI Assert::true(\is_subclass_of($plugin, PluginEventHandler::class), "$plugin must extend ".PluginEventHandler::class); Assert::notEq($plugin, PluginEventHandler::class); Assert::true(\str_contains(\ltrim($plugin, '\\'), '\\'), "$plugin must be in a namespace!"); - self::validatePlugin($plugin); + self::validateEventHandler($plugin); } return $plugins; @@ -373,7 +373,14 @@ abstract class EventHandler extends AbstractAPI PDO::class, mysqli::class, ]; - private static function validatePlugin(string $class): void + /** + * Perform static analysis on a certain event handler class, to make sure it satisfies some performance requirements. + * + * @param class-string $class Class name + * + * @throws AssertionError If validation fails. + */ + final public static function validateEventHandler(string $class): void { $file = read((new ReflectionClass($class))->getFileName()); $file = (new ParserFactory)->create(ParserFactory::ONLY_PHP7)->parse($file); @@ -384,13 +391,13 @@ abstract class EventHandler extends AbstractAPI /** @var DeclareDeclare|null $call */ $declare = $finder->findFirstInstanceOf($file, DeclareDeclare::class); - Assert::true( - $declare !== null - && $declare->key->name === 'strict_types' - && $declare->value instanceof LNumber - && $declare->value->value === 1, - "An error occurred while analyzing plugin $class: for performance reasons, the first statement of a plugin must be declare(strict_types=1);" - ); + if ($declare === null + || $declare->key->name !== 'strict_types' + || !$declare->value instanceof LNumber + || $declare->value->value !== 1 + ) { + throw new AssertionError("An error occurred while analyzing plugin $class: for performance reasons, the first statement of a plugin must be declare(strict_types=1);"); + } /** @var FuncCall $call */ foreach ($finder->findInstanceOf($file, FuncCall::class) as $call) { diff --git a/src/Exception.php b/src/Exception.php index 6c39bb097..d99fab7b8 100644 --- a/src/Exception.php +++ b/src/Exception.php @@ -59,15 +59,16 @@ class Exception extends \Exception */ public static function extension(string $extensionName): self { - $additional = 'Try running sudo apt-get install php'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION.'-'.$extensionName.'.'; if ($extensionName === 'libtgvoip') { - $additional = 'Follow the instructions @ https://voip.madelineproto.xyz to install it.'; + $additional = \sprintf(Lang::$current_lang['extensionRequiredInstallWithCustomInstructions'], 'https://voip.madelineproto.xyz'); } elseif ($extensionName === 'prime') { - $additional = 'Follow the instructions @ https://prime.madelineproto.xyz to install it.'; + $additional = \sprintf(Lang::$current_lang['extensionRequiredInstallWithCustomInstructions'], 'https://prime.madelineproto.xyz'); + } else { + $additional = \sprintf(Lang::$current_lang['extensionRequiredInstallWithApt'], 'php'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION.'-'.$extensionName); } - $message = 'MadelineProto requires the '.$extensionName.' extension to run. '.$additional; + $message = \sprintf(Lang::$current_lang['extensionRequired'], $extensionName, $additional); if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') { - echo $message.'
'; + echo \htmlentities($message).'
'; } $file = 'MadelineProto'; $line = 1; @@ -106,26 +107,22 @@ class Exception extends \Exception if (\str_contains($exception->getMessage(), 'Fiber stack protect failed') || \str_contains($exception->getMessage(), 'Fiber stack allocate failed') ) { - $maps = ""; + $maps = "?"; try { $maps = '~'.\substr_count(\file_get_contents('/proc/self/maps'), "\n"); $pid = \getmypid(); $maps = '~'.\substr_count(\file_get_contents("/proc/$pid/maps"), "\n"); } catch (\Throwable) { } - if ($maps !== '') { - $maps = " ($maps)"; + Logger::log(Lang::$current_lang['manualAdminActionRequired'], Logger::FATAL_ERROR); + Logger::log(Lang::$current_lang['manualAdminActionRequired'], Logger::FATAL_ERROR); + Logger::log(Lang::$current_lang['manualAdminActionRequired']); + foreach (\explode("\n", \trim(Lang::$current_lang['mmapError'])) as $line) { + Logger::log(\sprintf($line, $maps), Logger::FATAL_ERROR); } - Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR); - Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR); - Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR); - Logger::log("The maximum number of mmap'ed regions was reached$maps: please increase the vm.max_map_count kernel config to 262144 to fix."); - Logger::log("To fix, run the following command as root: echo 262144 | sudo tee /proc/sys/vm/max_map_count"); - Logger::log("To persist the change across reboots: echo vm.max_map_count=262144 | sudo tee /etc/sysctl.d/40-madelineproto.conf"); - Logger::log("On Windows and WSL, increasing the size of the pagefile might help; please switch to native Linux if the issue persists."); - Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR); - Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR); - Logger::log("!!!!!!!!! MANUAL SYSTEM ADMIN ACTION REQUIRED !!!!!!!!!", Logger::FATAL_ERROR); + Logger::log(Lang::$current_lang['manualAdminActionRequired']); + Logger::log(Lang::$current_lang['manualAdminActionRequired'], Logger::FATAL_ERROR); + Logger::log(Lang::$current_lang['manualAdminActionRequired'], Logger::FATAL_ERROR); } Logger::log($exception, Logger::FATAL_ERROR); die(1); diff --git a/src/MTProto.php b/src/MTProto.php index e66fbf8dd..7187e3773 100644 --- a/src/MTProto.php +++ b/src/MTProto.php @@ -25,6 +25,7 @@ use Amp\Dns\DnsResolver; use Amp\Future; use Amp\Http\Client\HttpClient; use Amp\Sync\LocalMutex; +use AssertionError; use danog\MadelineProto\Broadcast\Broadcast; use danog\MadelineProto\Db\DbArray; use danog\MadelineProto\Db\DbPropertiesFactory; @@ -1582,14 +1583,28 @@ final class MTProto implements TLCallback, LoggerGetter Logger::log($message); $warning = ''; - if (!$this->hasReportPeers() && $this->hasEventHandler()) { - Logger::log('!!! Warning: no report peers are set, please add the following method to your event handler !!!', Logger::FATAL_ERROR); - Logger::log("!!! public function getReportPeers() { return '@yourtelegramusername'; } !!!", Logger::FATAL_ERROR); - $warning .= "

Warning: no report peers are set, please add the following method to your event handler:

"; - $warning .= "public function getReportPeers() { return '@yourtelegramusername'; }"; + if ($this->hasEventHandler()) { + if (!$this->hasReportPeers()) { + Logger::log('!!! '.Lang::$current_lang['noReportPeers'].' !!!', Logger::FATAL_ERROR); + Logger::log("!!! public function getReportPeers() { return '@yourtelegramusername'; } !!!", Logger::FATAL_ERROR); + $warning .= "

".\htmlentities(Lang::$current_lang['noReportPeers'])."

"; + $warning .= "public function getReportPeers() { return '@yourtelegramusername'; }"; + } + if ($this->event_handler_instance instanceof EventHandler) { + try { + EventHandler::validateEventHandler($this->event_handler_instance::class); + } catch (AssertionError $e) { + Logger::log($e->getMessage(), Logger::FATAL_ERROR); + $e = \htmlentities($e->getMessage()); + $warning .= "

{$e}

"; + } + } } if (!Magic::$hasOpenssl) { - $warning .= "

Warning: the openssl extension is not installed, please install it to speed up MadelineProto

"; + $warning .= "

".\htmlentities(\sprintf(Lang::$current_lang['extensionRecommended'], 'openssl'))."

"; + } + if (!\extension_loaded('gmp')) { + $warning .= "

".\htmlentities(\sprintf(Lang::$current_lang['extensionRecommended'], 'gmp'))."

"; } return "

$message

$warning"; } diff --git a/src/PluginEventHandler.php b/src/PluginEventHandler.php index 7ccc0720d..933db8c45 100644 --- a/src/PluginEventHandler.php +++ b/src/PluginEventHandler.php @@ -25,4 +25,11 @@ namespace danog\MadelineProto; */ abstract class PluginEventHandler extends EventHandler { + /** + * Plugins can require other plugins ONLY with the getPlugins() method. + */ + final public function getPluginPaths(): string|array|null + { + return null; + } } diff --git a/src/TL/TL.php b/src/TL/TL.php index 397043c7a..de39aa3b8 100644 --- a/src/TL/TL.php +++ b/src/TL/TL.php @@ -870,7 +870,7 @@ final class TL implements TLInterface */ public static function extractWaveform(string $x): array { - $values = array_pad(\array_values(\unpack('C*', $x)), 63, 0); + $values = \array_pad(\array_values(\unpack('C*', $x)), 63, 0); $result = \array_fill(0, 100, 0); $bitPos = 0;