Skip to content

Commit aa42bb7

Browse files
committed
File reference improvements
1 parent 2ab76c7 commit aa42bb7

3 files changed

Lines changed: 76 additions & 61 deletions

File tree

src/MTProto/MTProtoOutgoingMessage.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Amp\CancelledException;
2525
use Amp\DeferredFuture;
2626
use Amp\Future;
27+
use Closure;
2728
use danog\MadelineProto\Connection;
2829
use danog\MadelineProto\Exception;
2930
use Revolt\EventLoop;
@@ -400,12 +401,10 @@ public function refreshReferences(): Future
400401
{
401402
$this->serializedBody = null;
402403

403-
return async(function (): void {
404+
return async(function (): ?Closure {
404405
$this->connection->API->referenceDatabase->refreshNextEnable();
405406
$this->connection->API->getTL()->serializeMethod($this->constructor, $this->body);
406-
$this->connection->API->referenceDatabase->refreshNextDisable();
407-
408-
$this->serializedBody = null;
407+
return $this->connection->API->referenceDatabase->refreshNextDisable();
409408
});
410409
}
411410

src/MTProtoSession/CallHandler.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use Amp\Future;
2626
use Amp\Sync\LocalKeyedMutex;
2727
use Amp\TimeoutCancellation;
28+
use Closure;
2829
use danog\MadelineProto\DataCenterConnection;
2930
use danog\MadelineProto\MTProto;
3031
use danog\MadelineProto\MTProto\Container;
@@ -80,7 +81,13 @@ public function methodRecall(MTProtoOutgoingMessage $request, ?int $forceDatacen
8081
$request->unlink();
8182
if ($defer) {
8283
$defer->catch($request->reply(...));
83-
$defer->map(fn () => $this->methodRecall($request, $forceDatacenter));
84+
$defer->map(function ($result) use ($request, $forceDatacenter): void {
85+
if ($result instanceof Closure) {
86+
$request->reply($result);
87+
} else {
88+
$this->methodRecall($request, $forceDatacenter);
89+
}
90+
});
8491
return;
8592
}
8693
$datacenter = $forceDatacenter ?? $this->datacenter;

src/MTProtoTools/ReferenceDatabase.php

Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
namespace danog\MadelineProto\MTProtoTools;
2222

2323
use Amp\Sync\LocalKeyedMutex;
24+
use Closure;
2425
use danog\AsyncOrm\Annotations\OrmMappedArray;
2526
use danog\AsyncOrm\DbArray;
2627
use danog\AsyncOrm\KeyType;
@@ -452,74 +453,80 @@ public function refreshNextEnable(): void
452453
Assert::false($this->refresh, 'Cannot enable refresh when it is already enabled');
453454
$this->refresh = true;
454455
}
455-
public function refreshNextDisable(): void
456+
public function refreshNextDisable(): ?Closure
456457
{
457458
Assert::true($this->refresh, 'Cannot disable refresh when it is already disabled');
458459
$this->refresh = false;
459460
$queue = $this->refreshQueue;
460461
$this->refreshQueue = [];
461462

462463
$ok = false;
463-
foreach ($queue as $locationString => $data) {
464+
foreach ($queue as $locationString => $_) {
465+
$data = $this->getDb($locationString);
464466
$data['reference'] = (string) $data['reference'];
465467
$count = 0;
466-
foreach ($data['origins'] as $originType => $origin) {
468+
foreach ($data['origins'] ?? [] as $originType => $origin) {
467469
$count++;
468470
$this->API->logger("Try {$count} refreshing file reference with origin type {$originType}", Logger::VERBOSE);
469471
$origin['specialMethodType'] = SpecialMethodType::FILEREF_RELATED;
470-
switch ($originType) {
471-
// Peer + msg ID
472-
case self::MESSAGE_ORIGIN:
473-
if (\is_array($origin['peer'])) {
474-
$origin['peer'] = $this->API->getIdInternal($origin['peer']);
475-
}
476-
if ($origin['peer'] < 0) {
477-
$this->API->methodCallAsyncRead('channels.getMessages', ['channel' => $origin['peer'], 'id' => [$origin['msg_id']]]);
472+
try {
473+
switch ($originType) {
474+
// Peer + msg ID
475+
case self::MESSAGE_ORIGIN:
476+
if (\is_array($origin['peer'])) {
477+
$origin['peer'] = $this->API->getIdInternal($origin['peer']);
478+
}
479+
if ($origin['peer'] < 0) {
480+
$this->API->methodCallAsyncRead('channels.getMessages', ['channel' => $origin['peer'], 'id' => [$origin['msg_id']]]);
481+
break;
482+
}
483+
$this->API->methodCallAsyncRead('messages.getMessages', ['id' => [$origin['msg_id']]]);
478484
break;
479-
}
480-
$this->API->methodCallAsyncRead('messages.getMessages', ['id' => [$origin['msg_id']]]);
481-
break;
482-
// Peer + photo ID
483-
case self::PEER_PHOTO_ORIGIN:
484-
$this->API->peerDatabase->expireFull($origin['peer']);
485-
$this->API->getFullInfo($origin['peer']);
486-
break;
487-
// Peer (default photo ID)
488-
case self::USER_PHOTO_ORIGIN:
489-
$this->API->methodCallAsyncRead('photos.getUserPhotos', $origin);
490-
break;
491-
case self::SAVED_GIFS_ORIGIN:
492-
$this->API->methodCallAsyncRead('messages.getSavedGifs', $origin);
493-
break;
494-
case self::STICKER_SET_ID_ORIGIN:
495-
$this->API->methodCallAsyncRead('messages.getStickerSet', $origin);
496-
break;
497-
case self::STICKER_SET_RECENT_ORIGIN:
498-
$this->API->methodCallAsyncRead('messages.getRecentStickers', $origin);
499-
break;
500-
case self::STICKER_SET_FAVED_ORIGIN:
501-
$this->API->methodCallAsyncRead('messages.getFavedStickers', $origin);
502-
break;
503-
case self::STICKER_SET_EMOTICON_ORIGIN:
504-
$this->API->methodCallAsyncRead('messages.getStickers', $origin);
505-
break;
506-
case self::WALLPAPER_ORIGIN:
507-
$this->API->methodCallAsyncRead('account.getWallPapers', $origin);
485+
// Peer + photo ID
486+
case self::PEER_PHOTO_ORIGIN:
487+
$this->API->peerDatabase->expireFull($origin['peer']);
488+
$this->API->getFullInfo($origin['peer']);
489+
break;
490+
// Peer (default photo ID)
491+
case self::USER_PHOTO_ORIGIN:
492+
$this->API->methodCallAsyncRead('photos.getUserPhotos', $origin);
493+
break;
494+
case self::SAVED_GIFS_ORIGIN:
495+
$this->API->methodCallAsyncRead('messages.getSavedGifs', $origin);
496+
break;
497+
case self::STICKER_SET_ID_ORIGIN:
498+
$this->API->methodCallAsyncRead('messages.getStickerSet', $origin);
499+
break;
500+
case self::STICKER_SET_RECENT_ORIGIN:
501+
$this->API->methodCallAsyncRead('messages.getRecentStickers', $origin);
502+
break;
503+
case self::STICKER_SET_FAVED_ORIGIN:
504+
$this->API->methodCallAsyncRead('messages.getFavedStickers', $origin);
505+
break;
506+
case self::STICKER_SET_EMOTICON_ORIGIN:
507+
$this->API->methodCallAsyncRead('messages.getStickers', $origin);
508+
break;
509+
case self::WALLPAPER_ORIGIN:
510+
$this->API->methodCallAsyncRead('account.getWallPapers', $origin);
511+
break;
512+
default:
513+
throw new Exception("Unknown origin type {$originType}");
514+
}
515+
$got = (string) $this->getDb($locationString)['reference'];
516+
if ($got !== $data['reference']) {
517+
$ok = true;
508518
break;
509-
default:
510-
throw new Exception("Unknown origin type {$originType}");
511-
}
512-
$got = (string) $this->getDb($locationString)['reference'];
513-
if ($got !== $data['reference']) {
514-
$ok = true;
515-
break;
519+
}
520+
} catch (\Throwable $e) {
521+
$this->API->logger("Could not refresh file reference for location {$locationString} with origin type {$originType}: $e", Logger::ERROR);
516522
}
517523
}
518524
}
519525
if (!$ok) {
520526
$count = \count($queue);
521-
throw new Exception("Could not refresh file reference for any of the {$count} locations");
527+
return static fn () => new Exception("Could not refresh file reference for any of the {$count} locations");
522528
}
529+
return null;
523530
}
524531
private function populateReference(array $object): array
525532
{
@@ -536,7 +543,13 @@ private function getDb(string $location): ?array
536543
public function getReference(int $locationType, array $location): string
537544
{
538545
$locationString = self::serializeLocation($locationType, $location);
539-
$res = $this->getDb($locationString);
546+
if ($this->refresh) {
547+
$this->refreshQueue[$locationString] = true;
548+
$res = [];
549+
} else {
550+
$res = $this->getDb($locationString);
551+
}
552+
540553
if (!isset($res['reference'])) {
541554
if (isset($location['file_reference'])) {
542555
$this->API->logger("Using outdated file reference for location of type {$locationType} object {$location['_']}", Logger::ULTRA_VERBOSE);
@@ -546,18 +559,14 @@ public function getReference(int $locationType, array $location): string
546559
}
547560
return (string) $location['file_reference'];
548561
}
549-
if (!$this->refresh) {
562+
if ($this->refresh) {
550563
$this->API->logger("Using null file reference for location of type {$locationType} object {$location['_']}", Logger::ULTRA_VERBOSE);
551564
return '';
552565
}
553566
throw new Exception("Could not find file reference for location of type {$locationType} object {$location['_']}");
554567
}
555-
$this->API->logger("Getting file reference for location of type {$locationType} object {$location['_']}", Logger::ULTRA_VERBOSE);
556-
$data = $this->getDb($locationString);
557-
if ($this->refresh) {
558-
$this->refreshQueue[$locationString] = $data;
559-
}
560-
return (string) $data['reference'];
568+
$this->API->logger("Got file reference for location of type {$locationType} object {$location['_']}", Logger::ULTRA_VERBOSE);
569+
return (string) $res['reference'];
561570
}
562571
private static function serializeLocation(int $locationType, array $location): string
563572
{

0 commit comments

Comments
 (0)