mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-27 08:34:41 +01:00
Update to layer 120
This commit is contained in:
parent
ad8ff52e5f
commit
dddf7f110f
@ -319,7 +319,7 @@ class AnnotationsBuilder
|
||||
if ($hasReturnValue && $async && \preg_match("/@return (.*)/", $phpdoc, $matches)) {
|
||||
$ret = $matches[1];
|
||||
$new = $ret;
|
||||
if ($type && !str_contains($ret, '<')) {
|
||||
if ($type && !\str_contains($ret, '<')) {
|
||||
$new = '';
|
||||
if ($type->allowsNull()) {
|
||||
$new .= '?';
|
||||
@ -330,7 +330,7 @@ class AnnotationsBuilder
|
||||
$new .= $type->getName() === 'self' ? $this->reflectionClasses['API'] : $type->getName();
|
||||
}
|
||||
$phpdoc = \str_replace("@return ".$ret, "@return mixed", $phpdoc);
|
||||
if (!str_contains($phpdoc, '@psalm-return')) {
|
||||
if (!\str_contains($phpdoc, '@psalm-return')) {
|
||||
$phpdoc = \str_replace("@return ", "@psalm-return $new|$promise<$new>\n * @return ", $phpdoc);
|
||||
}
|
||||
}
|
||||
|
@ -1393,7 +1393,7 @@ interface messages
|
||||
* Parameters:
|
||||
* * `InputPeer` **peer** - User or chat, histories with which are searched, or [(inputPeerEmpty)](https://docs.madelineproto.xyz/API_docs/constructors/inputPeerEmpty.html) constructor for global search
|
||||
* * `string` **q** - Text search request
|
||||
* * `InputUser` **from_id** - Optional: Only return messages sent by the specified user ID
|
||||
* * `InputPeer` **from_id** - Optional:
|
||||
* * `int` **top_msg_id** - Optional:
|
||||
* * `MessagesFilter` **filter** - Filter to return only specified message types
|
||||
* * `int` **min_date** - If a positive value was transferred, only messages with a sending date bigger than the transferred one will be returned
|
||||
@ -2675,9 +2675,11 @@ interface messages
|
||||
* Pin a message.
|
||||
*
|
||||
* Parameters:
|
||||
* * `boolean` **silent** - Optional: Pin the message silently, without triggering a notification
|
||||
* * `InputPeer` **peer** - The peer where to pin the message
|
||||
* * `int` **id** - The message to pin, can be 0 to unpin any currently pinned messages
|
||||
* * `boolean` **silent** - Optional: Pin the message silently, without triggering a notification
|
||||
* * `boolean` **unpin** - Optional:
|
||||
* * `boolean` **pm_oneside** - Optional:
|
||||
* * `InputPeer` **peer** - The peer where to pin the message
|
||||
* * `int` **id** - The message to pin, can be 0 to unpin any currently pinned messages
|
||||
*
|
||||
* @param array $params Parameters
|
||||
*
|
||||
@ -3049,6 +3051,18 @@ interface messages
|
||||
* @return bool
|
||||
*/
|
||||
public function readDiscussion($params);
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Parameters:
|
||||
* * `InputPeer` **peer** -.
|
||||
*
|
||||
* @param array $params Parameters
|
||||
*
|
||||
* @return messages.AffectedHistory
|
||||
*/
|
||||
public function unpinAllMessages($params);
|
||||
}
|
||||
|
||||
interface updates
|
||||
|
@ -255,7 +255,7 @@ class Logger
|
||||
if (!\file_exists(\pathinfo($this->optional, PATHINFO_DIRNAME))) {
|
||||
$this->optional = Magic::$script_cwd.'/MadelineProto.log';
|
||||
}
|
||||
if (!str_ends_with($this->optional, '.log')) {
|
||||
if (!\str_ends_with($this->optional, '.log')) {
|
||||
$this->optional .= '.log';
|
||||
}
|
||||
if ($maxSize !== -1 && \file_exists($this->optional) && \filesize($this->optional) > $maxSize) {
|
||||
|
@ -12,7 +12,7 @@ class TLSchema extends SettingsAbstract
|
||||
/**
|
||||
* TL layer version.
|
||||
*/
|
||||
protected int $layer = 119;
|
||||
protected int $layer = 120;
|
||||
/**
|
||||
* MTProto schema path.
|
||||
*/
|
||||
@ -20,7 +20,7 @@ class TLSchema extends SettingsAbstract
|
||||
/**
|
||||
* API schema path.
|
||||
*/
|
||||
protected string $APISchema = __DIR__.'/../TL_telegram_v119.tl';
|
||||
protected string $APISchema = __DIR__.'/../TL_telegram_v120.tl';
|
||||
/**
|
||||
* Secret schema path.
|
||||
*/
|
||||
@ -57,7 +57,7 @@ class TLSchema extends SettingsAbstract
|
||||
public function __wakeup()
|
||||
{
|
||||
if (!\file_exists($this->APISchema) // Scheme was upgraded
|
||||
|| $this->APISchema !== __DIR__.'/../TL_telegram_v119.tl' // Session path has changed
|
||||
|| $this->APISchema !== __DIR__.'/../TL_telegram_v120.tl' // Session path has changed
|
||||
) {
|
||||
$new = new self;
|
||||
$this->setAPISchema($new->getAPISchema());
|
||||
|
@ -23,9 +23,7 @@ use Amp\ByteStream\ClosedException;
|
||||
use Amp\File\File;
|
||||
use Amp\Promise;
|
||||
use Amp\Socket\Socket;
|
||||
use Amp\Success;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Stream\Async\RawStream;
|
||||
use danog\MadelineProto\Stream\BufferedStreamInterface;
|
||||
use danog\MadelineProto\Stream\BufferInterface;
|
||||
use danog\MadelineProto\Stream\ConnectionContext;
|
||||
@ -43,7 +41,7 @@ class FileBufferedStream implements BufferedStreamInterface, BufferInterface, Pr
|
||||
private int $append_after;
|
||||
private string $append;
|
||||
/**
|
||||
* Connect
|
||||
* Connect.
|
||||
*
|
||||
* @param ConnectionContext $ctx
|
||||
* @param string $header
|
||||
@ -169,7 +167,7 @@ class FileBufferedStream implements BufferedStreamInterface, BufferInterface, Pr
|
||||
return $this->write($data);
|
||||
}
|
||||
/**
|
||||
* Set file handle
|
||||
* Set file handle.
|
||||
*
|
||||
* @param File $extra
|
||||
* @return void
|
||||
@ -192,7 +190,7 @@ class FileBufferedStream implements BufferedStreamInterface, BufferInterface, Pr
|
||||
*/
|
||||
public function getSocket(): Socket
|
||||
{
|
||||
throw new \RuntimeException("Can't get underlying socket, is a File handle!");
|
||||
throw new \RuntimeException("Can't get underlying socket, is a File handle!");
|
||||
}
|
||||
/**
|
||||
* Get class name.
|
||||
@ -203,4 +201,4 @@ class FileBufferedStream implements BufferedStreamInterface, BufferInterface, Pr
|
||||
{
|
||||
return __CLASS__;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,13 +58,15 @@ class Ogg
|
||||
*/
|
||||
private Emitter $emitter;
|
||||
|
||||
private function __construct() {}
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param BufferedStreamInterface $stream The stream
|
||||
* @param int $frameDuration Required frame duration, microseconds
|
||||
*
|
||||
*
|
||||
* @return \Generator
|
||||
* @psalm-return \Generator<mixed, mixed, mixed, self>
|
||||
*/
|
||||
@ -145,7 +147,7 @@ class Ogg
|
||||
} else {
|
||||
$frameDuration = 2**($conf % 4) * 2500;
|
||||
}
|
||||
|
||||
|
||||
$paddingLen = 0;
|
||||
if ($c === 0) {
|
||||
// Exactly 1 frame
|
||||
@ -201,7 +203,7 @@ class Ogg
|
||||
$totalDuration = \count($sizes) * $frameDuration;
|
||||
if (!$selfDelimited && $totalDuration + $this->currentDuration <= $this->frameDuration) {
|
||||
$this->currentDuration += $totalDuration;
|
||||
$sum = array_sum($sizes);
|
||||
$sum = \array_sum($sizes);
|
||||
$this->opusPayload .= \substr($content, $preOffset, ($offset - $preOffset) + $sum + $paddingLen);
|
||||
if ($this->currentDuration === $this->frameDuration) {
|
||||
yield $this->emitter->emit($this->opusPayload);
|
||||
@ -214,8 +216,8 @@ class Ogg
|
||||
}
|
||||
|
||||
foreach ($sizes as $size) {
|
||||
$this->opusPayload .= chr($toc & ~3);
|
||||
$this->opusPayload .= substr($content, $offset, $size);
|
||||
$this->opusPayload .= \chr($toc & ~3);
|
||||
$this->opusPayload .= \substr($content, $offset, $size);
|
||||
$offset += $size;
|
||||
$this->currentDuration += $frameDuration;
|
||||
if ($this->currentDuration >= $this->frameDuration) {
|
||||
|
@ -200,7 +200,7 @@ trait TD
|
||||
if ($key === '_') {
|
||||
$newparams['ID'] = \ucfirst($value);
|
||||
} else {
|
||||
if (!\is_numeric($key) && !str_ends_with($key, '_')) {
|
||||
if (!\is_numeric($key) && !\str_ends_with($key, '_')) {
|
||||
$key = $key.'_';
|
||||
}
|
||||
$newparams[$key] = $this->tdToTdcli($value);
|
||||
|
@ -69,7 +69,7 @@ inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = In
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
|
||||
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
|
||||
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
||||
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
|
||||
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
|
||||
|
||||
@ -78,7 +78,7 @@ inputChatUploadedPhoto#c642724e flags:# file:flags.0?InputFile video:flags.1?Inp
|
||||
inputChatPhoto#8953ad37 id:InputPhoto = InputChatPhoto;
|
||||
|
||||
inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
|
||||
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
|
||||
inputGeoPoint#48222faf flags:# lat:double long:double accuracy_radius:flags.0?int = InputGeoPoint;
|
||||
|
||||
inputPhotoEmpty#1cd7bf0d = InputPhoto;
|
||||
inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto;
|
||||
@ -141,7 +141,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#d20b9f3c flags:# has_video:flags.0?true photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#58ae39c9 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
|
||||
message#58ae39c9 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
|
||||
messageService#286fa604 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -154,7 +154,7 @@ messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
||||
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
|
||||
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
|
||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
||||
|
||||
@ -181,6 +181,7 @@ messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
|
||||
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
|
||||
messageActionContactSignUp#f3f25f76 = MessageAction;
|
||||
messageActionGeoProximityReached#98e0d697 from_id:Peer to_id:Peer distance:int = MessageAction;
|
||||
|
||||
dialog#2c171f72 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
@ -195,7 +196,7 @@ photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
|
||||
photoSizeProgressive#5aa86a51 type:string location:FileLocation w:int h:int sizes:Vector<int> = PhotoSize;
|
||||
|
||||
geoPointEmpty#1117dd5f = GeoPoint;
|
||||
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
|
||||
geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radius:flags.0?int = GeoPoint;
|
||||
|
||||
auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
|
||||
|
||||
@ -247,8 +248,8 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
|
||||
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
|
||||
|
||||
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#c8edce1e flags:# inexact:flags.1?true count:int next_rate:flags.0?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#64479808 flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesNotModified#74535f21 count:int = messages.Messages;
|
||||
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
@ -274,6 +275,7 @@ inputMessagesFilterRoundVideo#b549da53 = MessagesFilter;
|
||||
inputMessagesFilterMyMentions#c1f8e69a = MessagesFilter;
|
||||
inputMessagesFilterGeo#e7026d0d = MessagesFilter;
|
||||
inputMessagesFilterContacts#e062db83 = MessagesFilter;
|
||||
inputMessagesFilterPinned#1bb00451 = MessagesFilter;
|
||||
|
||||
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||
@ -313,7 +315,6 @@ updateSavedGifs#9375341e = Update;
|
||||
updateBotInlineQuery#54826690 flags:# query_id:long user_id:int query:string geo:flags.0?GeoPoint offset:string = Update;
|
||||
updateBotInlineSend#e48f964 flags:# user_id:int query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update;
|
||||
updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update;
|
||||
updateChannelPinnedMessage#98592475 channel_id:int id:int = Update;
|
||||
updateBotCallbackQuery#e73547e1 flags:# query_id:long user_id:int peer:Peer msg_id:int chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
||||
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
|
||||
updateInlineBotCallbackQuery#f9d27a5a flags:# query_id:long user_id:int msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
|
||||
@ -338,8 +339,6 @@ updateChannelReadMessagesContents#89893b45 channel_id:int messages:Vector<int> =
|
||||
updateContactsReset#7084a7be = Update;
|
||||
updateChannelAvailableMessages#70db6837 channel_id:int available_min_id:int = Update;
|
||||
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
||||
updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
|
||||
updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update;
|
||||
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
||||
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
||||
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
|
||||
@ -361,6 +360,8 @@ updateReadChannelDiscussionInbox#1cc7de54 flags:# channel_id:int top_msg_id:int
|
||||
updateReadChannelDiscussionOutbox#4638a26c channel_id:int top_msg_id:int read_max_id:int = Update;
|
||||
updatePeerBlocked#246a4b22 peer_id:Peer blocked:Bool = Update;
|
||||
updateChannelUserTyping#ff2abe9f flags:# channel_id:int top_msg_id:flags.0?int user_id:int action:SendMessageAction = Update;
|
||||
updatePinnedMessages#ed85eab5 flags:# pinned:flags.0?true peer:Peer messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updatePinnedChannelMessages#8588878b flags:# pinned:flags.0?true channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -607,6 +608,7 @@ channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelPar
|
||||
channelParticipantCreator#447dca4b flags:# user_id:int admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant;
|
||||
channelParticipantAdmin#ccbebbaf flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant;
|
||||
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
|
||||
channelParticipantLeft#c3c6796b user_id:int = ChannelParticipant;
|
||||
|
||||
channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
|
||||
channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
|
||||
@ -615,6 +617,7 @@ channelParticipantsBots#b0d1865b = ChannelParticipantsFilter;
|
||||
channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsMentions#e04b5ceb flags:# q:flags.0?string top_msg_id:flags.1?int = ChannelParticipantsFilter;
|
||||
|
||||
channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
|
||||
channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
|
||||
@ -628,7 +631,7 @@ messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
|
||||
|
||||
inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaGeo#c1b15d65 flags:# geo_point:InputGeoPoint period:int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaGeo#96929a85 flags:# geo_point:InputGeoPoint heading:flags.0?int period:flags.1?int proximity_notification_radius:flags.3?int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaVenue#417bbf11 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaContact#a6edbffd flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
@ -640,7 +643,7 @@ inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:Input
|
||||
|
||||
botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaGeo#51846fd flags:# geo:GeoPoint heading:flags.0?int period:flags.1?int proximity_notification_radius:flags.3?int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaContact#18d1cdc2 flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
|
||||
@ -1164,8 +1167,6 @@ messageViews#455b853d flags:# views:flags.0?int forwards:flags.1?int replies:fla
|
||||
|
||||
messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> users:Vector<User> = messages.MessageViews;
|
||||
|
||||
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
|
||||
|
||||
messages.discussionMessage#f5dd8f9d flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||
|
||||
messageReplyHeader#a6d57763 flags:# reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
|
||||
@ -1174,6 +1175,8 @@ messageReplies#4128faac flags:# comments:flags.0?true replies:int replies_pts:in
|
||||
|
||||
peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
|
||||
|
||||
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -1299,7 +1302,7 @@ contacts.blockFromReplies#29a8962c flags:# delete_message:flags.0?true delete_hi
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#4e17810b flags:# peer:InputPeer q:string from_id:flags.0?InputUser top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#c352eec flags:# peer:InputPeer q:string from_id:flags.0?InputPeer top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
@ -1393,7 +1396,7 @@ messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
|
||||
messages.clearAllDrafts#7e58ee9c = Bool;
|
||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true peer:InputPeer id:int = Updates;
|
||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
|
||||
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
||||
messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
|
||||
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
||||
@ -1422,6 +1425,7 @@ messages.getOldFeaturedStickers#5fe7025b offset:int limit:int hash:int = message
|
||||
messages.getReplies#24b581ba peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
|
||||
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
|
||||
messages.unpinAllMessages#f025bc8b peer:InputPeer = messages.AffectedHistory;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@ -1543,4 +1547,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
|
||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||
|
||||
// LAYER 119
|
||||
// LAYER 120
|
@ -19,7 +19,6 @@ use danog\MadelineProto\Stream\ConnectionContext;
|
||||
use danog\MadelineProto\Stream\Ogg\Ogg;
|
||||
use danog\MadelineProto\VoIP\Endpoint;
|
||||
|
||||
use function Amp\delay;
|
||||
use function Amp\File\open;
|
||||
|
||||
if (\extension_loaded('php-libtgvoip')) {
|
||||
@ -270,10 +269,10 @@ class VoIP
|
||||
$frames []= $it->getCurrent();
|
||||
}
|
||||
foreach ($frames as $frame) {
|
||||
$t = (microtime(true) / 1000) + 60;
|
||||
$t = (\microtime(true) / 1000) + 60;
|
||||
yield $this->send_message(['_' => self::PKT_STREAM_DATA, 'stream_id' => 0, 'data' => $frame, 'timestamp' => $timestamp], $datacenter);
|
||||
|
||||
yield new Delayed((int) ($t - (microtime(true) / 1000)));
|
||||
yield new Delayed((int) ($t - (\microtime(true) / 1000)));
|
||||
|
||||
$timestamp += 60;
|
||||
}
|
||||
|
167
src/danog/MadelineProto/VoIP/Endpoint.php
Normal file
167
src/danog/MadelineProto/VoIP/Endpoint.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace danog\MadelineProto\VoIP;
|
||||
|
||||
use Amp\Promise;
|
||||
use Amp\Socket\EncryptableSocket;
|
||||
use danog\MadelineProto\MTProto\PermAuthKey;
|
||||
use danog\MadelineProto\MTProtoTools\Crypt;
|
||||
use danog\MadelineProto\VoIP;
|
||||
|
||||
use function Amp\Socket\connect;
|
||||
|
||||
class Endpoint
|
||||
{
|
||||
/**
|
||||
* IP address.
|
||||
*/
|
||||
private string $ip;
|
||||
/**
|
||||
* Port.
|
||||
*/
|
||||
private int $port;
|
||||
/**
|
||||
* Peer tag.
|
||||
*/
|
||||
private string $peerTag;
|
||||
|
||||
/**
|
||||
* Whether we're a reflector.
|
||||
*/
|
||||
private bool $reflector;
|
||||
|
||||
/**
|
||||
* Call instance.
|
||||
*/
|
||||
private VoIP $instance;
|
||||
/**
|
||||
* The socket.
|
||||
*/
|
||||
private EncryptableSocket $socket;
|
||||
|
||||
/**
|
||||
* Whether we're the creator.
|
||||
*/
|
||||
private bool $creator;
|
||||
|
||||
/**
|
||||
* The auth key.
|
||||
*/
|
||||
private PermAuthKey $authKey;
|
||||
|
||||
/**
|
||||
* Create endpoint.
|
||||
*
|
||||
* @param string $ip
|
||||
* @param integer $port
|
||||
* @param string $peerTag
|
||||
* @param VoIP $instance
|
||||
*/
|
||||
public function __construct(string $ip, int $port, string $peerTag, bool $reflector, VoIP $instance)
|
||||
{
|
||||
$this->ip = $ip;
|
||||
$this->port = $port;
|
||||
$this->peerTag = $peerTag;
|
||||
$this->reflector = $reflector;
|
||||
$this->instance = $instance;
|
||||
$this->creator = $instance->isCreator();
|
||||
$this->authKey = $instance->getAuthKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to endpoint.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function connect(): \Generator
|
||||
{
|
||||
$this->socket = yield connect("udp://{$this->ip}:{$this->port}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read packet.
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function read(): \Generator
|
||||
{
|
||||
do {
|
||||
$packet = yield $this->socket->read();
|
||||
if ($packet === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = \fopen('php://memory', 'rw+b');
|
||||
\fwrite($payload, $packet);
|
||||
\fseek($payload, 0);
|
||||
|
||||
$hasPeerTag = false;
|
||||
if ($this->instance->getPeerVersion() < 9 || $this->reflector) {
|
||||
$hasPeerTag = true;
|
||||
if (\stream_get_contents($payload, 16) !== $this->peerTag) {
|
||||
\danog\MadelineProto\Logger::log("Received packet has wrong peer tag", \danog\MadelineProto\Logger::ERROR);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (\stream_get_contents($payload, 12) === "\0\0\0\0\0\0\0\0\0\0\0\0") {
|
||||
$payload = \stream_get_contents($payload);
|
||||
} else {
|
||||
\fseek($payload, $hasPeerTag ? 16 : 0);
|
||||
$message_key = \stream_get_contents($payload, 16);
|
||||
[$aes_key, $aes_iv] = Crypt::aesCalculate($message_key, $this->authKey->getAuthKey(), !$this->creator);
|
||||
$encrypted_data = \stream_get_contents($payload);
|
||||
$packet = Crypt::igeDecrypt($encrypted_data, $aes_key, $aes_iv);
|
||||
|
||||
if ($message_key != \substr(\hash('sha256', \substr($this->authKey->getAuthKey(), 88 + ($this->creator ? 8 : 0), 32).$packet, true), 8, 16)) {
|
||||
\danog\MadelineProto\Logger::log("msg_key mismatch!", \danog\MadelineProto\Logger::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
$innerLen = \unpack('v', \substr($packet, 0, 2))[1];
|
||||
if ($innerLen > \strlen($packet)) {
|
||||
\danog\MadelineProto\Logger::log("Received packet has wrong inner length!", \danog\MadelineProto\Logger::ERROR);
|
||||
return false;
|
||||
}
|
||||
$packet = \substr($packet, 2);
|
||||
}
|
||||
$stream = \fopen('php://memory', 'rw+b');
|
||||
\fwrite($stream, $packet);
|
||||
\fseek($stream, 0);
|
||||
|
||||
return $stream;
|
||||
} while (true);
|
||||
}
|
||||
/**
|
||||
* Write data.
|
||||
*
|
||||
* @param string $payload
|
||||
* @return Promise
|
||||
*/
|
||||
public function write(string $payload): Promise
|
||||
{
|
||||
$plaintext = \pack('v', \strlen($payload)).$payload;
|
||||
$padding = 16 - (\strlen($plaintext) % 16);
|
||||
if ($padding < 16) {
|
||||
$padding += 16;
|
||||
}
|
||||
$plaintext .= \danog\MadelineProto\Tools::random($padding);
|
||||
$message_key = \substr(\hash('sha256', \substr($this->authKey->getAuthKey(), 88 + ($this->creator ? 0 : 8), 32).$plaintext, true), 8, 16);
|
||||
list($aes_key, $aes_iv) = Crypt::aesCalculate($message_key, $this->authKey->getAuthKey(), $this->creator);
|
||||
$payload = $message_key.Crypt::igeEncrypt($plaintext, $aes_key, $aes_iv);
|
||||
|
||||
if ($this->instance->getPeerVersion() < 9 || $this->reflector) {
|
||||
$payload = $this->peerTag.$payload;
|
||||
}
|
||||
|
||||
return $this->socket->write($payload);
|
||||
}
|
||||
/**
|
||||
* Get peer tag.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPeerTag(): string
|
||||
{
|
||||
return $this->peerTag;
|
||||
}
|
||||
}
|
@ -80,7 +80,7 @@ trait MessageHandler
|
||||
foreach ($args['audio_streams'] as $codec) {
|
||||
$message .= $codec;
|
||||
}
|
||||
$message .= chr(0);
|
||||
$message .= \chr(0);
|
||||
$message .= \chr(\count($args['video_streams']));
|
||||
foreach ($args['video_streams'] as $codec) {
|
||||
$message .= \chr($codec);
|
||||
|
Loading…
Reference in New Issue
Block a user