diff --git a/README.md b/README.md
index ebcc2635f..9aede636d 100644
--- a/README.md
+++ b/README.md
@@ -496,7 +496,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* Get diffie-hellman configuration: getDhConfig
* Get download info of file: getDownloadInfo
* Get download info of the propic of a user: getPropicInfo
- * Get download link of media file: getDownloadLink
+ * Get download link of media file: getDownloadLink
* Get event handler (or plugin instance): getEventHandler
* Get extension from file location: getExtensionFromLocation
* Get extension from mime type: getExtensionFromMime
diff --git a/docs b/docs
index 2bbdf1b07..ceaadaca9 160000
--- a/docs
+++ b/docs
@@ -1 +1 @@
-Subproject commit 2bbdf1b074a607c666dd7f9fd71cc19a137deae2
+Subproject commit ceaadaca96b69220bc631c2e0f9c0f11db206ab2
diff --git a/langs/en.json b/langs/en.json
index 526fdb8f6..969c05ab7 100644
--- a/langs/en.json
+++ b/langs/en.json
@@ -145,9 +145,8 @@
"plugins_must_have_exactly_one_class": "a plugin must define exactly one class! To define multiple classes, interfaces or traits, create separate files, they will be autoloaded by MadelineProto automatically.",
"cli_need_dl.php_link": "Please specify a download script URL when using getDownloadLink via CLI!",
- "invalid_dl.php": "%s is not a valid download script (%s)",
+ "invalid_dl.php_session": "%s is not a valid download script because its session ID is different (expected %s, got %s)",
"need_dl.php": "Could not generate default download script (%s), please create a dl.php file with the following content: %s and pass its URL to the second parameter of getDownloadLink",
"dl.php_powered_by_madelineproto": "Telegram file download server (up to 4GB), powered by MadelineProto!
Click here for more info on how to setup your very own Telegram file download server!"
-
}
diff --git a/langs/fa.json b/langs/fa.json
index bc2e1274e..4d60a3b8c 100644
--- a/langs/fa.json
+++ b/langs/fa.json
@@ -132,7 +132,7 @@
"do_not_remove_MadelineProto.log_phar": "لطفا madeline.phar یا madeline.php را حذف نکنید، در غیراینصورت مدلینپروتو crash خواهد کرد. در صورت داشتن هرگونه مشکل با مدلینپروتو، آن را به https://github.com/danog/MadelineProto یا https://t.me/pwrtelegramgroup گزارش کنید",
"do_not_use_deprecated_function": "تابع %s منسوخ شده، لطفا به جای آن از %s استفاده کنید",
"mmapErrorPart3": "برای تداوم تغییر در طول راهاندازی دوباره: %s",
- "recommend_not_use_filesystem_function": "استفاده از تابع %s پیشنهاد نمیشود، چراکه دسترسی و کار با فایل های سیستمی موقع پردازش آپدیت باعث کم شدن سرعت ربات شما میشود، لطفا صفحه https://docs.madelineproto.xyz/docs/UPDATES.html#avoiding-the-use-of-filesystem-functions را ببینید تا با راههای جایگزین برای ذخیره اطلاعات که باعث کاهش سرعت نمیشوند آشنا شوید!",
+ "recommend_not_use_filesystem_function": "استفاده از تابع %s پیشنهاد نمیشود، چراکه دسترسی و کار با فایل های سیستمی موقع پردازش آپدیت باعث کم شدن سرعت ربات شما میشود، لطفا صفحه https://docs.madelineproto.xyz/docs/UPDATES.html#avoiding-the-use-of-filesystem-functions را ببینید تا با راههای جایگزین برای ذخیره اطلاعات که باعث کاهش سرعت ربات شما نمیشوند آشنا شوید!",
"do_not_use_blocking_function": "به دلایل عملکردی و اجرایی، ایونتهندلرها نباید از فانکشن %s که async نیست استفاده کنند، لطفا به جای آن از %s استفاده کنید",
"do_not_use_blocking_class": "به دلایل عملکردی و اجرایی، هندلرها نباید از کلس %s که async نیست استفاده کنند، به جای آن از %s استفاده کنید",
"do_not_use_non_root_require_in_event_handler": "به دلایل عملکردی و اجرایی، شما نباید از require یا include داخل کلس ایونتهندلر استفاده کنید، فقط require های سطح root مجاز هستند.",
diff --git a/schemas b/schemas
index 2185331bb..5bac79163 160000
--- a/schemas
+++ b/schemas
@@ -1 +1 @@
-Subproject commit 2185331bb36565039fd1bcbe14ee7c25eeab2f51
+Subproject commit 5bac791635b33c1c978bacad22f65c0f11633eb6
diff --git a/src/API.php b/src/API.php
index 539013fa9..6b29574dc 100644
--- a/src/API.php
+++ b/src/API.php
@@ -418,7 +418,9 @@ final class API extends AbstractAPI
} else {
Assert::notEmpty($eventHandler);
Assert::allClassExists($eventHandler);
- foreach ($eventHandler as $c) { $c::cachePlugins($c); }
+ foreach ($eventHandler as $c) {
+ $c::cachePlugins($c);
+ }
}
$errors = [];
diff --git a/src/EventHandler.php b/src/EventHandler.php
index 4c159ea2a..1460a5dc7 100644
--- a/src/EventHandler.php
+++ b/src/EventHandler.php
@@ -265,6 +265,15 @@ abstract class EventHandler extends AbstractAPI
{
return $this->periodicLoops[$name];
}
+ /**
+ * Obtain all PeriodicLoop instances created by the Cron attribute.
+ *
+ * @return array
+ */
+ final public function getPeriodicLoops(): array
+ {
+ return $this->periodicLoops;
+ }
/**
* @internal
*/
diff --git a/src/EventHandler/Filter/Combinator/FilterNot.php b/src/EventHandler/Filter/Combinator/FilterNot.php
index 1ee8799ba..338f49d8c 100644
--- a/src/EventHandler/Filter/Combinator/FilterNot.php
+++ b/src/EventHandler/Filter/Combinator/FilterNot.php
@@ -16,9 +16,9 @@ final class FilterNot extends Filter
public function __construct(private readonly Filter $filter)
{
}
- public function initialize(EventHandler $API): ?Filter
+ public function initialize(EventHandler $API): Filter
{
- $filter = $this->filter->initialize($API) ?? $this->filter;
+ $filter = $this->filter->initialize($API);
if ($filter instanceof self) {
// The nested filter is a FilterNot, optimize !!A => A
return $filter->filter;
diff --git a/src/EventHandler/Filter/Combinator/FiltersAnd.php b/src/EventHandler/Filter/Combinator/FiltersAnd.php
index 3994a1d75..88e2c4a48 100644
--- a/src/EventHandler/Filter/Combinator/FiltersAnd.php
+++ b/src/EventHandler/Filter/Combinator/FiltersAnd.php
@@ -26,7 +26,7 @@ final class FiltersAnd extends Filter
{
$final = [];
foreach ($this->filters as $filter) {
- $filter = $filter->initialize($API) ?? $filter;
+ $filter = $filter->initialize($API);
if ($filter instanceof self) {
$final = \array_merge($final, $filter->filters);
} else {
diff --git a/src/EventHandler/Filter/Combinator/FiltersOr.php b/src/EventHandler/Filter/Combinator/FiltersOr.php
index 146ecf3a7..3be9eee61 100644
--- a/src/EventHandler/Filter/Combinator/FiltersOr.php
+++ b/src/EventHandler/Filter/Combinator/FiltersOr.php
@@ -26,7 +26,7 @@ final class FiltersOr extends Filter
{
$final = [];
foreach ($this->filters as $filter) {
- $filter = $filter->initialize($API) ?? $filter;
+ $filter = $filter->initialize($API);
if ($filter instanceof self) {
$final = \array_merge($final, $filter->filters);
} else {
diff --git a/src/EventHandler/Filter/Filter.php b/src/EventHandler/Filter/Filter.php
index 57c31497f..bda6eb332 100644
--- a/src/EventHandler/Filter/Filter.php
+++ b/src/EventHandler/Filter/Filter.php
@@ -46,9 +46,9 @@ abstract class Filter
{
abstract public function apply(Update $update): bool;
/** Run some initialization logic, optionally returning a new filter to replace the current one. */
- public function initialize(EventHandler $API): ?Filter
+ public function initialize(EventHandler $API): Filter
{
- return null;
+ return $this;
}
public static function fromReflectionType(ReflectionType $type): Filter
diff --git a/src/EventHandler/Filter/FilterFromAdmin.php b/src/EventHandler/Filter/FilterFromAdmin.php
index 5d8c85efa..5bd7f116d 100644
--- a/src/EventHandler/Filter/FilterFromAdmin.php
+++ b/src/EventHandler/Filter/FilterFromAdmin.php
@@ -14,10 +14,10 @@ use danog\MadelineProto\EventHandler\Update;
final class FilterFromAdmin extends Filter
{
private readonly array $adminIds;
- public function initialize(EventHandler $API): ?Filter
+ public function initialize(EventHandler $API): Filter
{
$this->adminIds = $API->getAdminIds();
- return null;
+ return $this;
}
public function apply(Update $update): bool
{
diff --git a/src/EventHandler/Filter/FilterFromSenders.php b/src/EventHandler/Filter/FilterFromSenders.php
index 22e87394f..93ab65183 100644
--- a/src/EventHandler/Filter/FilterFromSenders.php
+++ b/src/EventHandler/Filter/FilterFromSenders.php
@@ -21,14 +21,14 @@ final class FilterFromSenders extends Filter
{
$this->peers = \array_unique($idOrUsername);
}
- public function initialize(EventHandler $API): ?Filter
+ public function initialize(EventHandler $API): Filter
{
$res = [];
foreach ($this->peers as $peer) {
$res []= $API->getId($peer);
}
$this->peersResolved = $res;
- return null;
+ return $this;
}
public function apply(Update $update): bool
{
diff --git a/src/EventHandler/Filter/FilterPeer.php b/src/EventHandler/Filter/FilterPeer.php
index c09d1fbf0..156b548b6 100644
--- a/src/EventHandler/Filter/FilterPeer.php
+++ b/src/EventHandler/Filter/FilterPeer.php
@@ -17,10 +17,10 @@ final class FilterPeer extends Filter
public function __construct(private readonly string|int $peer)
{
}
- public function initialize(EventHandler $API): ?Filter
+ public function initialize(EventHandler $API): Filter
{
$this->peerResolved = $API->getId($this->peer);
- return null;
+ return $this;
}
public function apply(Update $update): bool
{
diff --git a/src/EventHandler/Filter/FilterSender.php b/src/EventHandler/Filter/FilterSender.php
index bbd9cdbe9..2cb198ba3 100644
--- a/src/EventHandler/Filter/FilterSender.php
+++ b/src/EventHandler/Filter/FilterSender.php
@@ -17,10 +17,10 @@ final class FilterSender extends Filter
public function __construct(private readonly string|int $peer)
{
}
- public function initialize(EventHandler $API): ?Filter
+ public function initialize(EventHandler $API): Filter
{
$this->peerResolved = $API->getId($this->peer);
- return null;
+ return $this;
}
public function apply(Update $update): bool
{
diff --git a/src/Ipc/Runner/RunnerAbstract.php b/src/Ipc/Runner/RunnerAbstract.php
index daf8bbd83..a278d75b8 100644
--- a/src/Ipc/Runner/RunnerAbstract.php
+++ b/src/Ipc/Runner/RunnerAbstract.php
@@ -27,12 +27,6 @@ abstract class RunnerAbstract
if (\defined('MADELINE_PHP')) {
return \MADELINE_PHP;
}
- /**
- * If using madeline.phar, simply return madeline.phar path.
- */
- if (\defined('MADELINE_PHAR')) {
- return \MADELINE_PHAR;
- }
// Write process runner to external file if inside a PHAR different from madeline.phar,
// because PHP can't open files inside a PHAR directly except for the stub.
if (\strpos(self::SCRIPT_PATH, 'phar://') === 0) {
diff --git a/src/Ipc/Runner/WebRunner.php b/src/Ipc/Runner/WebRunner.php
index 899eebf41..446607180 100644
--- a/src/Ipc/Runner/WebRunner.php
+++ b/src/Ipc/Runner/WebRunner.php
@@ -65,6 +65,7 @@ final class WebRunner extends RunnerAbstract
$params = [
'argv' => ['madeline-ipc', $session, $startupId],
'cwd' => Magic::getcwd(),
+ 'MadelineSelfRestart' => 1
];
if (\function_exists('memprof_enabled') && \memprof_enabled()) {
$params['MEMPROF_PROFILE'] = '1';
diff --git a/src/Lang.php b/src/Lang.php
index 0fe2e7b44..f61dd2011 100644
--- a/src/Lang.php
+++ b/src/Lang.php
@@ -441,7 +441,7 @@ final class Lang
'plugins_do_not_use_require' => 'به دلایل عملکردی و اجرایی، پلاگینها فقط میتوانند فایل های دیگر را که در پوشه پلاگین هاست با استفاده از راهاندازی بارگذار خودکار PSR-4، به صورت خودکار include یا require کنند (بدون require کردن دستی آنها).',
'plugins_must_have_exactly_one_class' => 'یک پلاگین باید دقیقا یک کلس را تعریف کند! برای تعریف چند کلس، اینترفیس یا تریت، فایلهای جداگانه بسازید، آنها توسط مدلینپروتو به صورت خودکار بارگذاری خواهند شد.',
'predicate_not_set' => 'مستند (مقدار تحت _) تنظیم نشده!',
- 'recommend_not_use_filesystem_function' => 'استفاده از تابع %s پیشنهاد نمیشود، چراکه دسترسی و کار با فایل های سیستمی موقع پردازش آپدیت باعث کم شدن سرعت ربات شما میشود، لطفا صفحه https://docs.madelineproto.xyz/docs/UPDATES.html#avoiding-the-use-of-filesystem-functions را ببینید تا با راههای جایگزین برای ذخیره اطلاعات که باعث کاهش سرعت نمیشوند آشنا شوید!',
+ 'recommend_not_use_filesystem_function' => 'استفاده از تابع %s پیشنهاد نمیشود، چراکه دسترسی و کار با فایل های سیستمی موقع پردازش آپدیت باعث کم شدن سرعت ربات شما میشود، لطفا صفحه https://docs.madelineproto.xyz/docs/UPDATES.html#avoiding-the-use-of-filesystem-functions را ببینید تا با راههای جایگزین برای ذخیره اطلاعات که باعث کاهش سرعت ربات شما نمیشوند آشنا شوید!',
'rpc_tg_error' => 'تلگرام یک خطای RPC برگرداند: %s (%s), ناشی از %s:%s%sTL رد:',
'sec_peer_not_in_db' => 'این peer مخفی در پایگاه داده (دیتابیس) داخلی peer وجود ندارد',
'secret_chat_skipping' => 'من چت مخفی (سکرت) %s را در پایگاه داده (دیتابیس) ندارم، درحال رد شدن از پیام...',
diff --git a/src/MTProto.php b/src/MTProto.php
index 7cd6f2321..b34afdf25 100644
--- a/src/MTProto.php
+++ b/src/MTProto.php
@@ -1654,6 +1654,7 @@ final class MTProto implements TLCallback, LoggerGetter
}
} catch (Throwable $e) {
unset($userOrId[$k]);
+ $peer = \json_encode($peer);
$this->logger("Could not obtain info about report peer $peer: $e", Logger::FATAL_ERROR);
}
}
diff --git a/src/MTProtoTools/FileServer.php b/src/MTProtoTools/FileServer.php
index 20957170d..dab7f012c 100644
--- a/src/MTProtoTools/FileServer.php
+++ b/src/MTProtoTools/FileServer.php
@@ -46,9 +46,11 @@ trait FileServer
*/
public static function downloadServer(string $session): void
{
- if (isset($_GET['c'])) {
+ if (isset($_GET['ping'])) {
$API = new API($session);
- $API->processDownloadServerPing($_GET['c'], $_GET['i']);
+ $id = (string) $API->getSelf()['id'];
+ header("Content-length: ".strlen($id));
+ echo $id;
die;
}
if (!isset($_GET['f'])) {
@@ -110,7 +112,7 @@ trait FileServer
$messageMedia['mime'] ??= $mime;
$messageMedia['name'] ??= $name;
- $f = is_string($media) ? $media : ($this->extractBotAPIFile($this->MTProtoToBotAPI($media))['file_id']);
+ $f = \is_string($media) ? $media : ($this->extractBotAPIFile($this->MTProtoToBotAPI($media))['file_id']);
[
'name' => $name,
'ext' => $ext,
@@ -208,25 +210,20 @@ trait FileServer
if (isset(self::$checkedScripts[$scriptUrl])) {
return;
}
- $i = (string) \random_int(PHP_INT_MIN, PHP_INT_MAX);
- $scriptUrlNew = $scriptUrl.'?'.\http_build_query(['c' => $scriptUrl, 'i' => $i]);
+ $scriptUrlNew = $scriptUrl.'?'.\http_build_query(['ping' => 1]);
$this->logger->logger("Checking $scriptUrlNew...");
- $this->fileGetContents($scriptUrlNew);
- if (!isset(self::$checkedScripts[$scriptUrl])) {
+ $result = $this->fileGetContents($scriptUrlNew);
+ $expected = (string) $this->getSelf()['id'];
+ if ($result !== $expected) {
throw new AssertionError(\sprintf(
- Lang::$current_lang['invalid_dl.php'],
+ Lang::$current_lang['invalid_dl.php_session'],
$scriptUrl,
- "the check array wasn't populated"
- ));
- }
- if (self::$checkedScripts[$scriptUrl] !== $i) {
- $v = self::$checkedScripts[$scriptUrl];
- throw new AssertionError(\sprintf(
- Lang::$current_lang['invalid_dl.php'],
- $scriptUrl,
- "the check array contains {$v} instead of $i"
+ $expected,
+ $result,
));
}
+
+ self::$checkedScripts[$scriptUrl] = true;
} finally {
$lock->release();
}
diff --git a/src/MTProtoTools/Files.php b/src/MTProtoTools/Files.php
index 6323f9823..6758d0f97 100644
--- a/src/MTProtoTools/Files.php
+++ b/src/MTProtoTools/Files.php
@@ -534,9 +534,12 @@ trait Files
}
$info = $info[$method];
if ($method === 'photo') {
+ $info = array_values($info);
$cur = $info[0];
foreach ($info as $n) {
- if ($n['width'] * $n['height'] > $cur['width'] * $cur['height']) $cur = $n;
+ if ($n['width'] * $n['height'] > $cur['width'] * $cur['height']) {
+ $cur = $n;
+ }
}
$info = $cur;
}