diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f0e112b7..1bf0f9fb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -482,6 +482,7 @@ set(TDLIB_SOURCE td/telegram/Document.h td/telegram/DocumentsManager.h td/telegram/DraftMessage.h + td/telegram/EncryptedFile.h td/telegram/FileReferenceManager.h td/telegram/files/FileBitmask.h td/telegram/files/FileData.h diff --git a/td/telegram/DocumentsManager.h b/td/telegram/DocumentsManager.h index 126091da9..f05b0f918 100644 --- a/td/telegram/DocumentsManager.h +++ b/td/telegram/DocumentsManager.h @@ -12,6 +12,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/Document.h" +#include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" #include "td/telegram/Photo.h" #include "td/telegram/SecretInputMedia.h" @@ -35,7 +36,7 @@ class DocumentsManager { public: tl_object_ptr document; // or - tl_object_ptr secret_file; + unique_ptr secret_file; tl_object_ptr secret_document; // or tl_object_ptr web_document; @@ -62,7 +63,7 @@ class DocumentsManager { , attributes(std::move(attributes)) { } - RemoteDocument(tl_object_ptr &&secret_file, + RemoteDocument(unique_ptr &&secret_file, tl_object_ptr &&secret_document, vector> &&attributes) : document(nullptr) diff --git a/td/telegram/EncryptedFile.h b/td/telegram/EncryptedFile.h new file mode 100644 index 000000000..dda1cf4e9 --- /dev/null +++ b/td/telegram/EncryptedFile.h @@ -0,0 +1,73 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/format.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +struct EncryptedFile { + static constexpr int32 MAGIC = 0x473d738a; + int64 id_ = 0; + int64 access_hash_ = 0; + int32 size_ = 0; + int32 dc_id_ = 0; + int32 key_fingerprint_ = 0; + + EncryptedFile() = default; + EncryptedFile(int64 id, int64 access_hash, int32 size, int32 dc_id, int32 key_fingerprint) + : id_(id), access_hash_(access_hash), size_(size), dc_id_(dc_id), key_fingerprint_(key_fingerprint) { + } + + static unique_ptr get_encrypted_file(tl_object_ptr file_ptr) { + if (file_ptr == nullptr || file_ptr->get_id() != telegram_api::encryptedFile::ID) { + return nullptr; + } + auto file = move_tl_object_as(file_ptr); + return make_unique(file->id_, file->access_hash_, file->size_, file->dc_id_, file->key_fingerprint_); + } + + template + void store(StorerT &storer) const { + using td::store; + store(MAGIC, storer); + store(id_, storer); + store(access_hash_, storer); + store(size_, storer); + store(dc_id_, storer); + store(key_fingerprint_, storer); + } + + template + void parse(ParserT &parser) { + using td::parse; + int32 got_magic; + + parse(got_magic, parser); + parse(id_, parser); + parse(access_hash_, parser); + parse(size_, parser); + parse(dc_id_, parser); + parse(key_fingerprint_, parser); + + if (got_magic != MAGIC) { + parser.set_error("EncryptedFile magic mismatch"); + } + } +}; + +inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedFile &file) { + return sb << "[" << tag("id", file.id_) << tag("access_hash", file.access_hash_) << tag("size", file.size_) + << tag("dc_id", file.dc_id_) << tag("key_fingerprint", file.key_fingerprint_) << "]"; +} + +} // namespace td \ No newline at end of file diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index f7afbe29a..3165a7ba5 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -3789,7 +3789,7 @@ static unique_ptr get_document_message_content(Td *td, tl_object } unique_ptr get_secret_message_content( - Td *td, string message_text, tl_object_ptr file, + Td *td, string message_text, unique_ptr file, tl_object_ptr &&media, vector> &&secret_entities, DialogId owner_dialog_id, MultiPromiseActor &load_data_multipromise) { diff --git a/td/telegram/MessageContent.h b/td/telegram/MessageContent.h index fc564cab3..d127710d6 100644 --- a/td/telegram/MessageContent.h +++ b/td/telegram/MessageContent.h @@ -7,6 +7,7 @@ #pragma once #include "td/telegram/DialogId.h" +#include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/InputGroupCallId.h" @@ -176,7 +177,7 @@ void unregister_message_content(Td *td, const MessageContent *content, FullMessa const char *source); unique_ptr get_secret_message_content( - Td *td, string message_text, tl_object_ptr file, + Td *td, string message_text, unique_ptr file, tl_object_ptr &&media, vector> &&secret_entities, DialogId owner_dialog_id, MultiPromiseActor &load_data_multipromise); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ba17b829e..f15ae18b9 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -12744,15 +12744,13 @@ void MessagesManager::on_send_secret_message_error(int64 random_id, Status error } void MessagesManager::on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date, - tl_object_ptr file_ptr, - Promise<> promise) { + unique_ptr file, Promise<> promise) { promise.set_value(Unit()); // TODO: set after message is saved FileId new_file_id; - if (file_ptr != nullptr && file_ptr->get_id() == telegram_api::encryptedFile::ID) { - auto file = move_tl_object_as(file_ptr); + if (file != nullptr) { if (!DcId::is_valid(file->dc_id_)) { - LOG(ERROR) << "Wrong dc_id = " << file->dc_id_ << " in file " << to_string(file); + LOG(ERROR) << "Wrong dc_id = " << file->dc_id_ << " in file " << *file; } else { DialogId owner_dialog_id; auto it = being_sent_messages_.find(random_id); @@ -12936,7 +12934,7 @@ void MessagesManager::on_update_secret_chat_state(SecretChatId secret_chat_id, S } void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, - int32 date, tl_object_ptr file, + int32 date, unique_ptr file, tl_object_ptr message, Promise<> promise) { LOG(DEBUG) << "On get " << to_string(message); CHECK(message != nullptr); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index a4530168b..411f73513 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -17,6 +17,7 @@ #include "td/telegram/DialogLocation.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/DialogSource.h" +#include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FolderId.h" @@ -228,8 +229,8 @@ class MessagesManager final : public Actor { void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise<>); - void on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date, - tl_object_ptr file_ptr, Promise<> promise); + void on_send_secret_message_success(int64 random_id, MessageId message_id, int32 date, unique_ptr file, + Promise<> promise); void on_send_secret_message_error(int64 random_id, Status error, Promise<> promise); void delete_secret_messages(SecretChatId secret_chat_id, std::vector random_ids, Promise<> promise); @@ -242,8 +243,8 @@ class MessagesManager final : public Actor { void on_update_secret_chat_state(SecretChatId secret_chat_id, SecretChatState state); void on_get_secret_message(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date, - tl_object_ptr file, - tl_object_ptr message, Promise<> promise); + unique_ptr file, tl_object_ptr message, + Promise<> promise); void on_secret_chat_screenshot_taken(SecretChatId secret_chat_id, UserId user_id, MessageId message_id, int32 date, int64 random_id, Promise<> promise); diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index dcbaf399f..e3358a52f 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -660,7 +660,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AnimationSize &an << animation_size.main_frame_timestamp; } -Photo get_encrypted_file_photo(FileManager *file_manager, tl_object_ptr &&file, +Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr &&file, tl_object_ptr &&photo, DialogId owner_dialog_id) { FileId file_id = file_manager->register_remote( diff --git a/td/telegram/Photo.h b/td/telegram/Photo.h index 47a87847c..3830b0777 100644 --- a/td/telegram/Photo.h +++ b/td/telegram/Photo.h @@ -7,6 +7,7 @@ #pragma once #include "td/telegram/DialogId.h" +#include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileType.h" #include "td/telegram/net/DcId.h" @@ -137,7 +138,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AnimationSize &an Photo get_photo(FileManager *file_manager, tl_object_ptr &&photo, DialogId owner_dialog_id); Photo get_photo(FileManager *file_manager, tl_object_ptr &&photo, DialogId owner_dialog_id); -Photo get_encrypted_file_photo(FileManager *file_manager, tl_object_ptr &&file, +Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr &&file, tl_object_ptr &&photo, DialogId owner_dialog_id); Photo get_web_document_photo(FileManager *file_manager, tl_object_ptr web_document, DialogId owner_dialog_id); diff --git a/td/telegram/SecretChatActor.cpp b/td/telegram/SecretChatActor.cpp index 314f77a43..955412e25 100644 --- a/td/telegram/SecretChatActor.cpp +++ b/td/telegram/SecretChatActor.cpp @@ -1238,11 +1238,6 @@ Status SecretChatActor::do_inbound_message_decrypted(unique_ptrpromise); // process message - tl_object_ptr file; - if (message->has_encrypted_file) { - file = message->file.as_encrypted_file(); - } - if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessage46::ID) { auto old = move_tl_object_as(message->decrypted_message_layer->message_); old->flags_ &= ~secret_api::decryptedMessage::GROUPED_ID_MASK; // just in case @@ -1266,7 +1261,8 @@ Status SecretChatActor::do_inbound_message_decrypted(unique_ptr(message->decrypted_message_layer->message_); context_->on_inbound_message(get_user_id(), MessageId(ServerMessageId(message->message_id)), message->date, - std::move(file), std::move(decrypted_message), std::move(save_message_finish)); + std::move(message->file), std::move(decrypted_message), + std::move(save_message_finish)); } else if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessageService::ID) { auto decrypted_message_service = move_tl_object_as(message->decrypted_message_layer->message_); @@ -1618,31 +1614,24 @@ void SecretChatActor::on_outbound_send_message_result(NetQueryPtr query, Promise } case telegram_api::messages_sentEncryptedFile::ID: { auto sent = move_tl_object_as(result); - std::function()> get_file; - telegram_api::downcast_call( - *sent->file_, overloaded( - [&](telegram_api::encryptedFileEmpty &) { - state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file( - telegram_api::inputEncryptedFileEmpty()); - get_file = [] { - return telegram_api::make_object(); - }; - }, - [&](telegram_api::encryptedFile &file) { - state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file( - telegram_api::inputEncryptedFile(file.id_, file.access_hash_)); - get_file = [id = file.id_, access_hash = file.access_hash_, size = file.size_, - dc_id = file.dc_id_, key_fingerprint = file.key_fingerprint_] { - return telegram_api::make_object(id, access_hash, size, - dc_id, key_fingerprint); - }; - })); - - state->send_result_ = [this, random_id = state->message->random_id, - message_id = MessageId(ServerMessageId(state->message->message_id)), date = sent->date_, - get_file = std::move(get_file)](Promise<> promise) { - this->context_->on_send_message_ok(random_id, message_id, date, get_file(), std::move(promise)); - }; + auto file = EncryptedFile::get_encrypted_file(std::move(sent->file_)); + if (file == nullptr) { + state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file(nullptr); + state->send_result_ = [this, random_id = state->message->random_id, + message_id = MessageId(ServerMessageId(state->message->message_id)), + date = sent->date_](Promise<> promise) { + this->context_->on_send_message_ok(random_id, message_id, date, nullptr, std::move(promise)); + }; + } else { + state->message->file = log_event::EncryptedInputFile::from_input_encrypted_file( + make_tl_object(file->id_, file->access_hash_)); + state->send_result_ = [this, random_id = state->message->random_id, + message_id = MessageId(ServerMessageId(state->message->message_id)), + date = sent->date_, file = *file](Promise<> promise) { + this->context_->on_send_message_ok(random_id, message_id, date, make_unique(file), + std::move(promise)); + }; + } state->send_result_(std::move(send_message_finish_promise)); return; } diff --git a/td/telegram/SecretChatActor.h b/td/telegram/SecretChatActor.h index 73905a52d..8008c680e 100644 --- a/td/telegram/SecretChatActor.h +++ b/td/telegram/SecretChatActor.h @@ -7,6 +7,7 @@ #pragma once #include "td/telegram/DhConfig.h" +#include "td/telegram/EncryptedFile.h" #include "td/telegram/FolderId.h" #include "td/telegram/logevent/SecretChatEvent.h" #include "td/telegram/MessageId.h" @@ -84,8 +85,7 @@ class SecretChatActor final : public NetQueryCallback { // this update through binlog too. So it wouldn't be deleted before update is saved. // inbound messages - virtual void on_inbound_message(UserId user_id, MessageId message_id, int32 date, - tl_object_ptr file, + virtual void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr file, tl_object_ptr message, Promise<> promise) = 0; virtual void on_delete_messages(std::vector random_id, Promise<> promise) = 0; virtual void on_flush_history(bool remove_from_dialog_list, MessageId message_id, Promise<> promise) = 0; @@ -97,8 +97,8 @@ class SecretChatActor final : public NetQueryCallback { // outbound messages virtual void on_send_message_ack(int64 random_id) = 0; - virtual void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, - tl_object_ptr file, Promise<> promise) = 0; + virtual void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, unique_ptr file, + Promise<> promise) = 0; virtual void on_send_message_error(int64 random_id, Status error, Promise<> promise) = 0; }; diff --git a/td/telegram/SecretChatsManager.cpp b/td/telegram/SecretChatsManager.cpp index 1e1c1c13f..c11795878 100644 --- a/td/telegram/SecretChatsManager.cpp +++ b/td/telegram/SecretChatsManager.cpp @@ -9,6 +9,7 @@ #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/DhCache.h" +#include "td/telegram/EncryptedFile.h" #include "td/telegram/FolderId.h" #include "td/telegram/Global.h" #include "td/telegram/logevent/SecretChatEvent.h" @@ -198,17 +199,7 @@ void SecretChatsManager::on_new_message(tl_object_ptrget_id() == telegram_api::encryptedMessage::ID) { auto message = move_tl_object_as(message_ptr); - if (message->file_->get_id() == telegram_api::encryptedFile::ID) { - auto file = move_tl_object_as(message->file_); - - event->file.id = file->id_; - event->file.access_hash = file->access_hash_; - event->file.size = file->size_; - event->file.dc_id = file->dc_id_; - event->file.key_fingerprint = file->key_fingerprint_; - - event->has_encrypted_file = true; - } + event->file = EncryptedFile::get_encrypted_file(std::move(message->file_)); } add_inbound_message(std::move(event)); } @@ -350,8 +341,7 @@ unique_ptr SecretChatsManager::make_secret_chat_contex user_id, state, is_outbound, ttl, date, key_hash, layer, initial_folder_id); } - void on_inbound_message(UserId user_id, MessageId message_id, int32 date, - tl_object_ptr file, + void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr file, tl_object_ptr message, Promise<> promise) final { send_closure_later(G()->messages_manager(), &MessagesManager::on_get_secret_message, secret_chat_id_, user_id, message_id, date, std::move(file), std::move(message), std::move(promise)); @@ -365,8 +355,8 @@ unique_ptr SecretChatsManager::make_secret_chat_contex void on_send_message_ack(int64 random_id) final { send_closure_later(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); } - void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, - tl_object_ptr file, Promise<> promise) final { + void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, unique_ptr file, + Promise<> promise) final { send_closure_later(G()->messages_manager(), &MessagesManager::on_send_secret_message_success, random_id, message_id, date, std::move(file), std::move(promise)); } diff --git a/td/telegram/logevent/SecretChatEvent.h b/td/telegram/logevent/SecretChatEvent.h index 748f96dd5..e400c9487 100644 --- a/td/telegram/logevent/SecretChatEvent.h +++ b/td/telegram/logevent/SecretChatEvent.h @@ -6,6 +6,7 @@ // #pragma once +#include "td/telegram/EncryptedFile.h" #include "td/telegram/Global.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/secret_api.h" @@ -218,53 +219,6 @@ inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedInputFile &fi return sb << to_string(file.as_input_encrypted_file()); } -// encryptedFile#4a70994c id:long access_hash:long size:int dc_id:int key_fingerprint:int = EncryptedFile; -struct EncryptedFileLocation { - static constexpr int32 MAGIC = 0x473d738a; - int64 id = 0; - int64 access_hash = 0; - int32 size = 0; - int32 dc_id = 0; - int32 key_fingerprint = 0; - - tl_object_ptr as_encrypted_file() { - return make_tl_object(id, access_hash, size, dc_id, key_fingerprint); - } - template - void store(StorerT &storer) const { - using td::store; - store(MAGIC, storer); - store(id, storer); - store(access_hash, storer); - store(size, storer); - store(dc_id, storer); - store(key_fingerprint, storer); - } - - template - void parse(ParserT &parser) { - using td::parse; - int32 got_magic; - - parse(got_magic, parser); - parse(id, parser); - parse(access_hash, parser); - parse(size, parser); - parse(dc_id, parser); - parse(key_fingerprint, parser); - - if (got_magic != MAGIC) { - parser.set_error("EncryptedFileLocation magic mismatch"); - return; - } - } -}; - -inline StringBuilder &operator<<(StringBuilder &sb, const EncryptedFileLocation &file) { - return sb << "[" << tag("id", file.id) << tag("access_hash", file.access_hash) << tag("size", file.size) - << tag("dc_id", file.dc_id) << tag("key_fingerprint", file.key_fingerprint) << "]"; -} - // LogEvents // TODO: Qts and SeqNoState could be just Logevents that are updated during regenerate class InboundSecretMessage final : public SecretChatLogEventBase { @@ -291,15 +245,15 @@ class InboundSecretMessage final : public SecretChatLogEventBaselayer_; } - EncryptedFileLocation file; + unique_ptr file; - bool has_encrypted_file = false; bool is_pending = false; template void store(StorerT &storer) const { using td::store; + bool has_encrypted_file = file != nullptr; BEGIN_STORE_FLAGS(); STORE_FLAG(has_encrypted_file); STORE_FLAG(is_pending); @@ -328,6 +282,7 @@ class InboundSecretMessage final : public SecretChatLogEventBase file, + void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr file, tl_object_ptr message, Promise<>) final; void on_send_message_error(int64 random_id, Status error, Promise<>) final; void on_send_message_ack(int64 random_id) final; - void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, - tl_object_ptr file, Promise<>) final; + void on_send_message_ok(int64 random_id, MessageId message_id, int32 date, unique_ptr file, + Promise<>) final; void on_delete_messages(std::vector random_id, Promise<>) final; void on_flush_history(bool, MessageId, Promise<>) final; void on_read_message(int64, Promise<>) final; @@ -974,7 +974,7 @@ void FakeSecretChatContext::send_net_query(NetQueryPtr query, ActorShared file, + unique_ptr file, tl_object_ptr message, Promise<> promise) { send_closure(master_, &Master::on_inbound_message, message->message_, std::move(promise)); } @@ -984,7 +984,7 @@ void FakeSecretChatContext::on_send_message_error(int64 random_id, Status error, void FakeSecretChatContext::on_send_message_ack(int64 random_id) { } void FakeSecretChatContext::on_send_message_ok(int64 random_id, MessageId message_id, int32 date, - tl_object_ptr file, Promise<> promise) { + unique_ptr file, Promise<> promise) { send_closure(master_, &Master::on_send_message_ok, random_id, std::move(promise)); } void FakeSecretChatContext::on_delete_messages(std::vector random_id, Promise<> promise) {