. * * @author Daniil Gentili * @copyright 2016-2020 Daniil Gentili * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3 * * @link https://docs.madelineproto.xyz MadelineProto documentation */ namespace danog\MadelineProto\SecretChats; /** * Manages responses. */ trait ResponseHandler { private function handleDecryptedUpdate(array $update): \Generator { $chatId = $update['message']['chat_id']; $decryptedMessage = $update['message']['decrypted_message']; if ($decryptedMessage['_'] === 'decryptedMessage') { yield from $this->saveUpdate($update); return; } if ($decryptedMessage['_'] === 'decryptedMessageService') { $action = $decryptedMessage['action']; switch ($action['_']) { case 'decryptedMessageActionRequestKey': yield from $this->acceptRekey($chatId, $action); return; case 'decryptedMessageActionAcceptKey': yield from $this->commitRekey($chatId, $action); return; case 'decryptedMessageActionCommitKey': yield from $this->completeRekey($chatId, $action); return; case 'decryptedMessageActionNotifyLayer': $this->secret_chats[$chatId]['layer'] = $action['layer']; if ($action['layer'] >= 17 && \time() - $this->secret_chats[$chatId]['created'] > 15) { yield from $this->notifyLayer($chatId); } if ($action['layer'] >= 73) { $this->secret_chats[$chatId]['mtproto'] = 2; } return; case 'decryptedMessageActionSetMessageTTL': $this->secret_chats[$chatId]['ttl'] = $action['ttl_seconds']; yield from $this->saveUpdate($update); return; case 'decryptedMessageActionNoop': return; case 'decryptedMessageActionResend': $action['start_seq_no'] -= $this->secret_chats[$chatId]['out_seq_no_x']; $action['end_seq_no'] -= $this->secret_chats[$chatId]['out_seq_no_x']; $action['start_seq_no'] /= 2; $action['end_seq_no'] /= 2; $this->logger->logger('Resending messages for secret chat '.$chatId, \danog\MadelineProto\Logger::WARNING); foreach ($this->secret_chats[$chatId]['outgoing'] as $seq => $message) { if ($seq >= $action['start_seq_no'] && $seq <= $action['end_seq_no']) { yield from $this->methodCallAsyncRead('messages.sendEncrypted', ['peer' => $chatId, 'message' => $message]); } } return; default: yield from $this->saveUpdate($update); } return; } if ($decryptedMessage['_'] === 'decryptedMessageLayer') { if ((yield from $this->checkSecretOutSeqNo($chatId, $decryptedMessage['out_seq_no'])) && (yield from $this->checkSecretInSeqNo($chatId, $decryptedMessage['in_seq_no']))) { $this->secret_chats[$chatId]['in_seq_no']++; if ($decryptedMessage['layer'] >= 17) { $this->secret_chats[$chatId]['layer'] = $decryptedMessage['layer']; if ($decryptedMessage['layer'] >= 17 && \time() - $this->secret_chats[$chatId]['created'] > 15) { yield from $this->notifyLayer($chatId); } } $update['message']['decrypted_message'] = $decryptedMessage['message']; yield from $this->handleDecryptedUpdate($update); } return; } throw new \danog\MadelineProto\ResponseException('Unrecognized decrypted message received: '.\var_export($update, true)); } }