1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-22 23:51:12 +01:00

Multiple fixes

This commit is contained in:
Daniil Gentili 2024-04-19 16:31:11 +02:00
parent 173d1501d8
commit 4bb21c0682
8 changed files with 86 additions and 264 deletions

View File

@ -35,7 +35,6 @@ use danog\MadelineProto\EventHandler\Plugin\RestartPlugin;
use danog\MadelineProto\EventHandler\SimpleFilter\FromAdmin;
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
use danog\MadelineProto\EventHandler\SimpleFilter\IsReply;
use danog\MadelineProto\LocalFile;
use danog\MadelineProto\Logger;
use danog\MadelineProto\ParseMode;
use danog\MadelineProto\RemoteUrl;

View File

@ -21,14 +21,11 @@ use danog\MadelineProto\EventHandler\Attributes\Handler;
use danog\MadelineProto\EventHandler\Message\PrivateMessage;
use danog\MadelineProto\EventHandler\Message\SecretMessage;
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
use danog\MadelineProto\LocalFile;
use danog\MadelineProto\Logger;
use danog\MadelineProto\Settings;
use danog\MadelineProto\SimpleEventHandler;
use function Amp\async;
use function Amp\File\read;
use function Amp\Future\await;
/*
* Various ways to load MadelineProto
*/
@ -86,234 +83,51 @@ class SecretHandler extends SimpleEventHandler
if (isset($this->sent[$update->chatId])) {
return;
}
$secret_media = [];
// Photo uploaded as document, secret chat
$secret_media['document_photo'] = [
'peer' => $update->chatId,
'file' => 'tests/faust.jpg',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/faust.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => mime_content_type('tests/faust.jpg'),
'caption' => 'This file was uploaded using MadelineProto',
'file_name' => 'faust.jpg',
'size' => filesize('tests/faust.jpg'),
'attributes' => [
[
'_' => 'documentAttributeImageSize',
'w' => 1280,
'h' => 914,
],
],
],
],
];
// Photo, secret chat
$secret_media['photo'] = [
'peer' => $update->chatId,
'file' => 'tests/faust.jpg',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaPhoto',
'thumb' => read('tests/faust.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'caption' => 'This file was uploaded using MadelineProto',
'size' => filesize('tests/faust.jpg'),
'w' => 1280,
'h' => 914,
],
],
];
$this->sendPhoto(
peer: $update->chatId,
file: new LocalFile('tests/faust.jpg'),
caption: 'This file was uploaded using MadelineProto',
);
// GIF, secret chat
$secret_media['gif'] = [
'peer' => $update->chatId,
'file' => 'tests/pony.mp4',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/pony.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => mime_content_type('tests/pony.mp4'),
'caption' => 'test',
'file_name' => 'pony.mp4',
'size' => filesize('tests/faust.jpg'),
'attributes' => [
['_' => 'documentAttributeAnimated'],
],
],
],
];
$this->sendGif(
peer: $update->chatId,
file: new LocalFile('tests/pony.mp4'),
caption: 'This file was uploaded using MadelineProto',
);
// Sticker, secret chat
$secret_media['sticker'] = [
'peer' => $update->chatId,
'file' => 'tests/lel.webp',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/lel.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => mime_content_type('tests/lel.webp'),
'caption' => 'test',
'file_name' => 'lel.webp',
'size' => filesize('tests/lel.webp'),
'attributes' => [
[
'_' => 'documentAttributeImageSize',
'w' => 512,
'h' => 510,
],
[
'_' => 'documentAttributeSticker',
'alt' => 'LEL',
'stickerset' => ['_' => 'inputStickerSetEmpty'],
],
],
],
],
];
$this->sendSticker(
peer: $update->chatId,
file: new LocalFile('tests/lel.webp'),
mimeType: "image/webp"
);
// Document, secrey chat
$secret_media['document'] = [
'peer' => $update->chatId,
'file' => 'tests/60',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/faust.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => 'magic/magic',
'caption' => 'test',
'file_name' => 'magic.magic',
'size' => filesize('tests/60'),
'attributes' => [
[
'_' => 'documentAttributeFilename',
'file_name' => 'fairy',
],
],
],
],
];
// Document, secret chat
$this->sendDocument(
peer: $update->chatId,
file: new LocalFile('tests/60'),
fileName: 'fairy'
);
// Video, secret chat
$secret_media['video'] = [
'peer' => $update->chatId,
'file' => 'tests/swing.mp4',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/swing.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => mime_content_type('tests/swing.mp4'),
'caption' => 'test',
'file_name' => 'swing.mp4',
'size' => filesize('tests/swing.mp4'),
'attributes' => [
[
'_' => 'documentAttributeVideo',
'duration' => 5,
'w' => 1280,
'h' => 720,
],
],
],
],
];
$this->sendVideo(
peer: $update->chatId,
file: new LocalFile('tests/swing.mp4'),
);
// audio, secret chat
$secret_media['audio'] = [
'peer' => $update->chatId,
'file' => 'tests/mosconi.mp3',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/faust.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => mime_content_type('tests/mosconi.mp3'),
'caption' => 'test',
'file_name' => 'mosconi.mp3',
'size' => filesize('tests/mosconi.mp3'),
'attributes' => [
[
'_' => 'documentAttributeAudio',
'voice' => false,
'duration' => 1,
'title' => 'AH NON LO SO IO',
'performer' => 'IL DIO GERMANO MOSCONI',
],
],
],
],
];
$this->sendAudio(
peer: $update->chatId,
file: new LocalFile('tests/mosconi.mp3'),
);
$secret_media['voice'] = [
'peer' => $update->chatId,
'file' => 'tests/mosconi.mp3',
'message' => [
'_' => 'decryptedMessage',
'ttl' => 0,
'message' => '',
'media' => [
'_' => 'decryptedMessageMediaDocument',
'thumb' => read('tests/faust.preview.jpg'),
'thumb_w' => 90,
'thumb_h' => 90,
'mime_type' => mime_content_type('tests/mosconi.mp3'),
'caption' => 'test',
'file_name' => 'mosconi.mp3',
'size' => filesize('tests/mosconi.mp3'),
'attributes' => [
[
'_' => 'documentAttributeAudio',
'voice' => true,
'duration' => 1,
'title' => 'AH NON LO SO IO',
'performer' => 'IL DIO GERMANO MOSCONI',
],
],
],
],
];
$promises = [];
foreach ($secret_media as $type => $smessage) {
$promises []= async($this->messages->sendEncryptedFile(...), $smessage);
}
await($promises);
$this->sendVoice(
peer: $update->chatId,
file: new LocalFile('tests/mosconi.mp3'),
);
$i = 0;
while ($i < 10) {

View File

@ -4115,6 +4115,8 @@
<code><![CDATA[$file]]></code>
<code><![CDATA[$file]]></code>
<code><![CDATA[$file]]></code>
<code><![CDATA[$file]]></code>
<code><![CDATA[$file]]></code>
</ReferenceConstraintViolation>
</file>
<file src="src/MTProtoTools/FilesLogic.php">
@ -5483,7 +5485,7 @@
<code><![CDATA[SecretMessage]]></code>
</MoreSpecificReturnType>
<PossiblyNullOperand>
<code><![CDATA[$user['user_id']]]></code>
<code><![CDATA[$user]]></code>
</PossiblyNullOperand>
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$user['user_id']]]></code>

