1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 04:08:59 +01:00
This commit is contained in:
Daniil Gentili 2023-07-11 20:23:34 +02:00
parent 392ecdf08c
commit df1019c941
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 91 additions and 85 deletions

View File

@ -17,15 +17,17 @@ Features:
- Added support for `pay`, `login_url`, `web_app` and `tg://user?id=` buttons in bot API syntax!
- Added a `getAdmin` function that returns the ID of the admin of the bot (which is equal to the first peer returned by getReportPeers in the event handler).
- getPlugin can now be used from IPC clients!
- `getReply`, `sendMessage`, `reply`
- `getReply`, `sendMessage`, `sendDocument`, `sendPhoto`, `reply`, `delete`
Fixes:
- Fixed file uploads with ext-uv!
- Many performance improvements and bugfixes!
- Fixed file re-uploads!
- Improve background broadcasting with the broadcast API using a pre-defined list of `whitelist` IDs!
- Fixed a bug that caused updates to get paused if an exception is thrown during onStart.
- Broadcast IDs are now unique across multiple broadcasts, even if previous broadcasts already completed their ID will never be re-used.
- Now uploadMedia, sendMedia and upload can upload files from string buffers created using `ReadableBuffer`.
- Reduce memory usage during flood waits by tweaking config defaults.
- Reduce memory usage by clearing the min database automatically as needed.
- Automatically try caching all dialogs if a peer not found error is about to be thrown
- Fix some issues with pure phar installs
- And many performance improvements and bugfixes!

View File

