diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index 4ed3e5547..66cf6537a 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -197,6 +197,7 @@ class API extends InternalDoc if (yield from $this->connectToMadelineProto($settings)) { return; // OK } + if (!$settings instanceof Settings) { $newSettings = new Settings; $newSettings->merge($settings); @@ -234,7 +235,7 @@ class API extends InternalDoc try { if (!isset($_GET['MadelineSelfRestart']) && ((yield $this->hasEventHandler()) || !(yield $this->isIpcWorker()))) { $this->logger->logger("Restarting to full instance: the bot is already running!"); - MTProto::closeConnection('The bot is already running!'); + Tools::closeConnection(yield $this->getWebMessage("The bot is already running!")); return false; } $this->logger->logger("Restarting to full instance: stopping IPC server..."); @@ -498,6 +499,7 @@ class API extends InternalDoc { $this->async(true); + yield $this->start(); if (!yield from $this->reconnectFull()) { return; } @@ -505,7 +507,6 @@ class API extends InternalDoc $errors = []; while (true) { try { - yield $this->start(); yield $this->setEventHandler($eventHandler); $started = true; return yield from $this->API->loop(); diff --git a/src/danog/MadelineProto/Ipc/Runner/ProcessRunner.php b/src/danog/MadelineProto/Ipc/Runner/ProcessRunner.php index 1a5f68248..05b8b1371 100644 --- a/src/danog/MadelineProto/Ipc/Runner/ProcessRunner.php +++ b/src/danog/MadelineProto/Ipc/Runner/ProcessRunner.php @@ -3,6 +3,7 @@ namespace danog\MadelineProto\Ipc\Runner; use danog\MadelineProto\Logger; +use danog\MadelineProto\Magic; final class ProcessRunner extends RunnerAbstract { @@ -52,8 +53,14 @@ final class ProcessRunner extends RunnerAbstract ]); Logger::log("Starting process with $command"); + $params = [ + 'argv' => ['madeline-ipc', $session, $startupId], + 'cwd' => Magic::getcwd() + ]; + $params = \http_build_query($params); + $pipes = []; - self::$resources []= \proc_open($command, [], $pipes); + self::$resources []= \proc_open($command, [], $pipes, null, ['QUERY_STRING' => $params]); } private static function locateBinary(): string { diff --git a/src/danog/MadelineProto/Ipc/Server.php b/src/danog/MadelineProto/Ipc/Server.php index 6cb67b29e..7b35496c9 100644 --- a/src/danog/MadelineProto/Ipc/Server.php +++ b/src/danog/MadelineProto/Ipc/Server.php @@ -39,6 +39,10 @@ use danog\MadelineProto\Tools; class Server extends SignalLoop { use InternalLoop; + /** + * Server version. + */ + const VERSION = 1; /** * Shutdown server. */ diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index dd31f7f64..25198e33b 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -1336,6 +1336,7 @@ class MTProto extends AsyncConstruct implements TLCallback } if (isset($this->datacenter)) { foreach ($this->datacenter->getDataCenterConnections() as $datacenter) { + $datacenter->setExtra($this); $datacenter->disconnect(); } } @@ -1886,6 +1887,25 @@ class MTProto extends AsyncConstruct implements TLCallback { return (bool) $this->reportDest; } + /** + * Get a message to show to the user when starting the bot. + * + * @param string $message + */ + public function getWebMessage(string $message): string + { + 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'; }"; + } + return "

$message

$warning"; + } + /** * Set peer(s) where to send errors occurred in the event loop. * diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php index 51273e366..87fe9e527 100644 --- a/src/danog/MadelineProto/Serialization.php +++ b/src/danog/MadelineProto/Serialization.php @@ -187,6 +187,11 @@ abstract class Serialization Logger::log("Please start the event handler or unset it to use the IPC server.", Logger::ERROR); return $ipcSocket ?? yield from self::tryConnect($session->getIpcPath(), $cancelIpc->promise()); } + } elseif (!$forceFull) { + // Unlock and fork + $unlock(); + $cancelIpc->resolve(Server::startMe($session)); + return $ipcSocket ?? yield from self::tryConnect($session->getIpcPath(), $cancelIpc->promise()); } $tempId = Shutdown::addCallback($unlock = static function () use ($unlock) { diff --git a/src/danog/MadelineProto/Tools.php b/src/danog/MadelineProto/Tools.php index 3ba6c3169..d591eacef 100644 --- a/src/danog/MadelineProto/Tools.php +++ b/src/danog/MadelineProto/Tools.php @@ -867,6 +867,30 @@ abstract class Tools extends StrTools $header[165] = $stripped[2]; return $header.\substr($stripped, 3).$footer; } + /** + * Close connection with client, connected via web. + * + * @param string $message Message + * + * @return void + */ + public static function closeConnection($message) + { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' || isset($GLOBALS['exited']) || \headers_sent() || isset($_GET['MadelineSelfRestart']) || Magic::$isIpcWorker) { + return; + } + $buffer = @\ob_get_clean() ?: ''; + $buffer .= $message; + \ignore_user_abort(true); + \header('Connection: close'); + \header('Content-Type: text/html'); + echo $buffer; + \flush(); + $GLOBALS['exited'] = true; + if (\function_exists('fastcgi_finish_request')) { + \fastcgi_finish_request(); + } + } /** * Get maximum photo size. * diff --git a/src/danog/MadelineProto/Wrappers/Loop.php b/src/danog/MadelineProto/Wrappers/Loop.php index f20bff365..3fae2933b 100644 --- a/src/danog/MadelineProto/Wrappers/Loop.php +++ b/src/danog/MadelineProto/Wrappers/Loop.php @@ -21,8 +21,6 @@ namespace danog\MadelineProto\Wrappers; use Amp\Loop as AmpLoop; use Amp\Promise; -use danog\MadelineProto\Logger; -use danog\MadelineProto\Magic; use danog\MadelineProto\Settings; use danog\MadelineProto\Shutdown; @@ -87,7 +85,7 @@ trait Loop $this->logger->logger("Added restart callback with ID $id!"); } $this->logger->logger("Done webhost init process!"); - $this->closeConnection('Bot was started'); + Tools::closeConnection($this->getWebMessage("The bot was started!")); $inited = true; } } @@ -181,29 +179,4 @@ trait Loop { return Tools::callFork($this->loop()); } - /** - * Close connection with client, connected via web. - * - * @param string $message Message - * - * @return void - */ - public static function closeConnection($message = 'OK!') - { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' || isset($GLOBALS['exited']) || \headers_sent() || isset($_GET['MadelineSelfRestart']) || Magic::$isIpcWorker) { - return; - } - Logger::log($message); - $buffer = @\ob_get_clean() ?: ''; - $buffer .= '

'.\htmlentities($message).'

'; - \ignore_user_abort(true); - \header('Connection: close'); - \header('Content-Type: text/html'); - echo $buffer; - \flush(); - $GLOBALS['exited'] = true; - if (\function_exists('fastcgi_finish_request')) { - \fastcgi_finish_request(); - } - } }