View File

@ -44,9 +44,9 @@ abstract class AbstractVideo extends Media
bool $protected,
) {
parent::__construct($API, $rawMedia, $protected);
$this->duration = $attribute['duration'];
$this->duration = $attribute['duration'] ?? 0.0;
$this->supportsStreaming = $attribute['supports_streaming'] ?? false;
$this->width = $attribute['w'];
$this->height = $attribute['h'];
$this->width = $attribute['w'] ?? 0;
$this->height = $attribute['h'] ?? 0;
}
}

View File

@ -1836,9 +1836,11 @@ abstract class InternalDoc
* @param Cancellation $cancellation Cancellation.
*
*/
final public function sendSticker(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, string $emoji = '', ?callable $callback = null, ?string $fileName = null, ?string $mimeType = null, ?int $ttl = null, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $updateStickersetsOrder = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
final public function sendSticker(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, string $mimeType, string $emoji = '', array $stickerSet = [
'_' => 'inputStickerSetEmpty',
], ?callable $callback = null, ?string $fileName = null, ?int $ttl = null, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $updateStickersetsOrder = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
{
return $this->wrapper->getAPI()->sendSticker($peer, $file, $emoji, $callback, $fileName, $mimeType, $ttl, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $forceResend, $cancellation);
return $this->wrapper->getAPI()->sendSticker($peer, $file, $mimeType, $emoji, $stickerSet, $callback, $fileName, $ttl, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $forceResend, $cancellation);
}
/**
* Sends a video.

View File

@ -237,10 +237,11 @@ trait FilesAbstraction
public function sendSticker(
int|string $peer,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
string $mimeType,
string $emoji = '',
array $stickerSet = ['_' => 'inputStickerSetEmpty'],
?callable $callback = null,
?string $fileName = null,
?string $mimeType = null,
?int $ttl = null,
?int $replyToMsgId = null,
?int $topMsgId = null,
@ -259,10 +260,10 @@ trait FilesAbstraction
type: Sticker::class,
mimeType: $mimeType,
thumb: null,
attributesOrig: [],
attributesOrig: ['_' => 'documentAttributeSticker', 'alt' => $emoji, 'stickerset' => $stickerSet],
peer: $peer,
file: $file,
caption: $emoji,
caption: '',
parseMode: ParseMode::TEXT,
callback: $callback,
fileName: $fileName,
@ -760,6 +761,7 @@ trait FilesAbstraction
: $attributesOrig['waveform'],
],
],
Sticker::class => [$attributesOrig],
default => [],
};
if ($type === Gif::class) {
@ -791,7 +793,7 @@ trait FilesAbstraction
$width = 0;
$height = 0;
if ($type === Photo::class) {
if ($type === Photo::class || $type === Sticker::class) {
if (!\extension_loaded('gd')) {
throw Exception::extension('gd');
}
@ -799,34 +801,36 @@ trait FilesAbstraction
$img = imagecreatefromstring($file);
$width = imagesx($img);
$height = imagesy($img);
if ($width > $height) {
$thumb_width = 90;
$thumb_height = (int) (90*$height/$width);
} elseif ($width < $height) {
$thumb_width = (int) (90*$width/$height);
$thumb_height = 90;
} else {
$thumb_width = 90;
$thumb_height = 90;
}
Assert::lessThanEq($thumb_height, 90);
Assert::lessThanEq($thumb_width, 90);
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
imagecopyresized($thumb, $img, 0, 0, 0, 0, $thumb_width, $thumb_height, $width, $height);
$stream = fopen('php://memory', 'r+');
imagepng($thumb, $stream);
rewind($stream);
$thumb = stream_get_contents($stream);
fclose($stream);
unset($stream);
$file = new ReadableBuffer($file);
if ($type === Photo::class) {
if ($width > $height) {
$thumb_width = 90;
$thumb_height = (int) (90*$height/$width);
} elseif ($width < $height) {
$thumb_width = (int) (90*$width/$height);
$thumb_height = 90;
} else {
$thumb_width = 90;
$thumb_height = 90;
}
Assert::lessThanEq($thumb_height, 90);
Assert::lessThanEq($thumb_width, 90);
$thumb = imagecreatetruecolor($thumb_width, $thumb_height);
imagecopyresized($thumb, $img, 0, 0, 0, 0, $thumb_width, $thumb_height, $width, $height);
$stream = fopen('php://memory', 'r+');
imagepng($thumb, $stream);
rewind($stream);
$thumb = stream_get_contents($stream);
fclose($stream);
unset($stream);
}
} elseif ($type === Video::class || $type === Gif::class) {
$this->extractVideoInfo(true, $attributesOrig['thumbSeek'], $file, $fileName, $callback, $cancellation, $mimeType, $attributes, $thumb);
} elseif ($type === Audio::class || $type === Voice::class) {
$this->extractAudioInfo(true, $file, $fileName, $callback, $cancellation, $mimeType, $attributes, $thumb);
} elseif ($mimeType === null) {
$mimeType = $this->extractMime($file, $fileName, $callback, $cancellation);
$mimeType = $this->extractMime(true, $file, $fileName, $callback, $cancellation);
}
if ($thumb !== null && $thumb_width === 0) {
@ -904,7 +908,7 @@ trait FilesAbstraction
} elseif ($type === Audio::class || $type === Voice::class) {
$this->extractAudioInfo(false, $file, $fileName, $callback, $cancellation, $mimeType, $attributes, $thumb);
} elseif ($mimeType === null) {
$mimeType = $this->extractMime($file, $fileName, $callback, $cancellation);
$mimeType = $this->extractMime(false, $file, $fileName, $callback, $cancellation);
}
$method = 'messages.sendMedia';
@ -1002,14 +1006,11 @@ trait FilesAbstraction
return $res;
}
/**
* @return list{array, string}
*/
private function extractMime(Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file, ?string $fileName, ?callable $callback, ?Cancellation $cancellation): array
private function extractMime(bool $secret, Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream &$file, ?string $fileName, ?callable $callback, ?Cancellation $cancellation): string
{
$file = $this->getStream($file, $cancellation);
$p = new Pipe(1024*1024);
$fileFuture = async(fn () => $this->upload(new StreamDuplicator($file, $p->getSink()), $fileName ?? '', $callback, cancellation: $cancellation));
$fileFuture = async(fn () => $this->upload(new StreamDuplicator($file, $p->getSink()), $fileName ?? '', $callback, $secret, $cancellation));
$buff = '';
while (\strlen($buff) < 1024*1024 && null !== $chunk = $p->getSource()->read($cancellation)) {
@ -1019,7 +1020,8 @@ trait FilesAbstraction
$p->getSource()->close();
unset($p);
return [$fileFuture->await(), (new finfo())->buffer($buff, FILEINFO_MIME_TYPE)];
$file = $fileFuture->await();
return (new finfo())->buffer($buff, FILEINFO_MIME_TYPE);
}
private function extractAudioInfo(bool $secret, Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream &$file, ?string $fileName, ?callable $callback, ?Cancellation $cancellation, ?string &$mimeType, array &$attributes, mixed &$thumb): void
{
@ -1029,7 +1031,7 @@ trait FilesAbstraction
}
$this->logger->logger('Install ffmpeg for audio info extraction!');
if ($mimeType === null) {
[$file, $mimeType] = $this->extractMime($file, $fileName, $callback, $cancellation);
$mimeType = $this->extractMime($secret, $file, $fileName, $callback, $cancellation);
}
return;
}
@ -1102,7 +1104,7 @@ trait FilesAbstraction
}
$this->logger->logger('Install ffmpeg for video info extraction!');
if ($mimeType === null) {
[$file, $mimeType] = $this->extractMime($file, $fileName, $callback, $cancellation);
$mimeType = $this->extractMime($secret, $file, $fileName, $callback, $cancellation);
}
return;
}
@ -1143,7 +1145,9 @@ trait FilesAbstraction
$fileFuture = async(fn () => $this->upload(new StreamDuplicator($file, ...$streams), $fileName ?? '', $callback, $secret, $cancellation));
[$stdout, $stderr] = await($f);
$thumb ??= new ReadableBuffer($stdout);
if ($stdout !== '') {
$thumb ??= new ReadableBuffer($stdout);
}
$process->join($cancellation);
if (preg_match('~Duration: (\d{2}:\d{2}:\d{2}\.\d{2}),.*? (\d{3,4})x(\d{3,4})~s', $stderr, $matches)) {

View File

@ -67,7 +67,8 @@ trait AuthKeyHandler
if ($user['type'] !== 'user') {
throw new AssertionError("Can only create a secret chat with a user!");
}
$this->logger->logger('Creating secret chat with '.$user['user_id'].'...', Logger::VERBOSE);
$user = $user['user_id'];
$this->logger->logger('Creating secret chat with '.$user.'...', Logger::VERBOSE);
$dh_config = ($this->getDhConfig());
$this->logger->logger('Generating a...', Logger::VERBOSE);
$a = new BigInteger(Tools::random(256), 256);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB