From 5cfaee670c14d8616ac3cdd7dc640387f8699a84 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Sat, 29 Jun 2019 14:54:12 +0200 Subject: [PATCH] Merge --- README.md | 273 +----------------- docs | 2 +- src/danog/MadelineProto/Connection.php | 55 +--- .../MadelineProto/DocsBuilder/Methods.php | 37 ++- .../Loop/Connection/ReadLoop.php | 1 - src/danog/MadelineProto/MTProto.php | 4 +- .../MTProtoTools/AuthKeyHandler.php | 5 +- .../Stream/ConnectionContext.php | 6 + .../Stream/MTProtoTools/MsgIdHandler.php | 3 + .../Stream/MTProtoTools/SeqNoHandler.php | 5 + .../Stream/MTProtoTools/Session.php | 59 ++++ .../MTProtoTransport/ObfuscatedStream.php | 12 +- 12 files changed, 122 insertions(+), 340 deletions(-) create mode 100644 src/danog/MadelineProto/Stream/MTProtoTools/Session.php diff --git a/README.md b/README.md index 021bec54..19e362ad 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ Tip: if you receive an error (or nothing), [send us](https://t.me/pwrtelegramgro * [Full chat info with full list of participants](https://docs.madelineproto.xyz/docs/CHAT_INFO.html#get_pwr_chat-now-fully-async) * [Full chat info](https://docs.madelineproto.xyz/docs/CHAT_INFO.html#get_full_info-now-fully-async) * [Reduced chat info (very fast)](https://docs.madelineproto.xyz/docs/CHAT_INFO.html#get_info-now-fully-async) + * [Just the chat ID (extremely fast)](https://docs.madelineproto.xyz/docs/CHAT_INFO.html#get_id-now-fully-async) * [Getting all chats (dialogs)](https://docs.madelineproto.xyz/docs/DIALOGS.html) * [Dialog list](https://docs.madelineproto.xyz/docs/DIALOGS.html#get_dialogs-now-fully-async) * [Full dialog info](https://docs.madelineproto.xyz/docs/DIALOGS.html#get_full_dialogs-now-fully-async) @@ -174,278 +175,6 @@ Tip: if you receive an error (or nothing), [send us](https://t.me/pwrtelegramgro * [Upload or download files up to 1.5 GB](https://docs.madelineproto.xyz/docs/FILES.html) * [Make a phone call and play a song](https://docs.madelineproto.xyz/docs/CALLS.html) * [Create a secret chat bot](https://docs.madelineproto.xyz/docs/SECRET_CHATS.html) - * Accept URL authorization: messages.acceptUrlAuth - * Accept contact: contacts.acceptContact - * Accept telegram passport authorization: account.acceptAuthorization - * Accept telegram's TOS: help.acceptTermsOfService - * Add a sticker set: messages.installStickerSet - * Add a sticker to favorites: messages.faveSticker - * Add a sticker to recent stickers: messages.saveRecentSticker - * Add a user to a normal chat (use channels->inviteToChannel for supergroups): messages.addChatUser - * Add contact: contacts.addContact - * Add phone number as contact: contacts.importContacts - * Add sticker to stickerset: stickers.addStickerToSet - * Add users to channel/supergroup: channels.inviteToChannel - * Block a user: contacts.block - * Bots only: get telegram passport authorization form: account.getAuthorizationForm - * Bots only: send payment form: payments.sendPaymentForm - * Bots only: set precheckout results: messages.setBotPrecheckoutResults - * Bots only: set shipping results: messages.setBotShippingResults - * Bots only: set the callback answer (after a button was clicked): messages.setBotCallbackAnswer - * Bots only: set the results of an inline query: messages.setInlineBotResults - * Call inline bot: messages.getInlineBotResults - * Cancel password recovery email: account.cancelPasswordEmail - * Change notification settings: account.updateNotifySettings - * Change sticker position in photo: stickers.changeStickerPosition - * Change the phone number associated to this account: account.changePhone - * Change the phone number: account.sendChangePhoneCode - * Change the profile photo: photos.updateProfilePhoto - * Change typing status: messages.setTyping - * Check if about to edit a message or a media caption: messages.getMessageEditData - * Check if an invitation link is valid: messages.checkChatInvite - * Check if this username is available: account.checkUsername - * Check if this username is free and can be assigned to a channel/supergroup: channels.checkUsername - * Clear all drafts: messages.clearAllDrafts - * Clear all recent stickers: messages.clearRecentStickers - * Clear saved payments info: payments.clearSavedInfo - * Confirm password recovery using email: account.confirmPasswordEmail - * Confirm this phone number is associated to this account, obtain phone_code_hash from sendConfirmPhoneCode: account.confirmPhone - * Contact signup notification setting value: account.getContactSignUpNotification - * Convert chat to supergroup: messages.migrateChat - * Create a chat (not supergroup): messages.createChat - * Create channel/supergroup: channels.createChannel - * Create stickerset: stickers.createStickerSet - * Delete a certain session: account.resetAuthorization - * Delete a certain telegram web login authorization: account.resetWebAuthorization - * Delete a channel/supergroup: channels.deleteChannel - * Delete a user from a chat (not supergroup): messages.deleteChatUser - * Delete all logged-in sessions.: auth.resetAuthorizations - * Delete all messages of a user in a channel/supergroup: channels.deleteUserHistory - * Delete all temporary authorization keys except the ones provided: auth.dropTempAuthKeys - * Delete channel/supergroup messages: channels.deleteMessages - * Delete chat history: messages.deleteHistory - * Delete contacts by phones: contacts.deleteByPhones - * Delete folder: folders.deleteFolder - * Delete messages: messages.deleteMessages - * Delete multiple contacts: contacts.deleteContacts - * Delete profile photos: photos.deletePhotos - * Delete secure telegram passport value: account.deleteSecureValue - * Delete the history of a supergroup/channel: channels.deleteHistory - * Delete this account: account.deleteAccount - * Disable all notifications for a certain period: account.updateDeviceLocked - * Download a file through telegram: upload.getWebFile - * Edit a message: messages.editMessage - * Edit a sent inline message: messages.editInlineBotMessage - * Edit admin permissions of a user in a channel/supergroup: channels.editAdmin - * Edit admin permissions: messages.editChatAdmin - * Edit chat info: messages.editChatAbout - * Edit creator of channel: channels.editCreator - * Edit default rights of chat: messages.editChatDefaultBannedRights - * Edit folder: folders.editPeerFolders - * Edit location (geochats): channels.editLocation - * Edit the photo of a normal chat (not supergroup): messages.editChatPhoto - * Edit the photo of a supergroup/channel: channels.editPhoto - * Edit the title of a normal chat (not supergroup): messages.editChatTitle - * Edit the title of a supergroup/channel: channels.editTitle - * Edit user info: help.editUserInfo - * Enable or disable hidden history for new channel/supergroup users: channels.togglePreHistoryHidden - * Export chat invite : messages.exportChatInvite - * Find a sticker set: messages.searchStickerSets - * Finish account exporting session: account.finishTakeoutSession - * Forward messages: messages.forwardMessages - * Get CDN configuration: help.getCdnConfig - * Get a stickerset: messages.getStickerSet - * Get account TTL: account.getAccountTTL - * Get admin log of a channel/supergroup: channels.getAdminLog - * Get all archived stickers: messages.getArchivedStickers - * Get all channels you left: channels.getLeftChannels - * Get all chats (not supergroups or channels): messages.getAllChats - * Get all contacts: contacts.getContacts - * Get all logged-in authorizations: account.getAuthorizations - * Get all message drafts: messages.getAllDrafts - * Get all secure telegram passport values: account.getAllSecureValues - * Get all stickerpacks: messages.getAllStickers - * Get all supergroups/channels where you're admin: channels.getAdminedPublicChannels - * Get and increase message views: messages.getMessagesViews - * Get app config: help.getAppConfig - * Get autodownload settings: account.getAutoDownloadSettings - * Get available languages: langpack.getLanguages - * Get blocked users: contacts.getBlocked - * Get call configuration: phone.getCallConfig - * Get channel/supergroup messages: channels.getMessages - * Get channel/supergroup participants (you should use `$MadelineProto->get_pwr_chat($id)` instead): channels.getParticipants - * Get chats in common with a user: messages.getCommonChats - * Get contacts by IDs: contacts.getContactIDs - * Get deep link info: help.getDeepLinkInfo - * Get dialog info of peers: messages.getPeerDialogs - * Get dialogs marked as unread manually: messages.getDialogUnreadMarks - * Get document by SHA256 hash: messages.getDocumentByHash - * Get emoji URL: messages.getEmojiURL - * Get emoji keyword difference: messages.getEmojiKeywordsDifference - * Get emoji keyword languages: messages.getEmojiKeywordsLanguages - * Get emoji keywords: messages.getEmojiKeywords - * Get favorite stickers: messages.getFavedStickers - * Get featured stickers: messages.getFeaturedStickers - * Get groups for discussion: channels.getGroupsForDiscussion - * Get high scores of a game sent in an inline message: messages.getInlineGameHighScores - * Get high scores of a game: messages.getGameHighScores - * Get info about a certain channel/supergroup participant: channels.getParticipant - * Get info about app updates: help.getAppUpdate - * Get info about chats: messages.getChats - * Get info about multiple channels/supergroups: channels.getChannels - * Get info about users: users.getUsers - * Get info of support user: help.getSupport - * Get information about the current proxy: help.getProxyData - * Get invitation text: help.getInviteText - * Get language pack strings: langpack.getStrings - * Get language pack updates: langpack.getDifference - * Get language pack: langpack.getLangPack - * Get language: langpack.getLanguage - * Get masks: messages.getMaskStickers - * Get message ranges to fetch: messages.getSplitRanges - * Get messages: messages.getMessages - * Get most used chats: contacts.getTopPeers - * Get nearest datacenter: help.getNearestDc - * Get notification exceptions: account.getNotifyExceptions - * Get notification settings: account.getNotifySettings - * Get online status of all users: contacts.getStatuses - * Get online users: messages.getOnlines - * Get passport config: help.getPassportConfig - * Get payment form: payments.getPaymentForm - * Get payment receipt: payments.getPaymentReceipt - * Get people nearby (geochats): contacts.getLocated - * Get pinned dialogs: messages.getPinnedDialogs - * Get poll results: messages.getPollResults - * Get previous messages of a group: messages.getHistory - * Get privacy settings: account.getPrivacy - * Get recent locations: messages.getRecentLocations - * Get recent stickers: messages.getRecentStickers - * Get recent t.me URLs: help.getRecentMeUrls - * Get saved contacts: contacts.getSaved - * Get saved gifs: messages.getSavedGifs - * Get saved payments info: payments.getSavedInfo - * Get search counter: messages.getSearchCounters - * Get secure value for telegram passport: account.getSecureValue - * Get server configuration: help.getConfig - * Get stats URL: messages.getStatsURL - * Get stickers attachable to images: messages.getAttachedStickers - * Get stickers: messages.getStickers - * Get support name: help.getSupportName - * Get telegram web login authorizations: account.getWebAuthorizations - * Get temporary password for buying products through bots: account.getTmpPassword - * Get the callback answer of a bot (after clicking a button): messages.getBotCallbackAnswer - * Get the changelog of this app: help.getAppChangelog - * Get the current password: account.getPassword - * Get the link of a message in a channel: channels.exportMessageLink - * Get the profile photos of a user: photos.getUserPhotos - * Get the settings of apeer: messages.getPeerSettings - * Get unread mentions: messages.getUnreadMentions - * Get updated TOS: help.getTermsOfServiceUpdate - * Get user info: help.getUserInfo - * Get wallpaper info: account.getWallPaper - * Get webpage preview: messages.getWebPage - * Get webpage preview: messages.getWebPagePreview - * Gets list of chats: you should use $MadelineProto->get_dialogs() instead: https://docs.madelineproto.xyz/docs/DIALOGS.html: messages.getDialogs - * Global message search: messages.searchGlobal - * Hide peer settings bar: messages.hidePeerSettingsBar - * Import chat invite: messages.importChatInvite - * Initializes connection and save information on the user's device and application.: initConnection - * Install wallpaper: account.installWallPaper - * Invalidate sent phone code: auth.cancelCode - * Invoke method from takeout session: invokeWithTakeout - * Invoke this method with layer X: invokeWithLayer - * Invoke with messages range: invokeWithMessagesRange - * Invoke with method without returning updates in the socket: invokeWithoutUpdates - * Invokes a query after successfull completion of one of the previous queries.: invokeAfterMsg - * Join a channel/supergroup: channels.joinChannel - * Kick or ban a user from a channel/supergroup: channels.editBanned - * Leave a channel/supergroup: channels.leaveChannel - * Log data for developer of this app: help.saveAppLog - * Mark channel/supergroup history as read: channels.readHistory - * Mark channel/supergroup messages as read: channels.readMessageContents - * Mark dialog as unread : messages.markDialogUnread - * Mark mentions as read: messages.readMentions - * Mark message as read: messages.readMessageContents - * Mark messages as read in secret chats: messages.readEncryptedHistory - * Mark messages as read: messages.readHistory - * Mark messages as read: messages.receivedMessages - * Mark new featured stickers as read: messages.readFeaturedStickers - * Notify server that you received a call (server will refuse all incoming calls until the current call is over): phone.receivedCall - * Pin or unpin dialog: messages.toggleDialogPin - * Register device for push notifications: account.registerDevice - * Remove a sticker set: messages.uninstallStickerSet - * Remove sticker from stickerset: stickers.removeStickerFromSet - * Reorder pinned dialogs: messages.reorderPinnedDialogs - * Reorder sticker sets: messages.reorderStickerSets - * Report a message in a supergroup/channel for spam: channels.reportSpam - * Report a message: messages.report - * Report a peer for spam: messages.reportSpam - * Report for spam a secret chat: messages.reportEncryptedSpam - * Report for spam: account.reportPeer - * Request URL authorization: messages.requestUrlAuth - * Resend password recovery email: account.resendPasswordEmail - * Resend the SMS verification code: auth.resendCode - * Reset all notification settings: account.resetNotifySettings - * Reset all telegram web login authorizations: account.resetWebAuthorizations - * Reset saved contacts: contacts.resetSaved - * Reset top peer rating for a certain category/peer: contacts.resetTopPeerRating - * Reset wallpapers: account.resetWallPapers - * Result type returned by a current query.: invokeAfterMsgs - * Returns a list of available wallpapers.: account.getWallPapers - * Save a GIF: messages.saveGif - * Save a message draft: messages.saveDraft - * Save autodownload settings: account.saveAutoDownloadSettings - * Save call debugging info: phone.saveCallDebug - * Save telegram passport secure value: account.saveSecureValue - * Save wallpaper: account.saveWallPaper - * Search contacts: contacts.search - * Search gifs: messages.searchGifs - * Search peers or messages: messages.search - * Send a custom request to the bot API: bots.sendCustomRequest - * Send a file to a secret chat: messages.sendEncryptedFile - * Send a media: messages.sendMedia - * Send a message: messages.sendMessage - * Send a service message to a secret chat: messages.sendEncryptedService - * Send an album: messages.sendMultiMedia - * Send an email to recover the 2FA password: auth.requestPasswordRecovery - * Send confirmation phone code: account.sendConfirmPhoneCode - * Send email verification code: account.sendVerifyEmailCode - * Send inline bot result obtained with messages.getInlineBotResults to the chat: messages.sendInlineBotResult - * Send message to secret chat: messages.sendEncrypted - * Send phone verification code: account.sendVerifyPhoneCode - * Send screenshot notification: messages.sendScreenshotNotification - * Send typing notification to secret chat: messages.setEncryptedTyping - * Send vote: messages.sendVote - * Send webhook request via bot API: bots.answerWebhookJSONQuery - * Set account TTL: account.setAccountTTL - * Set contact sign up notification: account.setContactSignUpNotification - * Set discussion group of channel: channels.setDiscussionGroup - * Set phone call rating: phone.setCallRating - * Set privacy settings: account.setPrivacy - * Set secure value error for telegram passport: users.setSecureValueErrors - * Set the game score of an inline message: messages.setInlineGameScore - * Set the game score: messages.setGameScore - * Set the supergroup/channel stickerpack: channels.setStickers - * Set the update status of webhook: help.setBotUpdatesStatus - * Start a bot: messages.startBot - * Start account exporting session: account.initTakeoutSession - * Stop sending PUSH notifications to app: account.unregisterDevice - * Toggle channel signatures: channels.toggleSignatures - * Toggle top peers: contacts.toggleTopPeers - * Unblock a user: contacts.unblock - * Update online status: account.updateStatus - * Update pinned message: messages.updatePinnedMessage - * Update profile info: account.updateProfile - * Update the username of a supergroup/channel: channels.updateUsername - * Update this user's username: account.updateUsername - * Upload a file without sending it to anyone: messages.uploadMedia - * Upload a secret chat file without sending it to anyone: messages.uploadEncryptedFile - * Upload profile photo: photos.uploadProfilePhoto - * Upload wallpaper: account.uploadWallPaper - * Use the code that was emailed to you after running $MadelineProto->auth->requestPasswordRecovery to login to your account: auth.recoverPassword - * Validate requested payment info: payments.validateRequestedInfo - * Verify email address: account.verifyEmail - * Verify phone number: account.verifyPhone * [Peers](https://docs.madelineproto.xyz/docs/USING_METHODS.html#peers) * [Files](https://docs.madelineproto.xyz/docs/FILES.html) * [Secret chats](https://docs.madelineproto.xyz/docs/USING_METHODS.html#secret-chats) diff --git a/docs b/docs index cbd913fb..7414ae3e 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit cbd913fba2249a0055bb732452a67f911119c40a +Subproject commit 7414ae3e537b26a15b75d2a00ef6f93e702d2cd8 diff --git a/src/danog/MadelineProto/Connection.php b/src/danog/MadelineProto/Connection.php index 3d5a6149..9caa7706 100644 --- a/src/danog/MadelineProto/Connection.php +++ b/src/danog/MadelineProto/Connection.php @@ -20,7 +20,6 @@ namespace danog\MadelineProto; use Amp\ByteStream\ClosedException; use Amp\Deferred; -use Amp\Promise; use danog\MadelineProto\Loop\Connection\CheckLoop; use danog\MadelineProto\Loop\Connection\HttpWaitLoop; use danog\MadelineProto\Loop\Connection\ReadLoop; @@ -42,6 +41,7 @@ class Connection use Crypt; use MsgIdHandler; use SeqNoHandler; + use \danog\Serializable; use Tools; @@ -55,40 +55,23 @@ class Connection public $stream; - public $time_delta = 0; public $type = 0; public $peer_tag; + public $temp_auth_key; public $auth_key; - public $session_id; - public $session_out_seq_no = 0; - public $session_in_seq_no = 0; - public $incoming_messages = []; - public $outgoing_messages = []; - public $new_incoming = []; - public $new_outgoing = []; + + public $pending_outgoing = []; public $pending_outgoing_key = 0; - public $pending_outgoing_unencrypted = []; - public $pending_outgoing_unencrypted_key = 0; - public $max_incoming_id; - public $max_outgoing_id; + public $authorized = false; - public $call_queue = []; - public $ack_queue = []; - public $i = []; - public $last_recv = 0; - private $last_chunk = 0; - public $last_http_wait = 0; public $datacenter; public $API; - public $resumeWriterDeferred; - public $ctx; - public $pendingCheckWatcherId; - public $http_req_count = 0; - public $http_res_count = 0; + public $ctx; + public function getCtx() { @@ -277,19 +260,7 @@ class Connection { return __CLASS__; } - public function haveRead() - { - $this->last_chunk = microtime(true); - } - /** - * Get the receive date of the latest chunk of data from the socket - * - * @return void - */ - public function getLastChunk() - { - return $this->last_chunk; - } + /** * Sleep function. * @@ -301,14 +272,4 @@ class Connection { return ['peer_tag', 'temp_auth_key', 'auth_key', 'session_id', 'session_out_seq_no', 'session_in_seq_no', 'max_incoming_id', 'max_outgoing_id', 'authorized', 'ack_queue']; } - - public function __wakeup() - { - $this->time_delta = 0; - $this->pending_outgoing = []; - $this->new_outgoing = []; - $this->new_incoming = []; - $this->outgoing_messages = []; - $this->incoming_messages = []; - } } diff --git a/src/danog/MadelineProto/DocsBuilder/Methods.php b/src/danog/MadelineProto/DocsBuilder/Methods.php index 9ff06eaa..d9ae773c 100644 --- a/src/danog/MadelineProto/DocsBuilder/Methods.php +++ b/src/danog/MadelineProto/DocsBuilder/Methods.php @@ -23,9 +23,21 @@ trait Methods { public function mk_methods() { - $bots = json_decode(file_get_contents('https://rpc.pwrtelegram.xyz/?bot'), true)['result']; - $errors = json_decode(file_get_contents('https://rpc.pwrtelegram.xyz/?all'), true); - $errors['result'] = array_merge_recursive(...$errors['result']); + static $bots; + if (!$bots) $bots = json_decode(file_get_contents('https://rpc.pwrtelegram.xyz/?bot'), true)['result']; + static $errors; + if (!$errors) $errors = json_decode(file_get_contents('https://rpc.pwrtelegram.xyz/?all'), true); + $new = ['result' => []]; + foreach ($errors['result'] as $code => $suberrors) { + foreach ($suberrors as $method => $suberrors) { + if (!isset($new[$method])) { + $new[$method] = []; + } + foreach ($suberrors as $error) { + $new['result'][$method][] = [$error, $code]; + } + } + } foreach (glob('methods/'.$this->any) as $unlink) { unlink($unlink); } @@ -76,11 +88,12 @@ trait Methods $this->docs_methods[$method] = '$MadelineProto->'.$md_method.'(\\['.$params.'\\]) === [$'.str_replace('_', '\\_', $type).'](../types/'.$php_type.'.md) '; +/* if (!isset(\danog\MadelineProto\MTProto::DISALLOWED_METHODS[$data['method']]) && isset($this->td_descriptions['methods'][$data['method']])) { $this->human_docs_methods[$this->td_descriptions['methods'][$data['method']]['description'].': '.$data['method']] = '* '.$this->td_descriptions['methods'][$data['method']]['description'].': '.$data['method'].' '; - } + }*/ $params = ''; $lua_params = ''; $pwr_params = ''; @@ -192,11 +205,12 @@ image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png '; +/* if (isset(\danog\MadelineProto\MTProto::DISALLOWED_METHODS[$data['method']])) { $header .= '**'.\danog\MadelineProto\MTProto::DISALLOWED_METHODS[$data['method']]."**\n\n\n\n\n"; file_put_contents('methods/'.$method.'.md', $header); continue; - } + }*/ if ($this->td) { $header .= 'YOU CANNOT USE THIS METHOD IN MADELINEPROTO @@ -293,14 +307,15 @@ You can also use normal markdown, note that to create mentions you must use the MadelineProto supports all html entities supported by [html_entity_decode](http://php.net/manual/en/function.html-entity-decode.php). '; } - if (isset($errors['result'][$data['method']])) { - $example .= '### Errors this method can return: + if (isset($new['result'][$data['method']])) { + $example .= '### Errors -| Error | Description | -|----------|---------------| +| Code | Type | Description | +|------|----------|---------------| '; - foreach ($errors['result'][$data['method']] as $error) { - $example .= '|'.$error.'|'.$errors['human_result'][$error][0].'|'."\n"; + foreach ($new['result'][$data['method']] as $error) { + [$error, $code] = $error; + $example .= "|$code|$error|".$errors['human_result'][$error][0].'|'."\n"; } $example .= "\n\n"; } diff --git a/src/danog/MadelineProto/Loop/Connection/ReadLoop.php b/src/danog/MadelineProto/Loop/Connection/ReadLoop.php index 9d8461d5..21160737 100644 --- a/src/danog/MadelineProto/Loop/Connection/ReadLoop.php +++ b/src/danog/MadelineProto/Loop/Connection/ReadLoop.php @@ -214,7 +214,6 @@ class ReadLoop extends SignalLoop $connection->incoming_messages[$message_id]['content'] = $deserialized; $connection->incoming_messages[$message_id]['response'] = -1; $connection->new_incoming[$message_id] = $message_id; - $connection->last_recv = time(); $connection->last_http_wait = 0; $API->logger->logger('Received payload from DC '.$datacenter, \danog\MadelineProto\Logger::ULTRA_VERBOSE); diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index cce3afd8..8010e342 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -133,6 +133,7 @@ class MTProto extends AsyncConstruct implements TLCallback public $authorized = 0; public $authorized_dc = -1; private $rsa_keys = []; + private $cdn_rsa_keys = []; private $dh_config = ['version' => 0]; public $chats = []; public $channel_participants = []; @@ -180,6 +181,7 @@ class MTProto extends AsyncConstruct implements TLCallback } // Load rsa keys $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['load_rsa'], Logger::ULTRA_VERBOSE); + $this->rsa_keys = []; foreach ($this->settings['authorization']['rsa_keys'] as $key) { $key = yield (new RSA())->load($key); $this->rsa_keys[$key->fp] = $key; @@ -1016,7 +1018,7 @@ class MTProto extends AsyncConstruct implements TLCallback try { foreach ((yield $this->method_call_async_read('help.getCdnConfig', [], ['datacenter' => $datacenter]))['public_keys'] as $curkey) { $tempkey = new \danog\MadelineProto\RSA($curkey['public_key']); - $this->rsa_keys[$tempkey->fp] = $tempkey; + $this->cdn_rsa_keys[$tempkey->fp] = $tempkey; } } catch (\danog\MadelineProto\TL\Exception $e) { $this->logger->logger($e->getMessage(), \danog\MadelineProto\Logger::FATAL_ERROR); diff --git a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php index 76959f2d..23147109 100644 --- a/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/AuthKeyHandler.php @@ -35,7 +35,8 @@ trait AuthKeyHandler public function create_auth_key_async($expires_in, $datacenter): \Generator { - $req_pq = strpos($datacenter, 'cdn') ? 'req_pq' : 'req_pq_multi'; + $cdn = strpos($datacenter, 'cdn'); + $req_pq = $cdn ? 'req_pq' : 'req_pq_multi'; for ($retry_id_total = 1; $retry_id_total <= $this->settings['max_tries']['authorization']; $retry_id_total++) { try { $this->logger->logger(\danog\MadelineProto\Lang::$current_lang['req_pq'], \danog\MadelineProto\Logger::VERBOSE); @@ -69,7 +70,7 @@ trait AuthKeyHandler * *********************************************************************** * Find our key in the server_public_key_fingerprints vector */ - foreach ($this->rsa_keys as $curkey) { + foreach ($cdn ? array_merge($this->cdn_rsa_keys, $this->rsa_keys) : $this->rsa_keys as $curkey) { if (in_array($curkey->fp, $ResPQ['server_public_key_fingerprints'])) { $key = $curkey; } diff --git a/src/danog/MadelineProto/Stream/ConnectionContext.php b/src/danog/MadelineProto/Stream/ConnectionContext.php index 2ee330ec..17bc7def 100644 --- a/src/danog/MadelineProto/Stream/ConnectionContext.php +++ b/src/danog/MadelineProto/Stream/ConnectionContext.php @@ -23,6 +23,7 @@ use Amp\Socket\ClientConnectContext; use Amp\Uri\Uri; use danog\MadelineProto\Stream\Transport\DefaultStream; use danog\MadelineProto\Stream\MTProtoTransport\ObfuscatedStream; +use danog\MadelineProto\Exception; /** * Connection context class. @@ -218,6 +219,7 @@ class ConnectionContext { return $this->isDns; } + /** * Whether this connection context will only be used by the DNS client * @@ -262,6 +264,10 @@ class ConnectionContext */ public function setDc($dc): self { + $int = intval($dc); + if (!(1 <= $int && $int <= 1000)) { + throw new Exception("Invalid DC id provided: $dc"); + } $this->dc = $dc; return $this; diff --git a/src/danog/MadelineProto/Stream/MTProtoTools/MsgIdHandler.php b/src/danog/MadelineProto/Stream/MTProtoTools/MsgIdHandler.php index ffc3e4eb..543663ab 100644 --- a/src/danog/MadelineProto/Stream/MTProtoTools/MsgIdHandler.php +++ b/src/danog/MadelineProto/Stream/MTProtoTools/MsgIdHandler.php @@ -24,6 +24,9 @@ namespace danog\MadelineProto\Stream\MTProtoTools; */ trait MsgIdHandler { + public $max_incoming_id; + public $max_outgoing_id; + public function check_message_id($new_message_id, $aargs) { if (!is_object($new_message_id)) { diff --git a/src/danog/MadelineProto/Stream/MTProtoTools/SeqNoHandler.php b/src/danog/MadelineProto/Stream/MTProtoTools/SeqNoHandler.php index 11206963..c0128b82 100644 --- a/src/danog/MadelineProto/Stream/MTProtoTools/SeqNoHandler.php +++ b/src/danog/MadelineProto/Stream/MTProtoTools/SeqNoHandler.php @@ -26,6 +26,11 @@ trait SeqNoHandler { use \danog\MadelineProto\MTProtoTools\SeqNoHandler; + public $session_out_seq_no = 0; + public $session_in_seq_no = 0; + + public $session_id; + public function generate_out_seq_no($content_related) { $in = $content_related ? 1 : 0; diff --git a/src/danog/MadelineProto/Stream/MTProtoTools/Session.php b/src/danog/MadelineProto/Stream/MTProtoTools/Session.php new file mode 100644 index 00000000..09308aae --- /dev/null +++ b/src/danog/MadelineProto/Stream/MTProtoTools/Session.php @@ -0,0 +1,59 @@ +. + * + * @author Daniil Gentili + * @copyright 2016-2019 Daniil Gentili + * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3 + * + * @link https://docs.madelineproto.xyz MadelineProto documentation + */ + +namespace danog\MadelineProto\Stream\MTProtoTools; + +/** + * Manages MTProto session-specific data + */ +class Session +{ + use MsgIdHandler; + use SaltHandler; + use SeqNoHandler; + public $incoming_messages = []; + public $outgoing_messages = []; + public $new_incoming = []; + public $new_outgoing = []; + + public $http_req_count = 0; + public $http_res_count = 0; + + public $last_http_wait = 0; + private $last_chunk = 0; + + public $time_delta = 0; + + public $call_queue = []; + public $ack_queue = []; + + + public function haveRead() + { + $this->last_chunk = microtime(true); + } + /** + * Get the receive date of the latest chunk of data from the socket + * + * @return void + */ + public function getLastChunk() + { + return $this->last_chunk; + } +} \ No newline at end of file diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php index 2aa2759d..63dbfd4a 100644 --- a/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php +++ b/src/danog/MadelineProto/Stream/MTProtoTransport/ObfuscatedStream.php @@ -186,11 +186,13 @@ class ObfuscatedStream implements BufferedProxyStreamInterface */ public function setExtra($extra) { - if (isset($extra['secret']) && strlen($extra['secret']) > 17) { - $extra['secret'] = hex2bin($extra['secret']); - } - if (isset($extra['secret']) && strlen($extra['secret']) == 17) { - $extra['secret'] = substr($extra['secret'], 0, 16); + if (isset($extra['secret'])) { + if (strlen($extra['secret']) > 17) { + $extra['secret'] = hex2bin($extra['secret']); + } + if (strlen($extra['secret']) == 17) { + $extra['secret'] = substr($extra['secret'], 1, 16); + } } $this->extra = $extra; }