1
0
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:
Daniil Gentili 2020-11-14 18:48:00 +01:00
parent ad8ff52e5f
commit dddf7f110f
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 228 additions and 44 deletions

View File

@ -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);
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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());

View File

@ -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__;
}
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View 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;
}
}

View File

@ -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);