@ -22,7 +22,6 @@
use danog\MadelineProto\API;
use danog\MadelineProto\Broadcast\Progress;
use danog\MadelineProto\Broadcast\Status;
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\EventHandler\Attributes\Cron;
use danog\MadelineProto\EventHandler\Attributes\Handler;
use danog\MadelineProto\EventHandler\Filter\FilterCommand;
@ -34,6 +33,7 @@ use danog\MadelineProto\Settings;
use danog\MadelineProto\Settings\Database\Mysql;
use danog\MadelineProto\Settings\Database\Postgres;
use danog\MadelineProto\Settings\Database\Redis;
use danog\MadelineProto\SimpleEventHandler;
// MadelineProto is already loaded
if (class_exists(API::class)) {
@ -52,7 +52,7 @@ if (class_exists(API::class)) {
*
* All properties returned by __sleep are automatically stored in the database.
*/
class MyEventHandler extends EventHandler
class MyEventHandler extends SimpleEventHandler
{
/**
* @var int|string Username or ID of bot admin
@ -145,11 +145,9 @@ class MyEventHandler extends EventHandler
if (!isset($this->notifiedChats[$message->chatId])) {
$this->notifiedChats[$message->chatId] = true;
$this->messages->sendMessage(
peer: $message->chatId,
$message->reply(
message: "This userbot is powered by [MadelineProto](https://t.me/MadelineProto)!",
reply_to_msg_id: $message->id,
parse_mode: 'Markdown'
parseMode: 'Markdown'
);
}
}
@ -170,11 +168,7 @@ class MyEventHandler extends EventHandler
// We can broadcast messages to all users.
if ($message->senderId === $this->adminId) {
if (!$message->replyToMsgId) {
$this->messages->sendMessage(
peer: $message->senderId,
message: "You should reply to the message you want to broadcast.",
reply_to_msg_id: $message->id,
);
$message->reply("You should reply to the message you want to broadcast.");
return;
}
$this->broadcastForwardMessages(
@ -190,7 +184,7 @@ class MyEventHandler extends EventHandler
#[FilterText('ping')]
public function pingCommand(Incoming&Message $message): void
{
$this->messages->sendMessage(['message' => 'pong', 'peer' => $message->chatId]);
$message->reply('pong');
}
}

View File

@ -42,6 +42,7 @@ use PhpParser\Node\Expr\Include_;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\DeclareDeclare;
use PhpParser\NodeFinder;
use PhpParser\NodeVisitor\NameResolver;
@ -470,7 +471,11 @@ abstract class EventHandler extends AbstractAPI
}
}
if ($finder->findFirstInstanceOf($file, Include_::class)) {
/** @var Include_ $include */
$include = $finder->findFirstInstanceOf($file, Include_::class);
if ($include
&& !($include->expr instanceof String_ && \in_array($include->expr->value, ['vendor/autoload.php', 'madeline.php', 'madeline.phar'], true))
) {
throw new AssertionError("An error occurred while analyzing plugin $class: for performance reasons, plugins can only automatically include or require other files present in the plugins folder by triggering the PSR-4 autoloader (not by manually require()'ing them).");
}
}

View File

@ -487,8 +487,11 @@ final class MTProto implements TLCallback, LoggerGetter
$initDeferred = new DeferredFuture;
$this->initPromise = $initDeferred->getFuture();
$this->initialize($settings);
$initDeferred->complete();
try {
$this->initialize($settings);
} finally {
$initDeferred->complete();
}
}
/**
@ -976,80 +979,82 @@ final class MTProto implements TLCallback, LoggerGetter
$deferred = new DeferredFuture;
$this->initPromise = $deferred->getFuture();
// Cleanup old properties, init new stuffs
$this->cleanupProperties();
try {
// Cleanup old properties, init new stuffs
$this->cleanupProperties();
// Re-set TL closures
$callbacks = [$this];
if ($this->settings->getDb()->getEnableFileReferenceDb()) {
$callbacks []= $this->referenceDatabase;
}
if (!($this->authorization['user']['bot'] ?? false) && $this->settings->getDb()->getEnableMinDb()) {
$callbacks[] = $this->minDatabase;
}
$this->TL->updateCallbacks($callbacks);
// Clean up phone call array
foreach ($this->calls as $id => $controller) {
if (!\is_object($controller)) {
unset($this->calls[$id]);
} elseif ($controller->getCallState() === VoIP::CALL_STATE_ENDED) {
$controller->setMadeline($this);
$controller->discard();
} else {
$controller->setMadeline($this);
// Re-set TL closures
$callbacks = [$this];
if ($this->settings->getDb()->getEnableFileReferenceDb()) {
$callbacks []= $this->referenceDatabase;
}
if (!($this->authorization['user']['bot'] ?? false) && $this->settings->getDb()->getEnableMinDb()) {
$callbacks[] = $this->minDatabase;
}
}
$this->settings->getConnection()->init();
// Setup logger
$this->setupLogger();
// Setup language
Lang::$current_lang =& Lang::$lang['en'];
if (Lang::$lang[$this->settings->getAppInfo()->getLangCode()] ?? false) {
Lang::$current_lang =& Lang::$lang[$this->settings->getAppInfo()->getLangCode()];
}
// Reset MTProto session (not related to user session)
$this->resetMTProtoSession();
// Update settings from constructor
$this->updateSettings($settings);
// Update TL callbacks
$callbacks = [$this];
if ($this->settings->getDb()->getEnableFileReferenceDb()) {
$callbacks[] = $this->referenceDatabase;
}
if ($this->settings->getDb()->getEnableMinDb() && !($this->authorization['user']['bot'] ?? false)) {
$callbacks[] = $this->minDatabase;
}
// Connect to all DCs, start internal loops
$this->connectToAllDcs();
if ($this->fullGetSelf()) {
$this->authorized = API::LOGGED_IN;
$this->TL->updateCallbacks($callbacks);
// Clean up phone call array
foreach ($this->calls as $id => $controller) {
if (!\is_object($controller)) {
unset($this->calls[$id]);
} elseif ($controller->getCallState() === VoIP::CALL_STATE_ENDED) {
$controller->setMadeline($this);
$controller->discard();
} else {
$controller->setMadeline($this);
}
}
$this->settings->getConnection()->init();
// Setup logger
$this->setupLogger();
$this->startLoops();
$this->getCdnConfig();
$this->initAuthorization();
} else {
$this->startLoops();
}
// onStart event handler
if ($this->event_handler && \class_exists($this->event_handler) && \is_subclass_of($this->event_handler, EventHandler::class)) {
$this->setEventHandler($this->event_handler);
}
$this->startUpdateSystem(true);
$this->cacheFullDialogs();
if ($this->authorized === API::LOGGED_IN) {
$this->logger->logger("Obtaining updates after deserialization...", Logger::NOTICE);
$this->updaters[UpdateLoop::GENERIC]->resume();
}
$this->updaters[UpdateLoop::GENERIC]->start();
// Setup language
Lang::$current_lang =& Lang::$lang['en'];
if (Lang::$lang[$this->settings->getAppInfo()->getLangCode()] ?? false) {
Lang::$current_lang =& Lang::$lang[$this->settings->getAppInfo()->getLangCode()];
}
// Reset MTProto session (not related to user session)
$this->resetMTProtoSession();
// Update settings from constructor
$this->updateSettings($settings);
// Update TL callbacks
$callbacks = [$this];
if ($this->settings->getDb()->getEnableFileReferenceDb()) {
$callbacks[] = $this->referenceDatabase;
}
if ($this->settings->getDb()->getEnableMinDb() && !($this->authorization['user']['bot'] ?? false)) {
$callbacks[] = $this->minDatabase;
}
// Connect to all DCs, start internal loops
$this->connectToAllDcs();
if ($this->fullGetSelf()) {
$this->authorized = API::LOGGED_IN;
$this->setupLogger();
$this->startLoops();
$this->getCdnConfig();
$this->initAuthorization();
} else {
$this->startLoops();
}
// onStart event handler
if ($this->event_handler && \class_exists($this->event_handler) && \is_subclass_of($this->event_handler, EventHandler::class)) {
$this->setEventHandler($this->event_handler);
}
$this->startUpdateSystem(true);
$this->cacheFullDialogs();
if ($this->authorized === API::LOGGED_IN) {
$this->logger->logger("Obtaining updates after deserialization...", Logger::NOTICE);
$this->updaters[UpdateLoop::GENERIC]->resume();
}
$this->updaters[UpdateLoop::GENERIC]->start();
foreach ($this->broadcasts as $broadcast) {
$broadcast->resume();
foreach ($this->broadcasts as $broadcast) {
$broadcast->resume();
}
} finally {
$deferred->complete();
}
$deferred->complete();
}
/**
* Unreference instance, allowing destruction.