From ad2cc6e5345d9d8f4b67c84f0b71c9227d875315 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 27 Sep 2021 21:43:14 +0300 Subject: [PATCH 01/82] Use ClientManager instead of Client in ClientDotNet. --- example/csharp/TdExample.cs | 14 +++-- example/uwp/app/MainPage.xaml.cs | 35 +++++-------- td/telegram/ClientDotNet.cpp | 88 +++++++++++++++----------------- 3 files changed, 61 insertions(+), 76 deletions(-) diff --git a/example/csharp/TdExample.cs b/example/csharp/TdExample.cs index 3b18f1dd9..39afc0ab4 100644 --- a/example/csharp/TdExample.cs +++ b/example/csharp/TdExample.cs @@ -34,13 +34,7 @@ namespace TdExample private static Td.Client CreateTdClient() { - Td.Client result = Td.Client.Create(new UpdateHandler()); - new Thread(() => - { - Thread.CurrentThread.IsBackground = true; - result.Run(); - }).Start(); - return result; + return Td.Client.Create(new UpdateHandler()); } private static void Print(string str) @@ -133,7 +127,6 @@ namespace TdExample else if (_authorizationState is TdApi.AuthorizationStateClosed) { Print("Closed"); - _client.Dispose(); // _client is closed and native resources can be disposed now if (!_needQuit) { _client = CreateTdClient(); // recreate _client after previous has closed @@ -223,6 +216,11 @@ namespace TdExample { throw new System.IO.IOException("Write access to the current directory is required"); } + new Thread(() => + { + Thread.CurrentThread.IsBackground = true; + Td.Client.Run(); + }).Start(); // create Td.Client _client = CreateTdClient(); diff --git a/example/uwp/app/MainPage.xaml.cs b/example/uwp/app/MainPage.xaml.cs index 2036150a2..7b843ec9f 100644 --- a/example/uwp/app/MainPage.xaml.cs +++ b/example/uwp/app/MainPage.xaml.cs @@ -30,30 +30,23 @@ namespace TdApp Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0)); Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile(Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "log"), 1 << 27, false))); Td.Client.SetLogMessageCallback(100, LogMessageCallback); - System.Threading.Tasks.Task.Run(() => { - try - { - _client = Td.Client.Create(_handler); - var parameters = new TdApi.TdlibParameters(); - parameters.DatabaseDirectory = Windows.Storage.ApplicationData.Current.LocalFolder.Path; - parameters.UseSecretChats = true; - parameters.UseMessageDatabase = true; - parameters.ApiId = 94575; - parameters.ApiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; - parameters.SystemLanguageCode = "en"; - parameters.DeviceModel = "Desktop"; - parameters.ApplicationVersion = "1.0.0"; - _client.Send(new TdApi.SetTdlibParameters(parameters), null); - _client.Send(new TdApi.CheckDatabaseEncryptionKey(), null); - _client.Run(); - } - catch (Exception ex) - { - Print(ex.ToString()); - } + Td.Client.Run(); }); + + _client = Td.Client.Create(_handler); + var parameters = new TdApi.TdlibParameters(); + parameters.DatabaseDirectory = Windows.Storage.ApplicationData.Current.LocalFolder.Path; + parameters.UseSecretChats = true; + parameters.UseMessageDatabase = true; + parameters.ApiId = 94575; + parameters.ApiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; + parameters.SystemLanguageCode = "en"; + parameters.DeviceModel = "Desktop"; + parameters.ApplicationVersion = "1.0.0"; + _client.Send(new TdApi.SetTdlibParameters(parameters), null); + _client.Send(new TdApi.CheckDatabaseEncryptionKey(), null); } public void Print(String str) diff --git a/td/telegram/ClientDotNet.cpp b/td/telegram/ClientDotNet.cpp index 57d3dc934..38bf780bd 100644 --- a/td/telegram/ClientDotNet.cpp +++ b/td/telegram/ClientDotNet.cpp @@ -56,18 +56,12 @@ public: /// of the query or with Telegram.Td.Api.Error as parameter. If it is null, nothing will be called. /// Thrown when query is null. void Send(Api::Function^ function, ClientResultHandler^ handler) { - if (function == nullptr) { - throw REF_NEW NullReferenceException("Function can't be null"); - } - - std::uint64_t queryId = Increment(currentId); + std::uint64_t requestId = Increment(currentRequestId); if (handler != nullptr) { - handlers[queryId] = handler; + handlers[requestId] = handler; } - td::Client::Request request; - request.id = queryId; - request.function = td::td_api::move_object_as(ToUnmanaged(function)->get_object_ptr()); - client->send(std::move(request)); + auto request = td::td_api::move_object_as(ToUnmanaged(function)->get_object_ptr()); + td::ClientManager::get_manager_singleton()->send(clientId, requestId, std::move(request)); } /// @@ -77,31 +71,32 @@ public: /// Returns request result. /// Thrown when query is null. static Api::BaseObject^ Execute(Api::Function^ function) { - if (function == nullptr) { - throw REF_NEW NullReferenceException("Function can't be null"); - } - - td::Client::Request request; - request.id = 0; - request.function = td::td_api::move_object_as(ToUnmanaged(function)->get_object_ptr()); - return Api::FromUnmanaged(*td::Client::execute(std::move(request)).object); + auto request = td::td_api::move_object_as(ToUnmanaged(function)->get_object_ptr()); + return Api::FromUnmanaged(*td::ClientManager::execute(std::move(request))); } /// /// Launches a cycle which will fetch all results of queries to TDLib and incoming updates from TDLib. - /// Must be called once on a separate dedicated thread, on which all updates and query results will be handled. - /// Returns only when TDLib instance is closed. + /// Must be called once on a separate dedicated thread, on which all updates and query results from all Clients will be handled. + /// Never returns. /// - void Run() { + static void Run() { while (true) { - auto response = client->receive(10.0); + auto response = td::ClientManager::get_manager_singleton()->receive(300.0); if (response.object != nullptr) { - ProcessResult(response.id, Api::FromUnmanaged(*response.object)); - - if (response.object->get_id() == td::td_api::updateAuthorizationState::ID && + bool isClosed = response.object->get_id() == td::td_api::updateAuthorizationState::ID && static_cast(*response.object).authorization_state_->get_id() == - td::td_api::authorizationStateClosed::ID) { - break; + td::td_api::authorizationStateClosed::ID && response.request_id == 0; + + ClientResultHandler^ handler; + if (response.request_id == 0 ? updateHandlers.TryGetValue(response.client_id, handler) : + handlers.TryRemove(response.request_id, handler)) { + // TODO try/catch + handler->OnResult(Api::FromUnmanaged(*response.object)); + } + + if (isClosed) { + updateHandlers.TryRemove(response.client_id, handler); } } } @@ -127,38 +122,33 @@ public: static void SetLogMessageCallback(std::int32_t max_verbosity_level, LogMessageCallback^ callback) { std::lock_guard lock(logMutex); if (callback == nullptr) { - ::td::ClientManager::set_log_message_callback(max_verbosity_level, nullptr); + td::ClientManager::set_log_message_callback(max_verbosity_level, nullptr); logMessageCallback = nullptr; } else { logMessageCallback = callback; - ::td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper); + td::ClientManager::set_log_message_callback(max_verbosity_level, LogMessageCallbackWrapper); } } #endif private: Client(ClientResultHandler^ updateHandler) { - client = new td::Client(); - handlers[0] = updateHandler; - } - - ~Client() { - delete client; - } - - std::int64_t currentId = 0; - ConcurrentDictionary handlers; - td::Client *client = nullptr; - - void ProcessResult(std::uint64_t id, Api::BaseObject^ object) { - ClientResultHandler^ handler; - // update handler stays forever - if (id == 0 ? handlers.TryGetValue(id, handler) : handlers.TryRemove(id, handler)) { - // TODO try/catch - handler->OnResult(object); + clientId = td::ClientManager::get_manager_singleton()->create_client_id(); + if (updateHandler != nullptr) { + updateHandlers[clientId] = updateHandler; } + Send(REF_NEW Api::GetOption("version"), nullptr); } +#if !TD_CLI + static std::int64_t currentRequestId; +#else + static std::int64_t currentRequestId = 0; +#endif + static ConcurrentDictionary handlers; + static ConcurrentDictionary updateHandlers; + std::int32_t clientId; + #if !TD_CLI static std::mutex logMutex; static LogMessageCallback^ logMessageCallback; @@ -173,6 +163,10 @@ private: }; #if !TD_CLI +std::int64_t Client::currentRequestId = 0; +ConcurrentDictionary Client::handlers; +ConcurrentDictionary Client::updateHandlers; + std::mutex Client::logMutex; LogMessageCallback^ Client::logMessageCallback; #endif From 77158cd7a52289256584bac49c5b78e913445c9f Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 4 Oct 2021 16:08:51 +0300 Subject: [PATCH 02/82] Register emoji messages. --- td/telegram/MessageContent.cpp | 45 +++++++++++++++----- td/telegram/StickersManager.cpp | 75 +++++++++++++++++++++++++++++++++ td/telegram/StickersManager.h | 7 +++ 3 files changed, 116 insertions(+), 11 deletions(-) diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 62dc1cd58..c9e993e58 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -3582,12 +3582,22 @@ bool merge_message_content_file_id(Td *td, MessageContent *message_content, File return false; } +static bool can_be_animated_emoji(const FormattedText &text) { + return text.entities.empty() && is_emoji(text.text); +} + void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id, const char *source) { switch (content->get_type()) { - case MessageContentType::Text: - return td->web_pages_manager_->register_web_page(static_cast(content)->web_page_id, - full_message_id, source); + case MessageContentType::Text: { + auto text = static_cast(content); + if (text->web_page_id.is_valid()) { + td->web_pages_manager_->register_web_page(text->web_page_id, full_message_id, source); + } else if (can_be_animated_emoji(text->text)) { + td->stickers_manager_->register_emoji(text->text.text, full_message_id, source); + } + return; + } case MessageContentType::Poll: return td->poll_manager_->register_poll(static_cast(content)->poll_id, full_message_id, source); @@ -3606,12 +3616,16 @@ void reregister_message_content(Td *td, const MessageContent *old_content, const auto new_content_type = new_content->get_type(); if (old_content_type == new_content_type) { switch (old_content_type) { - case MessageContentType::Text: - if (static_cast(old_content)->web_page_id == - static_cast(new_content)->web_page_id) { + case MessageContentType::Text: { + auto old_text = static_cast(old_content); + auto new_text = static_cast(new_content); + if (old_text->web_page_id == new_text->web_page_id && + (old_text->text == new_text->text || + (!can_be_animated_emoji(old_text->text) && !can_be_animated_emoji(new_text->text)))) { return; } break; + } case MessageContentType::Poll: if (static_cast(old_content)->poll_id == static_cast(new_content)->poll_id) { @@ -3637,9 +3651,15 @@ void reregister_message_content(Td *td, const MessageContent *old_content, const void unregister_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id, const char *source) { switch (content->get_type()) { - case MessageContentType::Text: - return td->web_pages_manager_->unregister_web_page(static_cast(content)->web_page_id, - full_message_id, source); + case MessageContentType::Text: { + auto text = static_cast(content); + if (text->web_page_id.is_valid()) { + td->web_pages_manager_->unregister_web_page(text->web_page_id, full_message_id, source); + } else if (can_be_animated_emoji(text->text)) { + td->stickers_manager_->unregister_emoji(text->text.text, full_message_id, source); + } + return; + } case MessageContentType::Poll: return td->poll_manager_->unregister_poll(static_cast(content)->poll_id, full_message_id, source); @@ -4781,6 +4801,9 @@ tl_object_ptr get_message_content_object(const MessageCo } case MessageContentType::Text: { const auto *m = static_cast(content); + if (can_be_animated_emoji(m->text) && !m->web_page_id.is_valid()) { + return td->stickers_manager_->get_message_content_animated_emoji_object(m->text.text); + } return make_tl_object( get_formatted_text_object(m->text, skip_bot_commands, max_media_timestamp), td->web_pages_manager_->get_web_page_object(m->web_page_id)); @@ -5311,8 +5334,8 @@ void get_message_content_animated_emoji_click_sticker(const MessageContent *cont return promise.set_error(Status::Error(400, "Message is not an animated emoji message")); } - auto &text = static_cast(content)->text; - if (!text.entities.empty()) { + const auto &text = static_cast(content)->text; + if (!can_be_animated_emoji(text)) { return promise.set_error(Status::Error(400, "Message is not an animated emoji message")); } td->stickers_manager_->get_animated_emoji_click_sticker(text.text, full_message_id, std::move(promise)); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 61271adb0..dd480bb87 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1280,6 +1280,8 @@ void StickersManager::init() { on_update_dice_success_values(); + load_special_sticker_set(add_special_sticker_set(SpecialStickerSetType::animated_emoji())); + if (G()->parameters().use_file_db) { auto old_featured_sticker_set_count_str = G()->td_db()->get_binlog_pmc()->get("old_featured_sticker_set_count"); if (!old_featured_sticker_set_count_str.empty()) { @@ -1404,6 +1406,27 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t CHECK(sticker_set != nullptr); CHECK(sticker_set->was_loaded); + if (type.type_ == SpecialStickerSetType::animated_emoji()) { + for (auto sticker_it : sticker_set->sticker_emojis_map_) { + for (auto &emoji : sticker_it.second) { + auto it = emoji_messages_.find(emoji); + if (it == emoji_messages_.end()) { + continue; + } + + vector full_message_ids; + for (auto full_message_id : it->second) { + full_message_ids.push_back(full_message_id); + } + CHECK(!full_message_ids.empty()); + for (auto full_message_id : full_message_ids) { + td_->messages_manager_->on_external_update_message_content(full_message_id); + } + } + } + return; + } + if (type.type_ == SpecialStickerSetType::animated_emoji_click()) { auto pending_get_requests = std::move(pending_get_animated_emoji_click_stickers_); reset_to_empty(pending_get_animated_emoji_click_stickers_); @@ -1893,6 +1916,13 @@ tl_object_ptr StickersManager::get_sticker_set_info_obje std::move(stickers)); } +td_api::object_ptr StickersManager::get_message_content_animated_emoji_object( + const string &emoji) { + return td_api::make_object( + td_api::make_object(emoji, std::vector>()), + nullptr); +} + tl_object_ptr StickersManager::get_input_sticker_set(StickerSetId sticker_set_id) const { auto sticker_set = get_sticker_set(sticker_set_id); if (sticker_set == nullptr) { @@ -4028,6 +4058,51 @@ void StickersManager::unregister_dice(const string &emoji, int32 value, FullMess } } +void StickersManager::register_emoji(const string &emoji, FullMessageId full_message_id, const char *source) { + CHECK(!emoji.empty()); + if (td_->auth_manager_->is_bot()) { + return; + } + + LOG(INFO) << "Register emoji " << emoji << " from " << full_message_id << " from " << source; + bool is_inserted = emoji_messages_[emoji].insert(full_message_id).second; + LOG_CHECK(is_inserted) << source << " " << emoji << " " << full_message_id; + + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); + bool need_load = false; + if (!special_sticker_set.id_.is_valid()) { + need_load = true; + } else { + auto sticker_set = get_sticker_set(special_sticker_set.id_); + CHECK(sticker_set != nullptr); + need_load = !sticker_set->was_loaded; + } + + if (need_load) { + LOG(INFO) << "Waiting for the animated emoji sticker set needed in " << full_message_id; + load_special_sticker_set(special_sticker_set); + } else { + // TODO reload once in a while + // reload_special_sticker_set(special_sticker_set); + } +} + +void StickersManager::unregister_emoji(const string &emoji, FullMessageId full_message_id, const char *source) { + CHECK(!emoji.empty()); + if (td_->auth_manager_->is_bot()) { + return; + } + + LOG(INFO) << "Unregister emoji " << emoji << " from " << full_message_id << " from " << source; + auto &message_ids = emoji_messages_[emoji]; + auto is_deleted = message_ids.erase(full_message_id) > 0; + LOG_CHECK(is_deleted) << source << " " << emoji << " " << full_message_id; + + if (message_ids.empty()) { + emoji_messages_.erase(emoji); + } +} + void StickersManager::get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, Promise> &&promise) { auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji_click()); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index a3ab9a092..8a1427488 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -63,12 +63,18 @@ class StickersManager final : public Actor { const vector &sticker_set_ids, size_t covers_limit) const; + td_api::object_ptr get_message_content_animated_emoji_object(const string &emoji); + tl_object_ptr get_input_sticker_set(StickerSetId sticker_set_id) const; void register_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source); void unregister_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source); + void register_emoji(const string &emoji, FullMessageId full_message_id, const char *source); + + void unregister_emoji(const string &emoji, FullMessageId full_message_id, const char *source); + void get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, Promise> &&promise); @@ -795,6 +801,7 @@ class StickersManager final : public Actor { std::unordered_map emoji_suggestions_urls_; std::unordered_map> dice_messages_; + std::unordered_map> emoji_messages_; string dice_emojis_str_; vector dice_emojis_; From ffe03ecb10a850c8cc16b45876b61b90c3e0f96c Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Oct 2021 16:12:04 +0300 Subject: [PATCH 03/82] Add messageAnimatedEmoji. --- td/generate/scheme/td_api.tl | 3 ++ td/telegram/StickersManager.cpp | 89 ++++++++++++++++++++++++++------- td/telegram/StickersManager.h | 6 ++- tdutils/td/utils/emoji.cpp | 12 +++++ tdutils/td/utils/emoji.h | 3 ++ 5 files changed, 95 insertions(+), 18 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 87bc6b797..fd67640cf 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1707,6 +1707,9 @@ messageVenue venue:venue = MessageContent; //@description A message with a user contact @contact The contact description messageContact contact:contact = MessageContent; +//@description A message with an animated emoji @sticker The animated sticker with the emoji animation @emoji The corresponding emoji +messageAnimatedEmoji sticker:sticker emoji:string = MessageContent; + //@description A dice message. The dice value is randomly generated by the server //@initial_state The animated stickers with the initial dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known //@final_state The animated stickers with the final dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index dd480bb87..c9a180569 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1360,6 +1360,7 @@ void StickersManager::load_special_sticker_set_by_type(const SpecialStickerSetTy } void StickersManager::load_special_sticker_set(SpecialStickerSet &sticker_set) { + CHECK(!td_->auth_manager_->is_bot()); if (sticker_set.is_being_loaded_) { return; } @@ -1407,23 +1408,17 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t CHECK(sticker_set->was_loaded); if (type.type_ == SpecialStickerSetType::animated_emoji()) { - for (auto sticker_it : sticker_set->sticker_emojis_map_) { - for (auto &emoji : sticker_it.second) { - auto it = emoji_messages_.find(emoji); - if (it == emoji_messages_.end()) { - continue; - } - - vector full_message_ids; - for (auto full_message_id : it->second) { + vector full_message_ids; + for (const auto &it : emoji_messages_) { + if (get_animated_emoji_sticker(sticker_set, it.first).first.is_valid()) { + for (auto full_message_id : it.second) { full_message_ids.push_back(full_message_id); } - CHECK(!full_message_ids.empty()); - for (auto full_message_id : full_message_ids) { - td_->messages_manager_->on_external_update_message_content(full_message_id); - } } } + for (auto full_message_id : full_message_ids) { + td_->messages_manager_->on_external_update_message_content(full_message_id); + } return; } @@ -1916,8 +1911,64 @@ tl_object_ptr StickersManager::get_sticker_set_info_obje std::move(stickers)); } +std::pair StickersManager::get_animated_emoji_sticker(const StickerSet *sticker_set, const string &emoji) { + auto emoji_without_modifiers = remove_emoji_modifiers(emoji).str(); + auto it = sticker_set->emoji_stickers_map_.find(emoji_without_modifiers); + if (it == sticker_set->emoji_stickers_map_.end()) { + return {}; + } + + // trying to find full emoji match + for (const auto &sticker_id : it->second) { + auto emoji_it = sticker_set->sticker_emojis_map_.find(sticker_id); + CHECK(emoji_it != sticker_set->sticker_emojis_map_.end()); + if (td::contains(emoji_it->second, emoji)) { + return {sticker_id, 0}; + } + } + + // trying to find match without Fitzpatrick modifiers + int modifier_id = get_fitzpatrick_modifier(emoji); + if (modifier_id > 0) { + for (const auto &sticker_id : it->second) { + auto emoji_it = sticker_set->sticker_emojis_map_.find(sticker_id); + CHECK(emoji_it != sticker_set->sticker_emojis_map_.end()); + if (td::contains(emoji_it->second, Slice(emoji).remove_suffix(4))) { + return {sticker_id, modifier_id}; + } + } + } + + // there is no match + return {}; +} + +std::pair StickersManager::get_animated_emoji_sticker(const string &emoji) { + if (td_->auth_manager_->is_bot()) { + return {}; + } + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); + if (!special_sticker_set.id_.is_valid()) { + load_special_sticker_set(special_sticker_set); + return {}; + } + + auto sticker_set = get_sticker_set(special_sticker_set.id_); + CHECK(sticker_set != nullptr); + if (!sticker_set->was_loaded) { + load_special_sticker_set(special_sticker_set); + return {}; + } + + return get_animated_emoji_sticker(sticker_set, emoji); +} + td_api::object_ptr StickersManager::get_message_content_animated_emoji_object( const string &emoji) { + auto animated_sticker = get_animated_emoji_sticker(emoji); + if (animated_sticker.first.is_valid()) { + return td_api::make_object(get_sticker_object(animated_sticker.first), emoji); + } return td_api::make_object( td_api::make_object(emoji, std::vector>()), nullptr); @@ -4139,7 +4190,7 @@ int StickersManager::get_emoji_number(Slice emoji) { return emoji[0] - '0'; } -vector StickersManager::get_animated_emoji_stickers(const StickerSet *sticker_set, Slice emoji) const { +vector StickersManager::get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const { vector result; for (auto sticker_id : sticker_set->sticker_ids) { auto s = get_sticker(sticker_id); @@ -4151,7 +4202,7 @@ vector StickersManager::get_animated_emoji_stickers(const StickerSet *st if (result.empty()) { const static vector heart_emojis{"๐Ÿ’›", "๐Ÿ’™", "๐Ÿ’š", "๐Ÿ’œ", "๐Ÿงก", "๐Ÿ–ค", "๐ŸคŽ", "๐Ÿค"}; if (td::contains(heart_emojis, emoji)) { - return get_animated_emoji_stickers(sticker_set, Slice("โค")); + return get_animated_emoji_click_stickers(sticker_set, Slice("โค")); } } return result; @@ -4172,7 +4223,7 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic return promise.set_value(nullptr); } - auto all_sticker_ids = get_animated_emoji_stickers(sticker_set, message_text); + auto all_sticker_ids = get_animated_emoji_click_stickers(sticker_set, message_text); vector> found_stickers; for (auto sticker_id : all_sticker_ids) { auto it = sticker_set->sticker_emojis_map_.find(sticker_id); @@ -4322,6 +4373,10 @@ bool StickersManager::is_sent_animated_emoji_click(DialogId dialog_id, Slice emo } Status StickersManager::on_animated_emoji_message_clicked(Slice emoji, FullMessageId full_message_id, string data) { + if (td_->auth_manager_->is_bot()) { + return Status::OK(); + } + TRY_RESULT(value, json_decode(data)); if (value.type() != JsonValue::Type::Object) { return Status::Error("Expected an object"); @@ -4402,7 +4457,7 @@ void StickersManager::schedule_update_animated_emoji_clicked(const StickerSet *s return; } - auto all_sticker_ids = get_animated_emoji_stickers(sticker_set, emoji); + auto all_sticker_ids = get_animated_emoji_click_stickers(sticker_set, emoji); std::unordered_map sticker_ids; for (auto sticker_id : all_sticker_ids) { auto it = sticker_set->sticker_emojis_map_.find(sticker_id); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 8a1427488..ab830f38c 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -603,7 +603,11 @@ class StickersManager final : public Actor { static int get_emoji_number(Slice emoji); - vector get_animated_emoji_stickers(const StickerSet *sticker_set, Slice emoji) const; + static std::pair get_animated_emoji_sticker(const StickerSet *sticker_set, const string &emoji); + + std::pair get_animated_emoji_sticker(const string &emoji); + + vector get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const; void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, Slice message_text, FullMessageId full_message_id, double start_time, diff --git a/tdutils/td/utils/emoji.cpp b/tdutils/td/utils/emoji.cpp index 918aff2ff..37ce7743e 100644 --- a/tdutils/td/utils/emoji.cpp +++ b/tdutils/td/utils/emoji.cpp @@ -839,6 +839,18 @@ bool is_emoji(Slice str) { return emojis.count(str) != 0; } +int get_fitzpatrick_modifier(Slice emoji) { + if (emoji.size() < 4 || emoji[emoji.size() - 4] != '\xF0' || emoji[emoji.size() - 3] != '\x9F' || + emoji[emoji.size() - 2] != '\x8F') { + return 0; + } + auto c = static_cast(emoji.back()); + if (c < 0xBB || c > 0xBF) { + return 0; + } + return (c - 0xBB) + 2; +} + Slice remove_emoji_modifiers(Slice emoji) { static const Slice modifiers[] = {u8"\uFE0E" /* variation selector-15 */, u8"\uFE0F" /* variation selector-16 */, diff --git a/tdutils/td/utils/emoji.h b/tdutils/td/utils/emoji.h index 4a0020187..89018cb1a 100644 --- a/tdutils/td/utils/emoji.h +++ b/tdutils/td/utils/emoji.h @@ -14,6 +14,9 @@ namespace td { // checks whether the string is an emoji; variation selectors are ignored bool is_emoji(Slice str); +// checks whether emoji ends on a Fitzpatrick modifier and returns it's number or 0 +int get_fitzpatrick_modifier(Slice emoji); + // removes all emoji modifiers from the end of the string Slice remove_emoji_modifiers(Slice emoji); From eb20f827301af13342df802dc0142d40e9c2a0d1 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Oct 2021 17:17:29 +0300 Subject: [PATCH 04/82] Add disable_animated_emoji option. --- td/telegram/StickersManager.cpp | 63 +++++++++++++++++++++------------ td/telegram/StickersManager.h | 6 ++++ td/telegram/Td.cpp | 5 +++ 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index c9a180569..9c615cd91 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1235,7 +1235,6 @@ StickersManager::StickersManager(Td *td, ActorShared<> parent) : td_(td), parent narrow_cast(G()->shared_config().get_option_integer("recent_stickers_limit", 200))); on_update_favorite_stickers_limit( narrow_cast(G()->shared_config().get_option_integer("favorite_stickers_limit", 5))); - on_update_dice_emojis(); next_click_animated_emoji_message_time_ = Time::now(); next_update_animated_emoji_clicked_time_ = Time::now(); @@ -1280,7 +1279,11 @@ void StickersManager::init() { on_update_dice_success_values(); - load_special_sticker_set(add_special_sticker_set(SpecialStickerSetType::animated_emoji())); + on_update_disable_animated_emojis(); + + if (!disable_animated_emojis_) { + load_special_sticker_set(add_special_sticker_set(SpecialStickerSetType::animated_emoji())); + } if (G()->parameters().use_file_db) { auto old_featured_sticker_set_count_str = G()->td_db()->get_binlog_pmc()->get("old_featured_sticker_set_count"); @@ -1408,17 +1411,7 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t CHECK(sticker_set->was_loaded); if (type.type_ == SpecialStickerSetType::animated_emoji()) { - vector full_message_ids; - for (const auto &it : emoji_messages_) { - if (get_animated_emoji_sticker(sticker_set, it.first).first.is_valid()) { - for (auto full_message_id : it.second) { - full_message_ids.push_back(full_message_id); - } - } - } - for (auto full_message_id : full_message_ids) { - td_->messages_manager_->on_external_update_message_content(full_message_id); - } + try_update_animated_emoji_messages(); return; } @@ -1944,7 +1937,7 @@ std::pair StickersManager::get_animated_emoji_sticker(const Sticker } std::pair StickersManager::get_animated_emoji_sticker(const string &emoji) { - if (td_->auth_manager_->is_bot()) { + if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { return {}; } auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); @@ -1966,7 +1959,7 @@ std::pair StickersManager::get_animated_emoji_sticker(const string td_api::object_ptr StickersManager::get_message_content_animated_emoji_object( const string &emoji) { auto animated_sticker = get_animated_emoji_sticker(emoji); - if (animated_sticker.first.is_valid()) { + if (animated_sticker.first.is_valid() && !disable_animated_emojis_) { return td_api::make_object(get_sticker_object(animated_sticker.first), emoji); } return td_api::make_object( @@ -2945,14 +2938,6 @@ void StickersManager::on_get_special_sticker_set(const SpecialStickerSetType &ty CHECK(s->is_inited); CHECK(s->is_loaded); - /* - if (type.type_ == SpecialStickerSetType::animated_emoji_click()) { - for (auto &sticker_id : s->sticker_ids) { - // TODO get supported emoji and their numbers - } - } - */ - LOG(INFO) << "Receive special sticker set " << type.type_ << ": " << sticker_set_id << ' ' << s->access_hash << ' ' << s->short_name; auto &sticker_set = add_special_sticker_set(type.type_); @@ -4040,6 +4025,22 @@ void StickersManager::on_update_dice_success_values() { }); } +void StickersManager::on_update_disable_animated_emojis() { + if (G()->close_flag() || td_->auth_manager_->is_bot() || !is_inited_) { + return; + } + + auto disable_animated_emojis = G()->shared_config().get_option_boolean("disable_animated_emoji"); + if (disable_animated_emojis == disable_animated_emojis_) { + return; + } + disable_animated_emojis_ = disable_animated_emojis; + if (!disable_animated_emojis_) { + load_special_sticker_set(add_special_sticker_set(SpecialStickerSetType::animated_emoji())); + } + try_update_animated_emoji_messages(); +} + void StickersManager::on_update_sticker_sets() { // TODO better support archived_sticker_set_ids_[0].clear(); @@ -4051,6 +4052,22 @@ void StickersManager::on_update_sticker_sets() { reload_installed_sticker_sets(true, true); } +void StickersManager::try_update_animated_emoji_messages() { + vector full_message_ids; + /* + for (const auto &it : emoji_messages_) { + if (get_animated_emoji_sticker(sticker_set, it.first).first.is_valid()) { + for (auto full_message_id : it.second) { + full_message_ids.push_back(full_message_id); + } + } + } + */ + for (auto full_message_id : full_message_ids) { + td_->messages_manager_->on_external_update_message_content(full_message_id); + } +} + void StickersManager::register_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source) { CHECK(!emoji.empty()); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index ab830f38c..97de82c38 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -148,6 +148,8 @@ class StickersManager final : public Actor { void on_uninstall_sticker_set(StickerSetId set_id); + void on_update_disable_animated_emojis(); + void on_update_dice_emojis(); void on_update_dice_success_values(); @@ -607,6 +609,8 @@ class StickersManager final : public Actor { std::pair get_animated_emoji_sticker(const string &emoji); + void try_update_animated_emoji_messages(); + vector get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const; void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, Slice message_text, @@ -812,6 +816,8 @@ class StickersManager final : public Actor { string dice_success_values_str_; vector> dice_success_values_; + + bool disable_animated_emojis_ = false; }; } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d5af1c0e8..d741605d0 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3321,6 +3321,8 @@ void Td::on_config_option_updated(const string &name) { } else if (name == "favorite_stickers_limit") { stickers_manager_->on_update_favorite_stickers_limit( narrow_cast(G()->shared_config().get_option_integer(name))); + } else if (name == "disable_animated_emoji") { + stickers_manager_->on_update_disable_animated_emojis(); } else if (name == "my_id") { G()->set_my_id(G()->shared_config().get_option_integer(name)); } else if (name == "session_count") { @@ -7338,6 +7340,9 @@ void Td::on_request(uint64 id, td_api::setOption &request) { } break; case 'd': + if (!is_bot && set_boolean_option("disable_animated_emoji")) { + return; + } if (!is_bot && set_boolean_option("disable_contact_registered_notifications")) { return; } From aae781295c08f19df79a6a7ae506cda49194fdb2 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Oct 2021 18:06:05 +0300 Subject: [PATCH 05/82] Improve updating animated emoji stickers. --- td/telegram/StickersManager.cpp | 110 +++++++++++++++++--------------- td/telegram/StickersManager.h | 9 ++- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 9c615cd91..2f78ae531 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1405,16 +1405,15 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t special_sticker_set.is_being_loaded_ = false; + if (type.type_ == SpecialStickerSetType::animated_emoji()) { + return; + } + CHECK(special_sticker_set.id_.is_valid()); auto sticker_set = get_sticker_set(special_sticker_set.id_); CHECK(sticker_set != nullptr); CHECK(sticker_set->was_loaded); - if (type.type_ == SpecialStickerSetType::animated_emoji()) { - try_update_animated_emoji_messages(); - return; - } - if (type.type_ == SpecialStickerSetType::animated_emoji_click()) { auto pending_get_requests = std::move(pending_get_animated_emoji_click_stickers_); reset_to_empty(pending_get_animated_emoji_click_stickers_); @@ -1904,7 +1903,31 @@ tl_object_ptr StickersManager::get_sticker_set_info_obje std::move(stickers)); } +const StickersManager::StickerSet *StickersManager::get_animated_emoji_sticker_set() { + if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { + return nullptr; + } + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); + if (!special_sticker_set.id_.is_valid()) { + load_special_sticker_set(special_sticker_set); + return nullptr; + } + + auto sticker_set = get_sticker_set(special_sticker_set.id_); + CHECK(sticker_set != nullptr); + if (!sticker_set->was_loaded) { + load_special_sticker_set(special_sticker_set); + return nullptr; + } + + return sticker_set; +} + std::pair StickersManager::get_animated_emoji_sticker(const StickerSet *sticker_set, const string &emoji) { + if (sticker_set == nullptr) { + return {}; + } + auto emoji_without_modifiers = remove_emoji_modifiers(emoji).str(); auto it = sticker_set->emoji_stickers_map_.find(emoji_without_modifiers); if (it == sticker_set->emoji_stickers_map_.end()) { @@ -1937,29 +1960,15 @@ std::pair StickersManager::get_animated_emoji_sticker(const Sticker } std::pair StickersManager::get_animated_emoji_sticker(const string &emoji) { - if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { - return {}; - } - auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); - if (!special_sticker_set.id_.is_valid()) { - load_special_sticker_set(special_sticker_set); - return {}; - } - - auto sticker_set = get_sticker_set(special_sticker_set.id_); - CHECK(sticker_set != nullptr); - if (!sticker_set->was_loaded) { - load_special_sticker_set(special_sticker_set); - return {}; - } - - return get_animated_emoji_sticker(sticker_set, emoji); + return get_animated_emoji_sticker(get_animated_emoji_sticker_set(), emoji); } td_api::object_ptr StickersManager::get_message_content_animated_emoji_object( const string &emoji) { - auto animated_sticker = get_animated_emoji_sticker(emoji); - if (animated_sticker.first.is_valid() && !disable_animated_emojis_) { + auto it = emoji_messages_.find(emoji); + auto animated_sticker = + it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji); + if (animated_sticker.first.is_valid()) { return td_api::make_object(get_sticker_object(animated_sticker.first), emoji); } return td_api::make_object( @@ -2881,6 +2890,11 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s update_sticker_set(s); update_load_requests(s, true, Status::OK()); send_update_installed_sticker_sets(); + + if (set_id == add_special_sticker_set(SpecialStickerSetType::animated_emoji()).id_) { + try_update_animated_emoji_messages(); + } + return set_id; } @@ -2956,6 +2970,7 @@ void StickersManager::on_get_special_sticker_set(const SpecialStickerSetType &ty << ' ' << sticker_set.short_name_); if (type.type_ == SpecialStickerSetType::animated_emoji()) { G()->shared_config().set_option_string(PSLICE() << type.type_ << "_name", sticker_set.short_name_); + try_update_animated_emoji_messages(); } else if (!type.get_dice_emoji().empty()) { sticker_set.is_being_loaded_ = true; } @@ -4053,16 +4068,17 @@ void StickersManager::on_update_sticker_sets() { } void StickersManager::try_update_animated_emoji_messages() { + auto sticker_set = get_animated_emoji_sticker_set(); vector full_message_ids; - /* - for (const auto &it : emoji_messages_) { - if (get_animated_emoji_sticker(sticker_set, it.first).first.is_valid()) { - for (auto full_message_id : it.second) { + for (auto &it : emoji_messages_) { + auto new_animated_sticker = get_animated_emoji_sticker(sticker_set, it.first); + if (new_animated_sticker != it.second.animated_emoji_sticker) { + it.second.animated_emoji_sticker = new_animated_sticker; + for (auto full_message_id : it.second.full_message_ids) { full_message_ids.push_back(full_message_id); } } } - */ for (auto full_message_id : full_message_ids) { td_->messages_manager_->on_external_update_message_content(full_message_id); } @@ -4133,26 +4149,12 @@ void StickersManager::register_emoji(const string &emoji, FullMessageId full_mes } LOG(INFO) << "Register emoji " << emoji << " from " << full_message_id << " from " << source; - bool is_inserted = emoji_messages_[emoji].insert(full_message_id).second; - LOG_CHECK(is_inserted) << source << " " << emoji << " " << full_message_id; - - auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); - bool need_load = false; - if (!special_sticker_set.id_.is_valid()) { - need_load = true; - } else { - auto sticker_set = get_sticker_set(special_sticker_set.id_); - CHECK(sticker_set != nullptr); - need_load = !sticker_set->was_loaded; - } - - if (need_load) { - LOG(INFO) << "Waiting for the animated emoji sticker set needed in " << full_message_id; - load_special_sticker_set(special_sticker_set); - } else { - // TODO reload once in a while - // reload_special_sticker_set(special_sticker_set); + auto &emoji_messages = emoji_messages_[emoji]; + if (emoji_messages.full_message_ids.empty()) { + emoji_messages.animated_emoji_sticker = get_animated_emoji_sticker(emoji); } + bool is_inserted = emoji_messages.full_message_ids.insert(full_message_id).second; + LOG_CHECK(is_inserted) << source << ' ' << emoji << ' ' << full_message_id; } void StickersManager::unregister_emoji(const string &emoji, FullMessageId full_message_id, const char *source) { @@ -4162,12 +4164,14 @@ void StickersManager::unregister_emoji(const string &emoji, FullMessageId full_m } LOG(INFO) << "Unregister emoji " << emoji << " from " << full_message_id << " from " << source; - auto &message_ids = emoji_messages_[emoji]; - auto is_deleted = message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << " " << emoji << " " << full_message_id; + auto it = emoji_messages_.find(emoji); + CHECK(it != emoji_messages_.end()); + auto &full_message_ids = it->second.full_message_ids; + auto is_deleted = full_message_ids.erase(full_message_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << emoji << ' ' << full_message_id; - if (message_ids.empty()) { - emoji_messages_.erase(emoji); + if (full_message_ids.empty()) { + emoji_messages_.erase(it); } } diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 97de82c38..86996699a 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -605,6 +605,8 @@ class StickersManager final : public Actor { static int get_emoji_number(Slice emoji); + const StickerSet *get_animated_emoji_sticker_set(); + static std::pair get_animated_emoji_sticker(const StickerSet *sticker_set, const string &emoji); std::pair get_animated_emoji_sticker(const string &emoji); @@ -809,7 +811,12 @@ class StickersManager final : public Actor { std::unordered_map emoji_suggestions_urls_; std::unordered_map> dice_messages_; - std::unordered_map> emoji_messages_; + + struct EmojiMessages { + std::unordered_set full_message_ids; + std::pair animated_emoji_sticker; + }; + std::unordered_map emoji_messages_; string dice_emojis_str_; vector dice_emojis_; From 9fb1f1438e275aaf2c2b53bef4f6b8155509f0bc Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Oct 2021 18:42:05 +0300 Subject: [PATCH 06/82] Add color replacements to messageAnimatedEmoji. --- td/generate/scheme/td_api.tl | 8 ++++++-- td/telegram/StickersManager.cpp | 30 +++++++++++++++++++++++++++++- td/telegram/StickersManager.h | 4 +++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index fd67640cf..b04d33c7c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -234,6 +234,10 @@ maskPointChin = MaskPoint; maskPosition point:MaskPoint x_shift:double y_shift:double scale:double = MaskPosition; +//@description Describes a color replacement for animated emoji @old_color Original animated emoji color in the RGB24 format @new_color Replacement animated emoji color in the RGB24 format +colorReplacement old_color:int32 new_color:int32 = ColorReplacement; + + //@description Represents a closed vector path. The path begins at the end point of the last command @commands List of vector path commands closedVectorPath commands:vector = ClosedVectorPath; @@ -1707,8 +1711,8 @@ messageVenue venue:venue = MessageContent; //@description A message with a user contact @contact The contact description messageContact contact:contact = MessageContent; -//@description A message with an animated emoji @sticker The animated sticker with the emoji animation @emoji The corresponding emoji -messageAnimatedEmoji sticker:sticker emoji:string = MessageContent; +//@description A message with an animated emoji @sticker The animated sticker with the emoji animation @color_replacements The list of colors to be replaced while the sticker is rendered @emoji The corresponding emoji +messageAnimatedEmoji sticker:sticker color_replacements:vector emoji:string = MessageContent; //@description A dice message. The dice value is randomly generated by the server //@initial_state The animated stickers with the initial dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 2f78ae531..866289620 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1963,13 +1963,41 @@ std::pair StickersManager::get_animated_emoji_sticker(const string return get_animated_emoji_sticker(get_animated_emoji_sticker_set(), emoji); } +vector> StickersManager::get_color_replacements_object( + int fitzpatrick_modifier) { + vector> result; + switch (fitzpatrick_modifier) { + case 0: + break; + case 2: + case 3: + case 4: + case 5: + case 6: { + static int32 old_colors[] = {0xf77e41, 0xffb139, 0xffd140, 0xffdf79}; + static int32 new_colors[] = {0xcb7b55, 0xf6b689, 0xffcda7, 0xffdfc5, 0xa45a38, 0xdf986b, 0xedb183, + 0xf4c3a0, 0x703a17, 0xab673d, 0xc37f4e, 0xd89667, 0x4a2409, 0x7d3e0e, + 0x965529, 0xa96337, 0x200f0a, 0x412924, 0x593d37, 0x63453f}; + for (size_t i = 0; i < 4; i++) { + result.push_back(td_api::make_object(old_colors[i], + new_colors[(fitzpatrick_modifier - 2) * 4 + i])); + } + break; + } + default: + UNREACHABLE(); + } + return result; +} + td_api::object_ptr StickersManager::get_message_content_animated_emoji_object( const string &emoji) { auto it = emoji_messages_.find(emoji); auto animated_sticker = it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji); if (animated_sticker.first.is_valid()) { - return td_api::make_object(get_sticker_object(animated_sticker.first), emoji); + return td_api::make_object( + get_sticker_object(animated_sticker.first), get_color_replacements_object(animated_sticker.second), emoji); } return td_api::make_object( td_api::make_object(emoji, std::vector>()), diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 86996699a..5a79b219b 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -603,7 +603,7 @@ class StickersManager final : public Actor { bool update_sticker_set_cache(const StickerSet *sticker_set, Promise &promise); - static int get_emoji_number(Slice emoji); + static vector> get_color_replacements_object(int fitzpatrick_modifier); const StickerSet *get_animated_emoji_sticker_set(); @@ -613,6 +613,8 @@ class StickersManager final : public Actor { void try_update_animated_emoji_messages(); + static int get_emoji_number(Slice emoji); + vector get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const; void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, Slice message_text, From 038abf546676f1fac52854dfd5cd9fb03c945d19 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 5 Oct 2021 23:20:49 +0300 Subject: [PATCH 07/82] Add sound to messageAnimatedEmoji. --- td/generate/scheme/td_api.tl | 4 +-- td/telegram/ConfigManager.cpp | 44 +++++++++++++++++++++++++ td/telegram/StickersManager.cpp | 57 +++++++++++++++++++++++++++++++-- td/telegram/StickersManager.h | 8 +++++ td/telegram/Td.cpp | 4 ++- tdutils/td/utils/emoji.cpp | 7 ++++ tdutils/td/utils/emoji.h | 3 ++ 7 files changed, 121 insertions(+), 6 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index b04d33c7c..97506ab20 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1711,8 +1711,8 @@ messageVenue venue:venue = MessageContent; //@description A message with a user contact @contact The contact description messageContact contact:contact = MessageContent; -//@description A message with an animated emoji @sticker The animated sticker with the emoji animation @color_replacements The list of colors to be replaced while the sticker is rendered @emoji The corresponding emoji -messageAnimatedEmoji sticker:sticker color_replacements:vector emoji:string = MessageContent; +//@description A message with an animated emoji @emoji The corresponding emoji @sticker Animated sticker with the emoji animation @color_replacements List of colors to be replaced while the sticker is rendered @sound File containing the sound to be played when the animated emoji is clicked if any; may be null +messageAnimatedEmoji emoji:string sticker:sticker color_replacements:vector sound:file = MessageContent; //@description A dice message. The dice value is randomly generated by the server //@initial_state The animated stickers with the initial dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 90ac22b3c..664dc6cb0 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -47,6 +47,7 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/crypto.h" +#include "td/utils/emoji.h" #include "td/utils/format.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" @@ -1478,6 +1479,7 @@ void ConfigManager::process_app_config(tl_object_ptr &c vector dice_emojis; std::unordered_map dice_emoji_index; std::unordered_map dice_emoji_success_value; + vector emoji_sounds; string animation_search_provider; string animation_search_emojis; vector suggested_actions; @@ -1563,6 +1565,46 @@ void ConfigManager::process_app_config(tl_object_ptr &c } continue; } + if (key == "emojies_sounds") { + if (value->get_id() == telegram_api::jsonObject::ID) { + auto sounds = std::move(static_cast(value)->value_); + for (auto &sound : sounds) { + CHECK(sound != nullptr); + if (sound->value_->get_id() == telegram_api::jsonObject::ID) { + string id; + string access_hash; + string file_reference_base64; + for (auto &sound_key_value : static_cast(sound->value_.get())->value_) { + if (sound_key_value->value_->get_id() != telegram_api::jsonString::ID) { + continue; + } + auto current_value = get_json_value_string(std::move(sound_key_value->value_), Slice()); + if (sound_key_value->key_ == "id") { + id = std::move(current_value); + } + if (sound_key_value->key_ == "access_hash") { + access_hash = std::move(current_value); + } + if (sound_key_value->key_ == "file_reference_base64") { + file_reference_base64 = std::move(current_value); + } + } + if (to_integer_safe(id).is_error() || to_integer_safe(access_hash).is_error() || + !is_base64url(file_reference_base64) || !is_emoji(sound->key_)) { + LOG(ERROR) << "Receive unexpected sound value " << to_string(sound); + } else { + emoji_sounds.push_back(sound->key_); + emoji_sounds.push_back(PSTRING() << id << ':' << access_hash << ':' << file_reference_base64); + } + } else { + LOG(ERROR) << "Receive unexpected emoji sound " << to_string(sound); + } + } + } else { + LOG(ERROR) << "Receive unexpected emojies_sounds " << to_string(*value); + } + continue; + } if (key == "gif_search_branding") { animation_search_provider = get_json_value_string(std::move(key_value->value_), "gif_search_branding"); continue; @@ -1722,6 +1764,8 @@ void ConfigManager::process_app_config(tl_object_ptr &c shared_config.set_option_string("dice_emojis", implode(dice_emojis, '\x01')); } + shared_config.set_option_string("emoji_sounds", implode(emoji_sounds, ',')); + if (animation_search_provider.empty()) { shared_config.set_option_empty("animation_search_provider"); } else { diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 866289620..ae1a65516 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -46,6 +46,7 @@ #include "td/utils/format.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" +#include "td/utils/MimeType.h" #include "td/utils/misc.h" #include "td/utils/PathView.h" #include "td/utils/Random.h" @@ -1279,6 +1280,8 @@ void StickersManager::init() { on_update_dice_success_values(); + on_update_emoji_sounds(); + on_update_disable_animated_emojis(); if (!disable_animated_emojis_) { @@ -1963,6 +1966,14 @@ std::pair StickersManager::get_animated_emoji_sticker(const string return get_animated_emoji_sticker(get_animated_emoji_sticker_set(), emoji); } +FileId StickersManager::get_animated_emoji_sound_file_id(const string &emoji) const { + auto it = emoji_sounds_.find(remove_fitzpatrick_modifier(emoji).str()); + if (it == emoji_sounds_.end()) { + return {}; + } + return it->second; +} + vector> StickersManager::get_color_replacements_object( int fitzpatrick_modifier) { vector> result; @@ -1996,8 +2007,11 @@ td_api::object_ptr StickersManager::get_message_content_ auto animated_sticker = it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji); if (animated_sticker.first.is_valid()) { + auto sound_file_id = + it != emoji_messages_.end() ? it->second.sound_file_id : get_animated_emoji_sound_file_id(emoji); return td_api::make_object( - get_sticker_object(animated_sticker.first), get_color_replacements_object(animated_sticker.second), emoji); + emoji, get_sticker_object(animated_sticker.first), get_color_replacements_object(animated_sticker.second), + sound_file_id.is_valid() ? td_->file_manager_->get_file_object(sound_file_id) : nullptr); } return td_api::make_object( td_api::make_object(emoji, std::vector>()), @@ -4068,8 +4082,41 @@ void StickersManager::on_update_dice_success_values() { }); } +void StickersManager::on_update_emoji_sounds() { + if (G()->close_flag() || !is_inited_ || td_->auth_manager_->is_bot()) { + return; + } + + auto emoji_sounds_str = G()->shared_config().get_option_string("emoji_sounds"); + if (emoji_sounds_str == emoji_sounds_str_) { + return; + } + + LOG(INFO) << "Change emoji sounds to " << emoji_sounds_str; + emoji_sounds_str_ = std::move(emoji_sounds_str); + + emoji_sounds_.clear(); + auto sounds = full_split(Slice(emoji_sounds_str_), ','); + CHECK(sounds.size() % 2 == 0); + for (size_t i = 0; i < sounds.size(); i += 2) { + vector parts = full_split(sounds[i + 1], ':'); + CHECK(parts.size() == 3); + auto id = to_integer(parts[0]); + auto access_hash = to_integer(parts[1]); + auto file_reference = base64url_decode(parts[2]).move_as_ok(); + auto suggested_file_name = PSTRING() << static_cast(id) << '.' + << MimeType::to_extension("audio/ogg", "oga"); + auto file_id = td_->file_manager_->register_remote( + FullRemoteFileLocation(FileType::VoiceNote, id, access_hash, DcId::internal(2), std::move(file_reference)), + FileLocationSource::FromServer, DialogId(), 0, 0, std::move(suggested_file_name)); + CHECK(file_id.is_valid()); + emoji_sounds_.emplace(remove_fitzpatrick_modifier(sounds[i]).str(), file_id); + } + try_update_animated_emoji_messages(); +} + void StickersManager::on_update_disable_animated_emojis() { - if (G()->close_flag() || td_->auth_manager_->is_bot() || !is_inited_) { + if (G()->close_flag() || !is_inited_ || td_->auth_manager_->is_bot()) { return; } @@ -4100,8 +4147,11 @@ void StickersManager::try_update_animated_emoji_messages() { vector full_message_ids; for (auto &it : emoji_messages_) { auto new_animated_sticker = get_animated_emoji_sticker(sticker_set, it.first); - if (new_animated_sticker != it.second.animated_emoji_sticker) { + auto new_sound_file_id = get_animated_emoji_sound_file_id(it.first); + if (new_animated_sticker != it.second.animated_emoji_sticker || + (new_animated_sticker.first.is_valid() && new_sound_file_id != it.second.sound_file_id)) { it.second.animated_emoji_sticker = new_animated_sticker; + it.second.sound_file_id = new_sound_file_id; for (auto full_message_id : it.second.full_message_ids) { full_message_ids.push_back(full_message_id); } @@ -4180,6 +4230,7 @@ void StickersManager::register_emoji(const string &emoji, FullMessageId full_mes auto &emoji_messages = emoji_messages_[emoji]; if (emoji_messages.full_message_ids.empty()) { emoji_messages.animated_emoji_sticker = get_animated_emoji_sticker(emoji); + emoji_messages.sound_file_id = get_animated_emoji_sound_file_id(emoji); } bool is_inserted = emoji_messages.full_message_ids.insert(full_message_id).second; LOG_CHECK(is_inserted) << source << ' ' << emoji << ' ' << full_message_id; diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 5a79b219b..387591b62 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -154,6 +154,8 @@ class StickersManager final : public Actor { void on_update_dice_success_values(); + void on_update_emoji_sounds(); + void on_update_sticker_sets(); void on_update_sticker_sets_order(bool is_masks, const vector &sticker_set_ids); @@ -611,6 +613,8 @@ class StickersManager final : public Actor { std::pair get_animated_emoji_sticker(const string &emoji); + FileId get_animated_emoji_sound_file_id(const string &emoji) const; + void try_update_animated_emoji_messages(); static int get_emoji_number(Slice emoji); @@ -817,6 +821,7 @@ class StickersManager final : public Actor { struct EmojiMessages { std::unordered_set full_message_ids; std::pair animated_emoji_sticker; + FileId sound_file_id; }; std::unordered_map emoji_messages_; @@ -826,6 +831,9 @@ class StickersManager final : public Actor { string dice_success_values_str_; vector> dice_success_values_; + string emoji_sounds_str_; + std::unordered_map emoji_sounds_; + bool disable_animated_emojis_ = false; }; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d741605d0..6bf50bd1a 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3275,7 +3275,7 @@ bool Td::is_internal_config_option(Slice name) { case 'd': return name == "dc_txt_domain_name" || name == "dice_emojis" || name == "dice_success_values"; case 'e': - return name == "edit_time_limit"; + return name == "edit_time_limit" || name == "emoji_sounds"; case 'i': return name == "ignored_restriction_reasons"; case 'l': @@ -3377,6 +3377,8 @@ void Td::on_config_option_updated(const string &name) { return send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_emojis); } else if (name == "dice_success_values") { return send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_success_values); + } else if (name == "emoji_sounds") { + return send_closure(stickers_manager_actor_, &StickersManager::on_update_emoji_sounds); } else if (is_internal_config_option(name)) { return; } diff --git a/tdutils/td/utils/emoji.cpp b/tdutils/td/utils/emoji.cpp index 37ce7743e..6243c8996 100644 --- a/tdutils/td/utils/emoji.cpp +++ b/tdutils/td/utils/emoji.cpp @@ -851,6 +851,13 @@ int get_fitzpatrick_modifier(Slice emoji) { return (c - 0xBB) + 2; } +Slice remove_fitzpatrick_modifier(Slice emoji) { + while (get_fitzpatrick_modifier(emoji) != 0) { + emoji.remove_suffix(4); + } + return emoji; +} + Slice remove_emoji_modifiers(Slice emoji) { static const Slice modifiers[] = {u8"\uFE0E" /* variation selector-15 */, u8"\uFE0F" /* variation selector-16 */, diff --git a/tdutils/td/utils/emoji.h b/tdutils/td/utils/emoji.h index 89018cb1a..f23084eef 100644 --- a/tdutils/td/utils/emoji.h +++ b/tdutils/td/utils/emoji.h @@ -17,6 +17,9 @@ bool is_emoji(Slice str); // checks whether emoji ends on a Fitzpatrick modifier and returns it's number or 0 int get_fitzpatrick_modifier(Slice emoji); +// removes all Fitzpatrick modifier from the end of the string +Slice remove_fitzpatrick_modifier(Slice emoji); + // removes all emoji modifiers from the end of the string Slice remove_emoji_modifiers(Slice emoji); From 6ecba8cb5dc260f834de2d01aa0611982497a526 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 6 Oct 2021 00:55:22 +0300 Subject: [PATCH 08/82] Download emoji sounds from main DC. --- td/telegram/ConfigManager.cpp | 2 +- td/telegram/StickersManager.cpp | 7 +++++-- td/telegram/net/ConnectionCreator.cpp | 4 ++-- td/telegram/net/NetQueryDispatcher.h | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 664dc6cb0..738dbc38a 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -1319,7 +1319,7 @@ void ConfigManager::save_config_expire(Timestamp timestamp) { } void ConfigManager::process_config(tl_object_ptr config) { - bool is_from_main_dc = G()->net_query_dispatcher().main_dc_id().get_value() == config->this_dc_; + bool is_from_main_dc = G()->net_query_dispatcher().get_main_dc_id().get_value() == config->this_dc_; LOG(INFO) << to_string(config); auto reload_in = clamp(config->expires_ - config->date_, 60, 86400); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index ae1a65516..fbafafdc3 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -25,6 +25,7 @@ #include "td/telegram/misc.h" #include "td/telegram/net/DcId.h" #include "td/telegram/net/MtprotoHeader.h" +#include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/secret_api.h" #include "td/telegram/StickerSetId.hpp" #include "td/telegram/StickersManager.hpp" @@ -4103,12 +4104,14 @@ void StickersManager::on_update_emoji_sounds() { CHECK(parts.size() == 3); auto id = to_integer(parts[0]); auto access_hash = to_integer(parts[1]); + auto dc_id = G()->net_query_dispatcher().get_main_dc_id(); auto file_reference = base64url_decode(parts[2]).move_as_ok(); + int32 expected_size = 7000; auto suggested_file_name = PSTRING() << static_cast(id) << '.' << MimeType::to_extension("audio/ogg", "oga"); auto file_id = td_->file_manager_->register_remote( - FullRemoteFileLocation(FileType::VoiceNote, id, access_hash, DcId::internal(2), std::move(file_reference)), - FileLocationSource::FromServer, DialogId(), 0, 0, std::move(suggested_file_name)); + FullRemoteFileLocation(FileType::VoiceNote, id, access_hash, dc_id, std::move(file_reference)), + FileLocationSource::FromServer, DialogId(), 0, expected_size, std::move(suggested_file_name)); CHECK(file_id.is_valid()); emoji_sounds_.emplace(remove_fitzpatrick_modifier(sounds[i]).str(), file_id); } diff --git a/td/telegram/net/ConnectionCreator.cpp b/td/telegram/net/ConnectionCreator.cpp index 0e696ca29..79bbd927b 100644 --- a/td/telegram/net/ConnectionCreator.cpp +++ b/td/telegram/net/ConnectionCreator.cpp @@ -295,7 +295,7 @@ ActorId ConnectionCreator::get_dns_resolver() { void ConnectionCreator::ping_proxy(int32 proxy_id, Promise promise) { CHECK(!close_flag_); if (proxy_id == 0) { - auto main_dc_id = G()->net_query_dispatcher().main_dc_id(); + auto main_dc_id = G()->net_query_dispatcher().get_main_dc_id(); bool prefer_ipv6 = G()->shared_config().get_option_boolean("prefer_ipv6"); auto infos = dc_options_set_.find_all_connections(main_dc_id, false, false, prefer_ipv6, false); if (infos.empty()) { @@ -361,7 +361,7 @@ void ConnectionCreator::ping_proxy_resolved(int32 proxy_id, IPAddress ip_address return promise.set_error(Status::Error(400, "Unknown proxy identifier")); } const Proxy &proxy = it->second; - auto main_dc_id = G()->net_query_dispatcher().main_dc_id(); + auto main_dc_id = G()->net_query_dispatcher().get_main_dc_id(); FindConnectionExtra extra; auto r_socket_fd = find_connection(proxy, ip_address, main_dc_id, false, extra); if (r_socket_fd.is_error()) { diff --git a/td/telegram/net/NetQueryDispatcher.h b/td/telegram/net/NetQueryDispatcher.h index e65a9fc32..673a1955d 100644 --- a/td/telegram/net/NetQueryDispatcher.h +++ b/td/telegram/net/NetQueryDispatcher.h @@ -52,8 +52,8 @@ class NetQueryDispatcher { void update_valid_dc(DcId dc_id); - DcId main_dc_id() const { - return DcId::internal(main_dc_id_.load()); + DcId get_main_dc_id() const { + return DcId::internal(main_dc_id_.load(std::memory_order_relaxed)); } void set_main_dc_id(int32 new_main_dc_id); From c3d898f1e65b82ce81d2a9ef0a5889e242aa14d1 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 6 Oct 2021 01:17:10 +0300 Subject: [PATCH 09/82] Add ConfigManager::reget_app_config. --- td/telegram/ConfigManager.cpp | 56 ++++++++++++++++++++++----------- td/telegram/ConfigManager.h | 5 +++ td/telegram/LinkManager.cpp | 16 +++++----- td/telegram/StickersManager.cpp | 3 +- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 738dbc38a..1b309c81e 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -960,6 +960,16 @@ void ConfigManager::lazy_request_config() { set_timeout_at(expire_time_.at()); } +void ConfigManager::try_request_app_config() { + if (get_app_config_queries_.size() + reget_app_config_queries_.size() != 1) { + return; + } + + auto query = G()->net_query_creator().create_unauth(telegram_api::help_getAppConfig()); + query->total_timeout_limit_ = 60 * 60 * 24; + G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, 1)); +} + void ConfigManager::get_app_config(Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); @@ -969,11 +979,21 @@ void ConfigManager::get_app_config(Promise } get_app_config_queries_.push_back(std::move(promise)); - if (get_app_config_queries_.size() == 1) { - auto query = G()->net_query_creator().create_unauth(telegram_api::help_getAppConfig()); - query->total_timeout_limit_ = 60 * 60 * 24; - G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, 1)); + try_request_app_config(); +} + +void ConfigManager::reget_app_config(Promise &&promise) { + if (G()->close_flag()) { + return promise.set_error(Status::Error(500, "Request aborted")); } + + auto auth_manager = G()->td().get_actor_unsafe()->auth_manager_.get(); + if (auth_manager != nullptr && auth_manager->is_bot()) { + return promise.set_value(Unit()); + } + + reget_app_config_queries_.push_back(std::move(promise)); + try_request_app_config(); } void ConfigManager::get_content_settings(Promise &&promise) { @@ -1066,7 +1086,7 @@ void ConfigManager::do_set_ignore_sensitive_content_restrictions(bool ignore_sen ignore_sensitive_content_restrictions); bool have_ignored_restriction_reasons = G()->shared_config().have_option("ignored_restriction_reasons"); if (have_ignored_restriction_reasons != ignore_sensitive_content_restrictions) { - get_app_config(Auto()); + reget_app_config(Auto()); } } @@ -1122,7 +1142,7 @@ void ConfigManager::on_result(NetQueryPtr res) { return; } remove_suggested_action(suggested_actions_, suggested_action); - get_app_config(Auto()); + reget_app_config(Auto()); for (auto &promise : promises) { promise.set_value(Unit()); @@ -1246,15 +1266,16 @@ void ConfigManager::on_result(NetQueryPtr res) { if (token == 1) { auto promises = std::move(get_app_config_queries_); get_app_config_queries_.clear(); - CHECK(!promises.empty()); + auto unit_promises = std::move(reget_app_config_queries_); + reget_app_config_queries_.clear(); + CHECK(!promises.empty() || !unit_promises.empty()); auto result_ptr = fetch_result(std::move(res)); if (result_ptr.is_error()) { for (auto &promise : promises) { - if (!promise) { - promise.set_value(nullptr); - } else { - promise.set_error(result_ptr.error().clone()); - } + promise.set_error(result_ptr.error().clone()); + } + for (auto &promise : unit_promises) { + promise.set_error(result_ptr.error().clone()); } return; } @@ -1262,11 +1283,10 @@ void ConfigManager::on_result(NetQueryPtr res) { auto result = result_ptr.move_as_ok(); process_app_config(result); for (auto &promise : promises) { - if (!promise) { - promise.set_value(nullptr); - } else { - promise.set_value(convert_json_value_object(result)); - } + promise.set_value(convert_json_value_object(result)); + } + for (auto &promise : unit_promises) { + promise.set_value(Unit()); } return; } @@ -1452,7 +1472,7 @@ void ConfigManager::process_config(tl_object_ptr config) { // shared_config.set_option_integer("push_chat_limit", config->push_chat_limit_); if (is_from_main_dc) { - get_app_config(Auto()); + reget_app_config(Auto()); if (!shared_config.have_option("can_ignore_sensitive_content_restrictions") || !shared_config.have_option("ignore_sensitive_content_restrictions")) { get_content_settings(Auto()); diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index 532719630..6e868d415 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -88,6 +88,8 @@ class ConfigManager final : public NetQueryCallback { void get_app_config(Promise> &&promise); + void reget_app_config(Promise &&promise); + void get_content_settings(Promise &&promise); void set_content_settings(bool ignore_sensitive_content_restrictions, Promise &&promise); @@ -114,6 +116,7 @@ class ConfigManager final : public NetQueryCallback { FloodControlStrict lazy_request_flood_control_; vector>> get_app_config_queries_; + vector> reget_app_config_queries_; vector> get_content_settings_queries_; vector> set_content_settings_queries_[2]; @@ -142,6 +145,8 @@ class ConfigManager final : public NetQueryCallback { void request_config_from_dc_impl(DcId dc_id); void process_config(tl_object_ptr config); + void try_request_app_config(); + void process_app_config(tl_object_ptr &config); void do_set_ignore_sensitive_content_restrictions(bool ignore_sensitive_content_restrictions); diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 8aea83355..b314f6ce6 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -1156,14 +1156,14 @@ void LinkManager::get_external_link_info(string &&link, Promise> &&result) mutable { - if (result.is_error()) { - return promise.set_value(td_api::make_object(link, false)); - } - send_closure(G()->link_manager(), &LinkManager::get_external_link_info, std::move(link), std::move(promise)); - }); - return send_closure(G()->config_manager(), &ConfigManager::get_app_config, std::move(query_promise)); + auto query_promise = + PromiseCreator::lambda([link = std::move(link), promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + return promise.set_value(td_api::make_object(link, false)); + } + send_closure(G()->link_manager(), &LinkManager::get_external_link_info, std::move(link), std::move(promise)); + }); + return send_closure(G()->config_manager(), &ConfigManager::reget_app_config, std::move(query_promise)); } if (autologin_token_.empty()) { diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index fbafafdc3..8c8ca210e 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -4180,8 +4180,7 @@ void StickersManager::register_dice(const string &emoji, int32 value, FullMessag if (!td::contains(dice_emojis_, emoji)) { if (full_message_id.get_message_id().is_any_server() && full_message_id.get_dialog_id().get_type() != DialogType::SecretChat) { - send_closure(G()->config_manager(), &ConfigManager::get_app_config, - Promise>()); + send_closure(G()->config_manager(), &ConfigManager::reget_app_config, Promise()); } return; } From 0259ee826224e4d9cc131c9826b785725bdbc411 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 6 Oct 2021 01:55:35 +0300 Subject: [PATCH 10/82] Improve documentation. --- td/generate/scheme/td_api.tl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 97506ab20..ba04801f8 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1711,7 +1711,11 @@ messageVenue venue:venue = MessageContent; //@description A message with a user contact @contact The contact description messageContact contact:contact = MessageContent; -//@description A message with an animated emoji @emoji The corresponding emoji @sticker Animated sticker with the emoji animation @color_replacements List of colors to be replaced while the sticker is rendered @sound File containing the sound to be played when the animated emoji is clicked if any; may be null +//@description A message with an animated emoji +//@emoji The corresponding emoji +//@sticker Animated sticker with the emoji animation +//@color_replacements List of colors to be replaced while the sticker is rendered +//@sound File containing the sound to be played when the animated emoji is clicked if any; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container messageAnimatedEmoji emoji:string sticker:sticker color_replacements:vector sound:file = MessageContent; //@description A dice message. The dice value is randomly generated by the server From f70498898bc5e046686c052fe89cbbbef819a75b Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 8 Oct 2021 13:41:22 +0300 Subject: [PATCH 11/82] Add fileSourceAppConfig. --- td/telegram/FileReferenceManager.cpp | 10 ++++++++++ td/telegram/FileReferenceManager.h | 6 +++++- td/telegram/FileReferenceManager.hpp | 5 ++++- td/telegram/StickersManager.cpp | 16 ++++++++++++++++ td/telegram/StickersManager.h | 4 ++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index a5382f3bf..51ea1394d 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -8,6 +8,7 @@ #include "td/telegram/AnimationsManager.h" #include "td/telegram/BackgroundManager.h" +#include "td/telegram/ConfigManager.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/Global.h" @@ -58,6 +59,7 @@ fileSourceFavoriteStickers = FileSource; // repa fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repaired with account.getWallPaper fileSourceBasicGroupFull basic_group_id:int32 = FileSource; // repaired with messages.getFullChat fileSourceSupergroupFull supergroup_id:int32 = FileSource; // repaired with messages.getFullChannel +fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable */ FileSourceId FileReferenceManager::get_current_file_source_id() const { @@ -117,6 +119,11 @@ FileSourceId FileReferenceManager::create_channel_full_file_source(ChannelId cha return add_file_source_id(source, PSLICE() << "full " << channel_id); } +FileSourceId FileReferenceManager::create_app_config_file_source() { + FileSourceAppConfig source; + return add_file_source_id(source, "app config"); +} + bool FileReferenceManager::add_file_source(NodeId node_id, FileSourceId file_source_id) { bool is_added = nodes_[node_id].file_source_ids.add(file_source_id); VLOG(file_references) << "Add " << (is_added ? "new" : "old") << ' ' << file_source_id << " for file " << node_id; @@ -290,6 +297,9 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source [&](const FileSourceChannelFull &source) { send_closure_later(G()->contacts_manager(), &ContactsManager::reload_channel_full, source.channel_id, std::move(promise), "repair file reference"); + }, + [&](const FileSourceAppConfig &source) { + send_closure_later(G()->config_manager(), &ConfigManager::reget_app_config, std::move(promise)); })); } diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index dc9234966..980df045d 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -51,6 +51,7 @@ class FileReferenceManager final : public Actor { FileSourceId create_background_file_source(BackgroundId background_id, int64 access_hash); FileSourceId create_chat_full_file_source(ChatId chat_id); FileSourceId create_channel_full_file_source(ChannelId channel_id); + FileSourceId create_app_config_file_source(); using NodeId = FileId; void repair_file_reference(NodeId node_id, Promise<> promise); @@ -132,12 +133,15 @@ class FileReferenceManager final : public Actor { struct FileSourceChannelFull { ChannelId channel_id; }; + struct FileSourceAppConfig { + // empty + }; // append only using FileSource = Variant; + FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig>; vector file_sources_; int64 query_generation_{0}; diff --git a/td/telegram/FileReferenceManager.hpp b/td/telegram/FileReferenceManager.hpp index 7923f7439..516d73d73 100644 --- a/td/telegram/FileReferenceManager.hpp +++ b/td/telegram/FileReferenceManager.hpp @@ -49,7 +49,8 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer td::store(source.access_hash, storer); }, [&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); }, - [&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); })); + [&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); }, + [&](const FileSourceAppConfig &source) {})); } template @@ -111,6 +112,8 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) { td::parse(channel_id, parser); return td->contacts_manager_->get_channel_full_file_source_id(channel_id); } + case 12: + return td->stickers_manager_->get_app_config_file_source_id(); default: parser.set_error("Invalid type in FileSource"); return FileSourceId(); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 8c8ca210e..0d6f72ef2 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -4096,7 +4096,13 @@ void StickersManager::on_update_emoji_sounds() { LOG(INFO) << "Change emoji sounds to " << emoji_sounds_str; emoji_sounds_str_ = std::move(emoji_sounds_str); + vector old_file_ids; + for (auto &emoji_sound : emoji_sounds_) { + old_file_ids.push_back(emoji_sound.second); + } emoji_sounds_.clear(); + + vector new_file_ids; auto sounds = full_split(Slice(emoji_sounds_str_), ','); CHECK(sounds.size() % 2 == 0); for (size_t i = 0; i < sounds.size(); i += 2) { @@ -4114,7 +4120,10 @@ void StickersManager::on_update_emoji_sounds() { FileLocationSource::FromServer, DialogId(), 0, expected_size, std::move(suggested_file_name)); CHECK(file_id.is_valid()); emoji_sounds_.emplace(remove_fitzpatrick_modifier(sounds[i]).str(), file_id); + new_file_ids.push_back(file_id); } + td_->file_manager_->change_files_source(get_app_config_file_source_id(), old_file_ids, new_file_ids); + try_update_animated_emoji_messages(); } @@ -6610,6 +6619,13 @@ int64 StickersManager::get_favorite_stickers_hash() const { return get_recent_stickers_hash(favorite_sticker_ids_); } +FileSourceId StickersManager::get_app_config_file_source_id() { + if (!app_config_file_source_id_.is_valid()) { + app_config_file_source_id_ = td_->file_reference_manager_->create_app_config_file_source(); + } + return app_config_file_source_id_; +} + FileSourceId StickersManager::get_favorite_stickers_file_source_id() { if (!favorite_stickers_file_source_id_.is_valid()) { favorite_stickers_file_source_id_ = td_->file_reference_manager_->create_favorite_stickers_file_source(); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 387591b62..d732aaea5 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -241,6 +241,8 @@ class StickersManager final : public Actor { void on_get_favorite_stickers_failed(bool is_repair, Status error); + FileSourceId get_app_config_file_source_id(); + FileSourceId get_favorite_stickers_file_source_id(); vector get_favorite_stickers(Promise &&promise); @@ -747,6 +749,8 @@ class StickersManager final : public Actor { vector favorite_sticker_file_ids_; FileSourceId favorite_stickers_file_source_id_; + FileSourceId app_config_file_source_id_; + vector archived_sticker_set_ids_[2]; int32 total_archived_sticker_set_count_[2] = {-1, -1}; From 23775700acae6f0bf463bb85ec8106f709ccb22e Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 8 Oct 2021 13:45:10 +0300 Subject: [PATCH 12/82] Update layer to 134. --- td/generate/scheme/telegram_api.tl | 52 +++++++------ td/telegram/ContactsManager.cpp | 12 +-- td/telegram/MessageContent.cpp | 2 + td/telegram/MessagesManager.cpp | 4 +- td/telegram/ThemeManager.cpp | 117 ++++++++++++++++++++--------- td/telegram/ThemeManager.h | 9 ++- td/telegram/UpdatesManager.cpp | 16 ++-- td/telegram/UpdatesManager.h | 4 + td/telegram/Version.h | 2 +- 9 files changed, 145 insertions(+), 73 deletions(-) diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index d377bea7a..d66485596 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -118,8 +118,8 @@ chatForbidden#6592a1a7 id:long title:string = Chat; channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; -chatFull#4dbdc099 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string = ChatFull; -channelFull#e9b27a17 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string = ChatFull; +chatFull#46a6ffb4 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector = ChatFull; +channelFull#59cff963 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -178,6 +178,7 @@ messageActionInviteToGroupCall#502f92f7 call:InputGroupCall users:Vector = messageActionSetMessagesTTL#aa1afbfd period:int = MessageAction; messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction; messageActionSetChatTheme#aa786345 emoticon:string = MessageAction; +messageActionChatJoinedByRequest#ebbca3cb = 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; @@ -368,6 +369,8 @@ updateChannelParticipant#985d3abb flags:# channel_id:long date:int actor_id:long updateBotStopped#c4870a49 user_id:long date:int stopped:Bool qts:int = Update; updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJSON = Update; updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector = Update; +updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector = Update; +updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -539,10 +542,10 @@ auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery; receivedNotifyMessage#a384b779 id:int flags:int = ReceivedNotifyMessage; -chatInviteExported#b18105e8 flags:# revoked:flags.0?true permanent:flags.5?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int = ExportedChatInvite; +chatInviteExported#ab4a819 flags:# revoked:flags.0?true permanent:flags.5?true request_needed:flags.6?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int requested:flags.7?int title:flags.8?string = ExportedChatInvite; chatInviteAlready#5a686d7c chat:Chat = ChatInvite; -chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector = ChatInvite; +chatInvite#300c44c1 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector = ChatInvite; chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite; inputStickerSetEmpty#ffb62b95 = InputStickerSet; @@ -615,7 +618,7 @@ channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter; channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector = ChannelMessagesFilter; channelParticipant#c00c07c0 user_id:long date:int = ChannelParticipant; -channelParticipantSelf#28a8bc67 user_id:long inviter_id:long date:int = ChannelParticipant; +channelParticipantSelf#35a8bfa7 flags:# via_invite:flags.0?true user_id:long inviter_id:long date:int = ChannelParticipant; channelParticipantCreator#2fe601d3 flags:# user_id:long admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant; channelParticipantAdmin#34c3bb53 flags:# can_edit:flags.0?true self:flags.1?true user_id:long inviter_id:flags.1?long promoted_by:long date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant; channelParticipantBanned#6df8014e flags:# left:flags.0?true peer:Peer kicked_by:long date:int banned_rights:ChatBannedRights = ChannelParticipant; @@ -898,6 +901,7 @@ channelAdminLogEventActionExportedInviteRevoke#410a134e invite:ExportedChatInvit channelAdminLogEventActionExportedInviteEdit#e90ebb59 prev_invite:ExportedChatInvite new_invite:ExportedChatInvite = ChannelAdminLogEventAction; channelAdminLogEventActionParticipantVolume#3e7f6847 participant:GroupCallParticipant = ChannelAdminLogEventAction; channelAdminLogEventActionChangeHistoryTTL#6e941a38 prev_value:int new_value:int = ChannelAdminLogEventAction; +channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatInvite approved_by:long = ChannelAdminLogEventAction; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; @@ -1112,7 +1116,7 @@ restrictionReason#d072acb4 platform:string reason:string text:string = Restricti inputTheme#3c5693e9 id:long access_hash:long = InputTheme; inputThemeSlug#f5890df1 slug:string = InputTheme; -theme#e802b8dc flags:# creator:flags.0?true default:flags.1?true for_chat:flags.5?true id:long access_hash:long slug:string title:string document:flags.2?Document settings:flags.3?ThemeSettings installs_count:flags.4?int = Theme; +theme#a00e67d6 flags:# creator:flags.0?true default:flags.1?true for_chat:flags.5?true id:long access_hash:long slug:string title:string document:flags.2?Document settings:flags.3?Vector emoticon:flags.6?string installs_count:flags.4?int = Theme; account.themesNotModified#f41eb622 = account.Themes; account.themes#9a3d8c6d hash:long themes:Vector = account.Themes; @@ -1224,7 +1228,7 @@ messages.historyImportParsed#5e0fb7b9 flags:# pm:flags.0?true group:flags.1?true messages.affectedFoundMessages#ef8d3e6c pts:int pts_count:int offset:int messages:Vector = messages.AffectedFoundMessages; -chatInviteImporter#b5cd5f4 user_id:long date:int = ChatInviteImporter; +chatInviteImporter#8c5adfd9 flags:# requested:flags.0?true user_id:long date:int about:flags.2?string approved_by:flags.1?long = ChatInviteImporter; messages.exportedChatInvites#bdc62dcc count:int invites:Vector users:Vector = messages.ExportedChatInvites; @@ -1261,15 +1265,18 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult; account.resetPasswordOk#e926d63e = account.ResetPasswordResult; -chatTheme#ed0b5c33 emoticon:string theme:Theme dark_theme:Theme = ChatTheme; - -account.chatThemesNotModified#e011e1c4 = account.ChatThemes; -account.chatThemes#fe4cbebd hash:int themes:Vector = account.ChatThemes; - -sponsoredMessage#2a3c381f flags:# random_id:bytes from_id:Peer start_param:flags.0?string message:string entities:flags.1?Vector = SponsoredMessage; +sponsoredMessage#d151e19a flags:# random_id:bytes from_id:Peer channel_post:flags.2?int start_param:flags.0?string message:string entities:flags.1?Vector = SponsoredMessage; messages.sponsoredMessages#65a4c7d5 messages:Vector chats:Vector users:Vector = messages.SponsoredMessages; +searchResultsCalendarPeriod#c9b0539f date:int min_msg_id:int max_msg_id:int count:int = SearchResultsCalendarPeriod; + +messages.searchResultsCalendar#147ee23c flags:# inexact:flags.0?true count:int min_date:int min_msg_id:int offset_id_offset:flags.1?int periods:Vector messages:Vector chats:Vector users:Vector = messages.SearchResultsCalendar; + +searchResultPosition#7f648b67 msg_id:int date:int offset:int = SearchResultsPosition; + +messages.searchResultsPositions#53b22baf count:int positions:Vector = messages.SearchResultsPositions; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1356,10 +1363,10 @@ account.resetWallPapers#bb3b9804 = Bool; account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings; account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool; account.uploadTheme#1c3db333 flags:# file:InputFile thumb:flags.0?InputFile file_name:string mime_type:string = Document; -account.createTheme#8432c21f flags:# slug:string title:string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = Theme; -account.updateTheme#5cb367d5 flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = Theme; +account.createTheme#652e4400 flags:# slug:string title:string document:flags.2?InputDocument settings:flags.3?Vector = Theme; +account.updateTheme#2bf40ccc flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?Vector = Theme; account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool; -account.installTheme#7ae43737 flags:# dark:flags.0?true format:flags.1?string theme:flags.1?InputTheme = Bool; +account.installTheme#c727bb3b flags:# dark:flags.0?true theme:flags.1?InputTheme format:flags.2?string base_theme:flags.3?BaseTheme = Bool; account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme; account.getThemes#7206e458 format:string hash:long = account.Themes; account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool; @@ -1370,7 +1377,7 @@ account.setGlobalPrivacySettings#1edaaac2 settings:GlobalPrivacySettings = Globa account.reportProfilePhoto#fa8cc6f5 peer:InputPeer photo_id:InputPhoto reason:ReportReason message:string = Bool; account.resetPassword#9308ce1b = account.ResetPasswordResult; account.declinePasswordReset#4c9409f6 = Bool; -account.getChatThemes#d6d71d7b hash:int = account.ChatThemes; +account.getChatThemes#d638de89 hash:long = account.Themes; users.getUsers#d91a548 id:Vector = Vector; users.getFullUser#ca30a5b1 id:InputUser = UserFull; @@ -1402,7 +1409,7 @@ messages.getDialogs#a0f4cb4f flags:# exclude_pinned:flags.0?true folder_id:flags messages.getHistory#4423e6c5 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages; messages.search#a0fda762 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:long = 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.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory; messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; @@ -1434,7 +1441,7 @@ messages.readMessageContents#36a73f77 id:Vector = messages.AffectedMessages messages.getStickers#d5a5d3a1 emoticon:string hash:long = messages.Stickers; messages.getAllStickers#b8a0a1a8 hash:long = messages.AllStickers; messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector = MessageMedia; -messages.exportChatInvite#14b9bcd7 flags:# legacy_revoke_permanent:flags.2?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int = ExportedChatInvite; +messages.exportChatInvite#a02ce5d5 flags:# legacy_revoke_permanent:flags.2?true request_needed:flags.3?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int title:flags.4?string = ExportedChatInvite; messages.checkChatInvite#3eadb1bb hash:string = ChatInvite; messages.importChatInvite#6c50051c hash:string = Updates; messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet; @@ -1531,15 +1538,18 @@ messages.uploadImportedMedia#2a862092 peer:InputPeer import_id:long file_name:st messages.startHistoryImport#b43df344 peer:InputPeer import_id:long = Bool; messages.getExportedChatInvites#a2b5a3f6 flags:# revoked:flags.3?true peer:InputPeer admin_id:InputUser offset_date:flags.2?int offset_link:flags.2?string limit:int = messages.ExportedChatInvites; messages.getExportedChatInvite#73746f5c peer:InputPeer link:string = messages.ExportedChatInvite; -messages.editExportedChatInvite#2e4ffbe flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int = messages.ExportedChatInvite; +messages.editExportedChatInvite#bdca2f75 flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int request_needed:flags.3?Bool title:flags.4?string = messages.ExportedChatInvite; messages.deleteRevokedExportedChatInvites#56987bd5 peer:InputPeer admin_id:InputUser = Bool; messages.deleteExportedChatInvite#d464a42b peer:InputPeer link:string = Bool; messages.getAdminsWithInvites#3920e6ef peer:InputPeer = messages.ChatAdminsWithInvites; -messages.getChatInviteImporters#26fb7289 peer:InputPeer link:string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters; +messages.getChatInviteImporters#df04dd4e flags:# requested:flags.0?true peer:InputPeer link:flags.1?string q:flags.2?string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters; messages.setHistoryTTL#b80e5fe4 peer:InputPeer period:int = Updates; messages.checkHistoryImportPeer#5dc60f03 peer:InputPeer = messages.CheckedHistoryImportPeer; messages.setChatTheme#e63be13f peer:InputPeer emoticon:string = Updates; messages.getMessageReadParticipants#2c6f97b7 peer:InputPeer msg_id:int = Vector; +messages.getSearchResultsCalendar#49f0bde9 peer:InputPeer filter:MessagesFilter offset_id:int offset_date:int = messages.SearchResultsCalendar; +messages.getSearchResultsPositions#6e9583a3 peer:InputPeer filter:MessagesFilter offset_id:int limit:int = messages.SearchResultsPositions; +messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPeer user_id:InputUser = Updates; updates.getState#edd4882a = updates.State; updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 31c919d65..bad7a6d23 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1629,7 +1629,7 @@ class ExportChatInviteQuery final : public Td::ResultHandler { } send_query(G()->net_query_creator().create(telegram_api::messages_exportChatInvite( - flags, false /*ignored*/, std::move(input_peer), expire_date, usage_limit))); + flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), expire_date, usage_limit, string()))); } void on_result(uint64 id, BufferSlice packet) final { @@ -1679,7 +1679,7 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { int32 flags = telegram_api::messages_editExportedChatInvite::EXPIRE_DATE_MASK | telegram_api::messages_editExportedChatInvite::USAGE_LIMIT_MASK; send_query(G()->net_query_creator().create(telegram_api::messages_editExportedChatInvite( - flags, false /*ignored*/, std::move(input_peer), invite_link, expire_date, usage_limit))); + flags, false /*ignored*/, std::move(input_peer), invite_link, expire_date, usage_limit, false, string()))); } void on_result(uint64 id, BufferSlice packet) final { @@ -1901,8 +1901,10 @@ class GetChatInviteImportersQuery final : public Td::ResultHandler { input_user = make_tl_object(); } - send_query(G()->net_query_creator().create(telegram_api::messages_getChatInviteImporters( - std::move(input_peer), invite_link, offset_date, std::move(input_user), limit))); + int32 flags = telegram_api::messages_getChatInviteImporters::LINK_MASK; + send_query(G()->net_query_creator().create( + telegram_api::messages_getChatInviteImporters(flags, false /*ignored*/, std::move(input_peer), invite_link, + string(), offset_date, std::move(input_user), limit))); } void on_result(uint64 id, BufferSlice packet) final { @@ -1959,7 +1961,7 @@ class RevokeChatInviteLinkQuery final : public Td::ResultHandler { int32 flags = telegram_api::messages_editExportedChatInvite::REVOKED_MASK; send_query(G()->net_query_creator().create(telegram_api::messages_editExportedChatInvite( - flags, false /*ignored*/, std::move(input_peer), invite_link, 0, 0))); + flags, false /*ignored*/, std::move(input_peer), invite_link, 0, 0, false, string()))); } void on_result(uint64 id, BufferSlice packet) final { diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index c9e993e58..112041712 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -4733,6 +4733,8 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(action); return td::make_unique(std::move(set_chat_theme->emoticon_)); } + case telegram_api::messageActionChatJoinedByRequest::ID: + return make_unique(); default: UNREACHABLE(); } diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 59ecf4fb5..b61818e08 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2589,7 +2589,7 @@ class DeleteHistoryQuery final : public Td::ResultHandler { send_query(G()->net_query_creator().create( telegram_api::messages_deleteHistory(flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), - max_message_id_.get_server_message_id().get()))); + max_message_id_.get_server_message_id().get(), 0, 0))); } public: @@ -31689,6 +31689,8 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob return make_tl_object( invite_link.get_chat_invite_link_object(td_->contacts_manager_.get())); } + case telegram_api::channelAdminLogEventActionParticipantJoinByRequest::ID: + return nullptr; case telegram_api::channelAdminLogEventActionParticipantLeave::ID: return make_tl_object(); case telegram_api::channelAdminLogEventActionParticipantInvite::ID: { diff --git a/td/telegram/ThemeManager.cpp b/td/telegram/ThemeManager.cpp index c2c219992..b22ea27cf 100644 --- a/td/telegram/ThemeManager.cpp +++ b/td/telegram/ThemeManager.cpp @@ -16,6 +16,7 @@ #include "td/utils/algorithm.h" #include "td/utils/buffer.h" +#include "td/utils/emoji.h" #include "td/utils/logging.h" #include "td/utils/Random.h" #include "td/utils/Time.h" @@ -24,14 +25,14 @@ namespace td { class GetChatThemesQuery final : public Td::ResultHandler { - Promise> promise_; + Promise> promise_; public: - explicit GetChatThemesQuery(Promise> &&promise) + explicit GetChatThemesQuery(Promise> &&promise) : promise_(std::move(promise)) { } - void send(int32 hash) { + void send(int64 hash) { send_query(G()->net_query_creator().create(telegram_api::account_getChatThemes(hash))); } @@ -111,8 +112,7 @@ void ThemeManager::ChatTheme::store(StorerT &storer) const { BEGIN_STORE_FLAGS(); END_STORE_FLAGS(); td::store(emoji, storer); - td::store(light_id, storer); - td::store(dark_id, storer); + td::store(id, storer); td::store(light_theme, storer); td::store(dark_theme, storer); } @@ -122,8 +122,7 @@ void ThemeManager::ChatTheme::parse(ParserT &parser) { BEGIN_PARSE_FLAGS(); END_PARSE_FLAGS(); td::parse(emoji, parser); - td::parse(light_id, parser); - td::parse(dark_id, parser); + td::parse(id, parser); td::parse(light_theme, parser); td::parse(dark_theme, parser); } @@ -180,29 +179,57 @@ void ThemeManager::loop() { } auto request_promise = PromiseCreator::lambda( - [actor_id = actor_id(this)](Result> result) { + [actor_id = actor_id(this)](Result> result) { send_closure(actor_id, &ThemeManager::on_get_chat_themes, std::move(result)); }); td_->create_handler(std::move(request_promise))->send(chat_themes_.hash); } +bool ThemeManager::is_dark_base_theme(BaseTheme base_theme) { + switch (base_theme) { + case BaseTheme::Classic: + case BaseTheme::Day: + case BaseTheme::Arctic: + return false; + case BaseTheme::Night: + case BaseTheme::Tinted: + return true; + default: + UNREACHABLE(); + return false; + } +} + void ThemeManager::on_update_theme(telegram_api::object_ptr &&theme, Promise &&promise) { CHECK(theme != nullptr); bool is_changed = false; + bool was_light = false; + bool was_dark = false; for (auto &chat_theme : chat_themes_.themes) { - if (chat_theme.light_id == theme->id_ || chat_theme.dark_id == theme->id_) { - auto theme_settings = get_chat_theme_settings(std::move(theme->settings_)); - if (theme_settings.message_colors.empty()) { - break; - } - if (chat_theme.light_id == theme->id_ && chat_theme.light_theme != theme_settings) { - chat_theme.light_theme = theme_settings; - is_changed = true; - } - if (chat_theme.dark_id == theme->id_ && chat_theme.dark_theme != theme_settings) { - chat_theme.dark_theme = theme_settings; - is_changed = true; + if (chat_theme.id == theme->id_) { + for (auto &settings : theme->settings_) { + auto theme_settings = get_chat_theme_settings(std::move(settings)); + if (theme_settings.message_colors.empty()) { + continue; + } + if (is_dark_base_theme(theme_settings.base_theme)) { + if (!was_dark) { + was_dark = true; + if (chat_theme.dark_theme != theme_settings) { + chat_theme.dark_theme = std::move(theme_settings); + is_changed = true; + } + } + } else { + if (!was_light) { + was_light = true; + if (chat_theme.light_theme != theme_settings) { + chat_theme.light_theme = std::move(theme_settings); + is_changed = true; + } + } + } } } } @@ -254,7 +281,7 @@ void ThemeManager::send_update_chat_themes() const { send_closure(G()->td(), &Td::send_update, get_update_chat_themes_object()); } -void ThemeManager::on_get_chat_themes(Result> result) { +void ThemeManager::on_get_chat_themes(Result> result) { if (result.is_error()) { set_timeout_in(Random::fast(40, 60)); return; @@ -265,29 +292,49 @@ void ThemeManager::on_get_chat_themes(Resultget_id() == telegram_api::account_chatThemesNotModified::ID) { + if (chat_themes_ptr->get_id() == telegram_api::account_themesNotModified::ID) { return; } - CHECK(chat_themes_ptr->get_id() == telegram_api::account_chatThemes::ID); - auto chat_themes = telegram_api::move_object_as(chat_themes_ptr); + CHECK(chat_themes_ptr->get_id() == telegram_api::account_themes::ID); + auto chat_themes = telegram_api::move_object_as(chat_themes_ptr); chat_themes_.hash = chat_themes->hash_; chat_themes_.themes.clear(); - for (auto &chat_theme : chat_themes->themes_) { - if (chat_theme->emoticon_.empty()) { - LOG(ERROR) << "Receive " << to_string(chat_theme); + for (auto &theme : chat_themes->themes_) { + if (!is_emoji(theme->emoticon_) || !theme->for_chat_) { + LOG(ERROR) << "Receive " << to_string(theme); continue; } - ChatTheme theme; - theme.emoji = std::move(chat_theme->emoticon_); - theme.light_id = chat_theme->theme_->id_; - theme.dark_id = chat_theme->dark_theme_->id_; - theme.light_theme = get_chat_theme_settings(std::move(chat_theme->theme_->settings_)); - theme.dark_theme = get_chat_theme_settings(std::move(chat_theme->dark_theme_->settings_)); - if (theme.light_theme.message_colors.empty() || theme.dark_theme.message_colors.empty()) { + bool was_light = false; + bool was_dark = false; + ChatTheme chat_theme; + chat_theme.emoji = std::move(theme->emoticon_); + chat_theme.id = theme->id_; + for (auto &settings : theme->settings_) { + auto theme_settings = get_chat_theme_settings(std::move(settings)); + if (theme_settings.message_colors.empty()) { + continue; + } + if (is_dark_base_theme(theme_settings.base_theme)) { + if (!was_dark) { + was_dark = true; + if (chat_theme.dark_theme != theme_settings) { + chat_theme.dark_theme = std::move(theme_settings); + } + } + } else { + if (!was_light) { + was_light = true; + if (chat_theme.light_theme != theme_settings) { + chat_theme.light_theme = std::move(theme_settings); + } + } + } + } + if (chat_theme.light_theme.message_colors.empty() || chat_theme.dark_theme.message_colors.empty()) { continue; } - chat_themes_.themes.push_back(std::move(theme)); + chat_themes_.themes.push_back(std::move(chat_theme)); } save_chat_themes(); diff --git a/td/telegram/ThemeManager.h b/td/telegram/ThemeManager.h index 444b4816c..f39698665 100644 --- a/td/telegram/ThemeManager.h +++ b/td/telegram/ThemeManager.h @@ -59,8 +59,7 @@ class ThemeManager final : public Actor { struct ChatTheme { string emoji; - int64 light_id = 0; - int64 dark_id = 0; + int64 id = 0; ThemeSettings light_theme; ThemeSettings dark_theme; @@ -72,7 +71,7 @@ class ThemeManager final : public Actor { }; struct ChatThemes { - int32 hash = 0; + int64 hash = 0; double next_reload_time = 0; vector themes; @@ -89,7 +88,9 @@ class ThemeManager final : public Actor { void tear_down() final; - void on_get_chat_themes(Result> result); + static bool is_dark_base_theme(BaseTheme base_theme); + + void on_get_chat_themes(Result> result); td_api::object_ptr get_theme_settings_object(const ThemeSettings &settings) const; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 2ce4d7fdd..a2af461f1 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -676,6 +676,7 @@ bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ case telegram_api::messageActionGroupCallScheduled::ID: case telegram_api::messageActionSetMessagesTTL::ID: case telegram_api::messageActionSetChatTheme::ID: + case telegram_api::messageActionChatJoinedByRequest::ID: break; case telegram_api::messageActionChatCreate::ID: { auto chat_create = static_cast(action); @@ -695,13 +696,9 @@ bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ } break; } - case telegram_api::messageActionChatJoinedByLink::ID: { - auto chat_joined_by_link = static_cast(action); - if (!is_acceptable_user(UserId(chat_joined_by_link->inviter_id_))) { - return false; - } + case telegram_api::messageActionChatJoinedByLink::ID: + // inviter_id_ isn't used break; - } case telegram_api::messageActionChatDeleteUser::ID: { auto chat_delete_user = static_cast(action); if (!is_acceptable_user(UserId(chat_delete_user->user_id_))) { @@ -3217,4 +3214,11 @@ void UpdatesManager::on_update(tl_object_ptr update, // unsupported updates +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { +} + } // namespace td diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 42bf659e4..61a5e87b6 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -491,6 +491,10 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); // unsupported updates + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); }; } // namespace td diff --git a/td/telegram/Version.h b/td/telegram/Version.h index 70cf0b911..dacaea31d 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -10,7 +10,7 @@ namespace td { -constexpr int32 MTPROTO_LAYER = 133; +constexpr int32 MTPROTO_LAYER = 134; enum class Version : int32 { Initial, // 0 From 16f1e161072e90e301d94d325ed3a460ec7e3fc6 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 8 Oct 2021 15:29:40 +0300 Subject: [PATCH 13/82] Support message links in sponsoredMessage. --- td/telegram/SponsoredMessageManager.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/td/telegram/SponsoredMessageManager.cpp b/td/telegram/SponsoredMessageManager.cpp index d4d4407bf..46f218fdf 100644 --- a/td/telegram/SponsoredMessageManager.cpp +++ b/td/telegram/SponsoredMessageManager.cpp @@ -7,12 +7,14 @@ #include "td/telegram/SponsoredMessageManager.h" #include "td/telegram/ChannelId.h" +#include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" #include "td/telegram/MessageContent.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/net/NetQueryCreator.h" +#include "td/telegram/ServerMessageId.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" @@ -95,13 +97,16 @@ class ViewSponsoredMessageQuery final : public Td::ResultHandler { struct SponsoredMessageManager::SponsoredMessage { int32 local_id = 0; DialogId sponsor_dialog_id; + ServerMessageId server_message_id; string start_param; unique_ptr content; SponsoredMessage() = default; - SponsoredMessage(int32 local_id, DialogId sponsor_dialog_id, string start_param, unique_ptr content) + SponsoredMessage(int32 local_id, DialogId sponsor_dialog_id, ServerMessageId server_message_id, string start_param, + unique_ptr content) : local_id(local_id) , sponsor_dialog_id(sponsor_dialog_id) + , server_message_id(server_message_id) , start_param(std::move(start_param)) , content(std::move(content)) { } @@ -162,6 +167,13 @@ td_api::object_ptr SponsoredMessageManager::get_sponso link = td_api::make_object(bot_username, sponsored_message.start_param); break; } + case DialogType::Channel: { + auto channel_id = sponsored_message.sponsor_dialog_id.get_channel_id(); + auto t_me = G()->shared_config().get_option_string("t_me_url", "https://t.me/"); + link = td_api::make_object( + PSTRING() << t_me << "/c" << channel_id.get() << '/' << sponsored_message.server_message_id.get()); + break; + } default: break; } @@ -239,6 +251,11 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( LOG(ERROR) << "Receive unknown sponsor " << sponsor_dialog_id; continue; } + auto server_message_id = ServerMessageId(sponsored_message->channel_post_); + if (!server_message_id.is_valid() && server_message_id != ServerMessageId()) { + LOG(ERROR) << "Receive invalid channel post in " << to_string(sponsored_message); + server_message_id = ServerMessageId(); + } td_->messages_manager_->force_create_dialog(sponsor_dialog_id, "on_get_dialog_sponsored_messages"); auto message_text = get_message_text(td_->contacts_manager_.get(), std::move(sponsored_message->message_), std::move(sponsored_message->entities_), true, true, 0, false, @@ -253,8 +270,8 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( CHECK(current_sponsored_message_id_ < std::numeric_limits::max()); auto local_id = ++current_sponsored_message_id_; messages->message_random_ids[local_id] = sponsored_message->random_id_.as_slice().str(); - messages->messages.emplace_back(local_id, sponsor_dialog_id, std::move(sponsored_message->start_param_), - std::move(content)); + messages->messages.emplace_back(local_id, sponsor_dialog_id, server_message_id, + std::move(sponsored_message->start_param_), std::move(content)); } for (auto &promise : promises) { From 884232d9355cafdee29f88ad026e14ca7cce68ed Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 9 Oct 2021 12:52:25 +0300 Subject: [PATCH 14/82] Add chatInviteLink.requires_approval/pending_join_request_count. --- td/generate/scheme/td_api.tl | 4 +++- td/telegram/DialogInviteLink.cpp | 27 +++++++++++++++++++++------ td/telegram/DialogInviteLink.h | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index ba04801f8..8f86f1577 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -562,9 +562,11 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@expire_date Point in time (Unix timestamp) when the link will expire; 0 if never //@member_limit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited //@member_count Number of chat members, which joined the chat using the link +//@pending_join_request_count Number of pending join requests, created using this link +//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators //@is_primary True, if the link is primary. Primary invite link can't have expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time //@is_revoked True, if the link was revoked -chatInviteLink invite_link:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 is_primary:Bool is_revoked:Bool = ChatInviteLink; +chatInviteLink invite_link:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 pending_join_request_count:int32 requires_approval:Bool is_primary:Bool is_revoked:Bool = ChatInviteLink; //@description Contains a list of chat invite links @total_count Approximate total count of chat invite links found @invite_links List of invite links chatInviteLinks total_count:int32 invite_links:vector = ChatInviteLinks; diff --git a/td/telegram/DialogInviteLink.cpp b/td/telegram/DialogInviteLink.cpp index 714e480d9..c35b3f1bb 100644 --- a/td/telegram/DialogInviteLink.cpp +++ b/td/telegram/DialogInviteLink.cpp @@ -58,14 +58,25 @@ DialogInviteLink::DialogInviteLink(tl_object_ptrflags_ & telegram_api::chatInviteExported::REQUESTED_MASK) != 0) { + request_count_ = exported_invite->requested_; + if (request_count_ < 0) { + LOG(ERROR) << "Receive wrong pending join request count " << request_count_ << " for a link " << invite_link_; + request_count_ = 0; + } + } + requires_approval_ = exported_invite->request_needed_; is_revoked_ = exported_invite->revoked_; is_permanent_ = exported_invite->permanent_; - if (is_permanent_ && (usage_limit_ > 0 || expire_date_ > 0 || edit_date_ > 0)) { + if (is_permanent_ && + (usage_limit_ > 0 || expire_date_ > 0 || edit_date_ > 0 || request_count_ > 0 || requires_approval_)) { LOG(ERROR) << "Receive wrong permanent " << *this; expire_date_ = 0; usage_limit_ = 0; edit_date_ = 0; + request_count_ = 0; + requires_approval_ = false; } } @@ -82,13 +93,15 @@ td_api::object_ptr DialogInviteLink::get_chat_invite_lin return td_api::make_object( invite_link_, contacts_manager->get_user_id_object(creator_user_id_, "get_chat_invite_link_object"), date_, - edit_date_, expire_date_, usage_limit_, usage_count_, is_permanent_, is_revoked_); + edit_date_, expire_date_, usage_limit_, usage_count_, request_count_, requires_approval_, is_permanent_, + is_revoked_); } bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { return lhs.invite_link_ == rhs.invite_link_ && lhs.creator_user_id_ == rhs.creator_user_id_ && lhs.date_ == rhs.date_ && lhs.edit_date_ == rhs.edit_date_ && lhs.expire_date_ == rhs.expire_date_ && lhs.usage_limit_ == rhs.usage_limit_ && lhs.usage_count_ == rhs.usage_count_ && + lhs.request_count_ == rhs.request_count_ && lhs.requires_approval_ == rhs.requires_approval_ && lhs.is_permanent_ == rhs.is_permanent_ && lhs.is_revoked_ == rhs.is_revoked_; } @@ -97,10 +110,12 @@ bool operator!=(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { } StringBuilder &operator<<(StringBuilder &string_builder, const DialogInviteLink &invite_link) { - return string_builder << "ChatInviteLink[" << invite_link.invite_link_ << " by " << invite_link.creator_user_id_ - << " created at " << invite_link.date_ << " edited at " << invite_link.edit_date_ - << " expiring at " << invite_link.expire_date_ << " used by " << invite_link.usage_count_ - << " with usage limit " << invite_link.usage_limit_ << "]"; + return string_builder << "ChatInviteLink[" << invite_link.invite_link_ + << (invite_link.requires_approval_ ? " requiring approval" : "") << " by " + << invite_link.creator_user_id_ << " created at " << invite_link.date_ << " edited at " + << invite_link.edit_date_ << " expiring at " << invite_link.expire_date_ << " used by " + << invite_link.usage_count_ << " with usage limit " << invite_link.usage_limit_ << " and " + << invite_link.request_count_ << "pending join requests]"; } } // namespace td diff --git a/td/telegram/DialogInviteLink.h b/td/telegram/DialogInviteLink.h index 1baedb5c8..eb92ec853 100644 --- a/td/telegram/DialogInviteLink.h +++ b/td/telegram/DialogInviteLink.h @@ -27,6 +27,8 @@ class DialogInviteLink { int32 expire_date_ = 0; int32 usage_limit_ = 0; int32 usage_count_ = 0; + int32 request_count_ = 0; + bool requires_approval_ = false; bool is_revoked_ = false; bool is_permanent_ = false; @@ -66,6 +68,7 @@ class DialogInviteLink { bool has_usage_limit = usage_limit_ != 0; bool has_usage_count = usage_count_ != 0; bool has_edit_date = edit_date_ != 0; + bool has_request_count = request_count_ != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(is_revoked_); STORE_FLAG(is_permanent_); @@ -73,6 +76,8 @@ class DialogInviteLink { STORE_FLAG(has_usage_limit); STORE_FLAG(has_usage_count); STORE_FLAG(has_edit_date); + STORE_FLAG(has_request_count); + STORE_FLAG(requires_approval_); END_STORE_FLAGS(); store(invite_link_, storer); store(creator_user_id_, storer); @@ -89,6 +94,9 @@ class DialogInviteLink { if (has_edit_date) { store(edit_date_, storer); } + if (has_request_count) { + store(request_count_, storer); + } } template @@ -98,6 +106,7 @@ class DialogInviteLink { bool has_usage_limit; bool has_usage_count; bool has_edit_date; + bool has_request_count; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_revoked_); PARSE_FLAG(is_permanent_); @@ -105,6 +114,8 @@ class DialogInviteLink { PARSE_FLAG(has_usage_limit); PARSE_FLAG(has_usage_count); PARSE_FLAG(has_edit_date); + PARSE_FLAG(has_request_count); + PARSE_FLAG(requires_approval_); END_PARSE_FLAGS(); parse(invite_link_, parser); parse(creator_user_id_, parser); @@ -121,6 +132,9 @@ class DialogInviteLink { if (has_edit_date) { parse(edit_date_, parser); } + if (has_request_count) { + parse(request_count_, parser); + } } }; From 63d86176f2d7441209043d361f56e924ef7157f4 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 9 Oct 2021 13:19:38 +0300 Subject: [PATCH 15/82] Add chatInviteLinkInfo.description/requires_approval. --- td/generate/scheme/td_api.tl | 4 +++- td/telegram/ContactsManager.cpp | 13 ++++++++++--- td/telegram/ContactsManager.h | 4 +++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 8f86f1577..1748b88b3 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -592,10 +592,12 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@type Contains information about the type of the chat //@title Title of the chat //@photo Chat photo; may be null +//@param_description Chat description //@member_count Number of members in the chat //@member_user_ids User identifiers of some chat members that may be known to the current user +//@requires_approval True, if the user will need to be approved by chat administrators //@is_public True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup -chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo member_count:int32 member_user_ids:vector is_public:Bool = ChatInviteLinkInfo; +chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector requires_approval:Bool is_public:Bool = ChatInviteLinkInfo; //@description Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index bad7a6d23..c224e8b8c 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -12542,8 +12542,10 @@ void ContactsManager::on_get_dialog_invite_link_info(const string &invite_link, invite_link_info->dialog_id = DialogId(); invite_link_info->title = chat_invite->title_; invite_link_info->photo = get_photo(td_->file_manager_.get(), std::move(chat_invite->photo_), DialogId()); + invite_link_info->description = std::move(chat_invite->about_); invite_link_info->participant_count = chat_invite->participants_count_; invite_link_info->participant_user_ids = std::move(participant_user_ids); + invite_link_info->requires_approval = std::move(chat_invite->request_needed_); invite_link_info->is_chat = (chat_invite->flags_ & CHAT_INVITE_FLAG_IS_CHANNEL) == 0; invite_link_info->is_channel = (chat_invite->flags_ & CHAT_INVITE_FLAG_IS_CHANNEL) != 0; @@ -15953,8 +15955,7 @@ tl_object_ptr ContactsManager::get_secret_chat_object_const( secret_chat->is_outbound, secret_chat->key_hash, secret_chat->layer); } -tl_object_ptr ContactsManager::get_chat_invite_link_info_object( - const string &invite_link) const { +tl_object_ptr ContactsManager::get_chat_invite_link_info_object(const string &invite_link) { auto it = invite_link_infos_.find(invite_link); if (it == invite_link_infos_.end()) { return nullptr; @@ -15967,8 +15968,10 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ string title; const DialogPhoto *photo = nullptr; DialogPhoto invite_link_photo; + string description; int32 participant_count = 0; vector member_user_ids; + bool requires_approval = false; bool is_public = false; bool is_member = false; td_api::object_ptr chat_type; @@ -16013,12 +16016,15 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ default: UNREACHABLE(); } + description = get_dialog_about(dialog_id); } else { title = invite_link_info->title; invite_link_photo = as_fake_dialog_photo(invite_link_info->photo, dialog_id); photo = &invite_link_photo; + description = invite_link_info->description; participant_count = invite_link_info->participant_count; member_user_ids = get_user_ids_object(invite_link_info->participant_user_ids, "get_chat_invite_link_info_object"); + requires_approval = invite_link_info->requires_approval; is_public = invite_link_info->is_public; if (invite_link_info->is_chat) { @@ -16041,7 +16047,8 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ return make_tl_object(dialog_id.get(), accessible_for, std::move(chat_type), title, get_chat_photo_info_object(td_->file_manager_.get(), photo), - participant_count, std::move(member_user_ids), is_public); + description, participant_count, std::move(member_user_ids), + requires_approval, is_public); } UserId ContactsManager::get_support_user(Promise &&promise) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 9b266b0cf..ce1a2138c 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -566,7 +566,7 @@ class ContactsManager final : public Actor { tl_object_ptr get_chat_member_object(const DialogParticipant &dialog_participant) const; - tl_object_ptr get_chat_invite_link_info_object(const string &invite_link) const; + tl_object_ptr get_chat_invite_link_info_object(const string &invite_link); UserId get_support_user(Promise &&promise); @@ -927,8 +927,10 @@ class ContactsManager final : public Actor { // unknown dialog string title; Photo photo; + string description; int32 participant_count = 0; vector participant_user_ids; + bool requires_approval = false; bool is_chat = false; bool is_channel = false; bool is_public = false; From 5d9a224386f772fea7d8721ad83a2b2ba4a1b7bd Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 9 Oct 2021 13:51:37 +0300 Subject: [PATCH 16/82] Add chatInviteLinkMember.approver_user_id. --- td/generate/scheme/td_api.tl | 4 ++-- td/telegram/ContactsManager.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 1748b88b3..1f76ba480 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -580,8 +580,8 @@ chatInviteLinkCount user_id:int53 invite_link_count:int32 revoked_invite_link_co //@description Contains a list of chat invite link counts @invite_link_counts List of invite linkcounts chatInviteLinkCounts invite_link_counts:vector = ChatInviteLinkCounts; -//@description Describes a chat member joined a chat by an invite link @user_id User identifier @joined_chat_date Point in time (Unix timestamp) when the user joined the chat -chatInviteLinkMember user_id:int53 joined_chat_date:int32 = ChatInviteLinkMember; +//@description Describes a chat member joined a chat by an invite link @user_id User identifier @joined_chat_date Point in time (Unix timestamp) when the user joined the chat @approver_user_id User identifier of the chat administrator, approved user join request +chatInviteLinkMember user_id:int53 joined_chat_date:int32 approver_user_id:int53 = ChatInviteLinkMember; //@description Contains a list of chat members joined a chat by an invite link @total_count Approximate total count of chat members found @members List of chat members, joined a chat by an invite link chatInviteLinkMembers total_count:int32 members:vector = ChatInviteLinkMembers; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index c224e8b8c..fb8c35de4 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1931,8 +1931,16 @@ class GetChatInviteImportersQuery final : public Td::ResultHandler { total_count--; continue; } + UserId approver_user_id(importer->approved_by_); + if (!approver_user_id.is_valid() && approver_user_id != UserId()) { + LOG(ERROR) << "Receive invalid invite link approver " << approver_user_id << " for " << user_id << " in " + << dialog_id_; + total_count--; + continue; + } invite_link_members.push_back(td_api::make_object( - td->contacts_manager_->get_user_id_object(user_id, "chatInviteLinkMember"), importer->date_)); + td->contacts_manager_->get_user_id_object(user_id, "chatInviteLinkMember"), importer->date_, + td->contacts_manager_->get_user_id_object(approver_user_id, "chatInviteLinkMember"))); } promise_.set_value(td_api::make_object(total_count, std::move(invite_link_members))); } From 64d572bcbeecd53544dee056be877e80291ab342 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 9 Oct 2021 14:20:48 +0300 Subject: [PATCH 17/82] Allow creation and edit of invite links, requiring approval. --- td/generate/scheme/td_api.tl | 6 ++++-- td/telegram/ContactsManager.cpp | 32 +++++++++++++++++++------------- td/telegram/ContactsManager.h | 10 +++++----- td/telegram/Td.cpp | 6 +++--- td/telegram/cli.cpp | 16 ++++++++++------ 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 1f76ba480..e3340d32c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4872,14 +4872,16 @@ replacePrimaryChatInviteLink chat_id:int53 = ChatInviteLink; //@chat_id Chat identifier //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited -createChatInviteLink chat_id:int53 expire_date:int32 member_limit:int32 = ChatInviteLink; +//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators +createChatInviteLink chat_id:int53 expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; //@description Edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links //@chat_id Chat identifier //@invite_link Invite link to be edited //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited -editChatInviteLink chat_id:int53 invite_link:string expire_date:int32 member_limit:int32 = ChatInviteLink; +//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators +editChatInviteLink chat_id:int53 invite_link:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; //@description Returns information about an invite link. Requires administrator privileges and can_invite_users right in the chat to get own links and owner privileges to get other links //@chat_id Chat identifier diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index fb8c35de4..a16ef65b7 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1610,7 +1610,7 @@ class ExportChatInviteQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool is_permanent) { + void send(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool requires_approval, bool is_permanent) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { @@ -1624,6 +1624,9 @@ class ExportChatInviteQuery final : public Td::ResultHandler { if (usage_limit > 0) { flags |= telegram_api::messages_exportChatInvite::USAGE_LIMIT_MASK; } + if (requires_approval) { + flags |= telegram_api::messages_exportChatInvite::REQUEST_NEEDED_MASK; + } if (is_permanent) { flags |= telegram_api::messages_exportChatInvite::LEGACY_REVOKE_PERMANENT_MASK; } @@ -1669,7 +1672,8 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, const string &invite_link, int32 expire_date, int32 usage_limit) { + void send(DialogId dialog_id, const string &invite_link, int32 expire_date, int32 usage_limit, + bool requires_approval) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { @@ -1677,9 +1681,11 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { } int32 flags = telegram_api::messages_editExportedChatInvite::EXPIRE_DATE_MASK | - telegram_api::messages_editExportedChatInvite::USAGE_LIMIT_MASK; - send_query(G()->net_query_creator().create(telegram_api::messages_editExportedChatInvite( - flags, false /*ignored*/, std::move(input_peer), invite_link, expire_date, usage_limit, false, string()))); + telegram_api::messages_editExportedChatInvite::USAGE_LIMIT_MASK | + telegram_api::messages_editExportedChatInvite::REQUEST_NEEDED_MASK; + send_query(G()->net_query_creator().create( + telegram_api::messages_editExportedChatInvite(flags, false /*ignored*/, std::move(input_peer), invite_link, + expire_date, usage_limit, requires_approval, string()))); } void on_result(uint64 id, BufferSlice packet) final { @@ -7268,31 +7274,31 @@ Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool } void ContactsManager::export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, - bool is_permanent, + bool requires_approval, bool is_permanent, Promise> &&promise) { - get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, expire_date, usage_limit, is_permanent, - promise = std::move(promise)](Result &&result) mutable { + get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, expire_date, usage_limit, requires_approval, + is_permanent, promise = std::move(promise)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { send_closure(actor_id, &ContactsManager::export_dialog_invite_link_impl, dialog_id, expire_date, usage_limit, - is_permanent, std::move(promise)); + requires_approval, is_permanent, std::move(promise)); } })); } void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, - bool is_permanent, + bool requires_approval, bool is_permanent, Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); td_->create_handler(std::move(promise)) - ->send(dialog_id, expire_date, usage_limit, is_permanent); + ->send(dialog_id, expire_date, usage_limit, requires_approval, is_permanent); } void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string &invite_link, int32 expire_date, - int32 usage_limit, + int32 usage_limit, bool requires_approval, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); @@ -7301,7 +7307,7 @@ void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string & } td_->create_handler(std::move(promise)) - ->send(dialog_id, invite_link, expire_date, usage_limit); + ->send(dialog_id, invite_link, expire_date, requires_approval, usage_limit); } void ContactsManager::get_dialog_invite_link(DialogId dialog_id, const string &invite_link, diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index ce1a2138c..7b97656ba 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -382,11 +382,11 @@ class ContactsManager final : public Actor { void transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, Promise &&promise); - void export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool is_permanent, - Promise> &&promise); + void export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool requires_approval, + bool is_permanent, Promise> &&promise); void edit_dialog_invite_link(DialogId dialog_id, const string &link, int32 expire_date, int32 usage_limit, - Promise> &&promise); + bool requires_approval, Promise> &&promise); void get_dialog_invite_link(DialogId dialog_id, const string &invite_link, Promise> &&promise); @@ -1387,8 +1387,8 @@ class ContactsManager final : public Actor { static bool is_channel_public(const Channel *c); - void export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool is_permanent, - Promise> &&promise); + void export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool requires_approval, + bool is_permanent, Promise> &&promise); void remove_dialog_access_by_invite_link(DialogId dialog_id); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 6bf50bd1a..8e0fad362 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6285,20 +6285,20 @@ void Td::on_request(uint64 id, td_api::getChatAdministrators &request) { void Td::on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request) { CREATE_REQUEST_PROMISE(); - contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), 0, 0, true, std::move(promise)); + contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), 0, 0, false, true, std::move(promise)); } void Td::on_request(uint64 id, const td_api::createChatInviteLink &request) { CREATE_REQUEST_PROMISE(); contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), request.expire_date_, request.member_limit_, - false, std::move(promise)); + request.requires_approval_, false, std::move(promise)); } void Td::on_request(uint64 id, td_api::editChatInviteLink &request) { CLEAN_INPUT_STRING(request.invite_link_); CREATE_REQUEST_PROMISE(); contacts_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, request.expire_date_, - request.member_limit_, std::move(promise)); + request.member_limit_, request.requires_approval_, std::move(promise)); } void Td::on_request(uint64 id, td_api::getChatInviteLink &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 092f977bc..854e460be 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2939,16 +2939,19 @@ class CliClient final : public Actor { string chat_id; int32 expire_date; int32 member_limit; - get_args(args, chat_id, expire_date, member_limit); - send_request(td_api::make_object(as_chat_id(chat_id), expire_date, member_limit)); + bool requires_approval; + get_args(args, chat_id, expire_date, member_limit, requires_approval); + send_request(td_api::make_object(as_chat_id(chat_id), expire_date, member_limit, + requires_approval)); } else if (op == "ecil") { string chat_id; string invite_link; int32 expire_date; int32 member_limit; - get_args(args, chat_id, invite_link, expire_date, member_limit); - send_request( - td_api::make_object(as_chat_id(chat_id), invite_link, expire_date, member_limit)); + bool requires_approval; + get_args(args, chat_id, invite_link, expire_date, member_limit, requires_approval); + send_request(td_api::make_object(as_chat_id(chat_id), invite_link, expire_date, + member_limit, requires_approval)); } else if (op == "rcil") { string chat_id; string invite_link; @@ -2981,7 +2984,8 @@ class CliClient final : public Actor { get_args(args, chat_id, invite_link, offset_user_id, offset_date, limit); send_request(td_api::make_object( as_chat_id(chat_id), invite_link, - td_api::make_object(as_user_id(offset_user_id), offset_date), as_limit(limit))); + td_api::make_object(as_user_id(offset_user_id), offset_date, 0), + as_limit(limit))); } else if (op == "drcil") { string chat_id; string invite_link; From 6b511f277b5d4aa1be1b538d3779cb525e422204 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 9 Oct 2021 15:04:17 +0300 Subject: [PATCH 18/82] Add messageChatJoinByLink.is_approved. --- td/generate/scheme/td_api.tl | 4 ++-- td/telegram/MessageContent.cpp | 44 +++++++++++++++++++++++++++------- td/telegram/Version.h | 1 + 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e3340d32c..57a26fa04 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1774,8 +1774,8 @@ messageChatDeletePhoto = MessageContent; //@description New chat members were added @member_user_ids User identifiers of the new members messageChatAddMembers member_user_ids:vector = MessageContent; -//@description A new member joined the chat by invite link -messageChatJoinByLink = MessageContent; +//@description A new member joined the chat by invite link @is_approved True, if the join request was approved by a chat administrator +messageChatJoinByLink is_approved:Bool = MessageContent; //@description A chat member was deleted @user_id User identifier of the deleted chat member messageChatDeleteMember user_id:int53 = MessageContent; diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 112041712..108d02306 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -319,6 +319,12 @@ class MessageChatAddUsers final : public MessageContent { class MessageChatJoinedByLink final : public MessageContent { public: + bool is_approved = false; + + MessageChatJoinedByLink() = default; + explicit MessageChatJoinedByLink(bool is_approved) : is_approved(is_approved) { + } + MessageContentType get_type() const final { return MessageContentType::ChatJoinedByLink; } @@ -866,8 +872,13 @@ static void store(const MessageContent *content, StorerT &storer) { store(m->user_ids, storer); break; } - case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatJoinedByLink: { + auto m = static_cast(content); + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->is_approved); + END_STORE_FLAGS(); break; + } case MessageContentType::ChatDeleteUser: { const auto *m = static_cast(content); store(m->user_id, storer); @@ -1229,9 +1240,18 @@ static void parse(unique_ptr &content, ParserT &parser) { content = std::move(m); break; } - case MessageContentType::ChatJoinedByLink: - content = make_unique(); + case MessageContentType::ChatJoinedByLink: { + auto m = make_unique(); + if (parser.version() >= static_cast(Version::AddInviteLinksRequiringApproval)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->is_approved); + END_PARSE_FLAGS(); + } else { + m->is_approved = false; + } + content = std::move(m); break; + } case MessageContentType::ChatDeleteUser: { auto m = make_unique(); parse(m->user_id, parser); @@ -3253,8 +3273,14 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo } break; } - case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatJoinedByLink: { + auto old_ = static_cast(old_content); + auto new_ = static_cast(new_content); + if (old_->is_approved != new_->is_approved) { + need_update = true; + } break; + } case MessageContentType::ChatDeleteUser: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); @@ -4538,7 +4564,7 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(std::move(user_ids)); } case telegram_api::messageActionChatJoinedByLink::ID: - return make_unique(); + return make_unique(false); case telegram_api::messageActionChatDeleteUser::ID: { auto chat_delete_user = move_tl_object_as(action); @@ -4734,7 +4760,7 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(std::move(set_chat_theme->emoticon_)); } case telegram_api::messageActionChatJoinedByRequest::ID: - return make_unique(); + return make_unique(true); default: UNREACHABLE(); } @@ -4855,8 +4881,10 @@ tl_object_ptr get_message_content_object(const MessageCo return make_tl_object( td->contacts_manager_->get_user_ids_object(m->user_ids, "MessageChatAddUsers")); } - case MessageContentType::ChatJoinedByLink: - return make_tl_object(); + case MessageContentType::ChatJoinedByLink: { + const MessageChatJoinedByLink *m = static_cast(content); + return make_tl_object(m->is_approved); + } case MessageContentType::ChatDeleteUser: { const auto *m = static_cast(content); return make_tl_object( diff --git a/td/telegram/Version.h b/td/telegram/Version.h index dacaea31d..2a8fbb5ee 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -47,6 +47,7 @@ enum class Version : int32 { SupportBannedChannels, RemovePhotoVolumeAndLocalId, Support64BitIds, + AddInviteLinksRequiringApproval, Next }; From a4aa509308446637dc4bc78ec55424f8cc9b42f3 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 9 Oct 2021 16:53:29 +0300 Subject: [PATCH 19/82] Add requested_ flag check. --- td/telegram/ContactsManager.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index a16ef65b7..3c529bc03 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1932,15 +1932,10 @@ class GetChatInviteImportersQuery final : public Td::ResultHandler { vector> invite_link_members; for (auto &importer : result->importers_) { UserId user_id(importer->user_id_); - if (!user_id.is_valid()) { - LOG(ERROR) << "Receive invalid invite link " << user_id << " in " << dialog_id_; - total_count--; - continue; - } UserId approver_user_id(importer->approved_by_); - if (!approver_user_id.is_valid() && approver_user_id != UserId()) { - LOG(ERROR) << "Receive invalid invite link approver " << approver_user_id << " for " << user_id << " in " - << dialog_id_; + if (!user_id.is_valid() || (!approver_user_id.is_valid() && approver_user_id != UserId()) || + importer->requested_) { + LOG(ERROR) << "Receive invalid invite link importer: " << to_string(importer); total_count--; continue; } From e49ae700b605dfcdcd05b4530ae72475214d4ab7 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 18:11:17 +0300 Subject: [PATCH 20/82] Add chat.pending_join_request_count. --- td/generate/scheme/td_api.tl | 6 +++- td/telegram/ContactsManager.cpp | 5 +++ td/telegram/ContactsManager.h | 2 ++ td/telegram/MessagesManager.cpp | 62 +++++++++++++++++++++++++++++++-- td/telegram/MessagesManager.h | 7 ++++ td/telegram/UpdatesManager.cpp | 7 ++-- td/telegram/UpdatesManager.h | 4 +-- 7 files changed, 85 insertions(+), 8 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 57a26fa04..8f96f6396 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -948,10 +948,11 @@ voiceChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@theme_name If non-empty, name of a theme, set for the chat //@action_bar Describes actions which must be possible to do through a chat action bar; may be null //@voice_chat Contains information about voice chat of the chat +//@pending_join_request_count Number of pending join requests, waiting administrator's approval //@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat //@draft_message A draft of a message in the chat; may be null //@client_data Contains application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used -chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar voice_chat:voiceChat reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; +chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar voice_chat:voiceChat pending_join_request_count:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; //@description Represents a list of chats @total_count Approximate total count of chats found @chat_ids List of chat identifiers chats total_count:int32 chat_ids:vector = Chats; @@ -3704,6 +3705,9 @@ updateChatActionBar chat_id:int53 action_bar:ChatActionBar = Update; //@description The chat theme was changed @chat_id Chat identifier @theme_name The new name of the chat theme; may be empty if theme was reset to default updateChatTheme chat_id:int53 theme_name:string = Update; +//@description The number of chat pending join requests was changed @chat_id Chat identifier @pending_join_request_count The new number of pending join requests +updateChatPendingJoinRequestCount chat_id:int53 pending_join_request_count:int32 = Update; + //@description The default chat reply markup was changed. Can occur because new messages with reply markup were received or because an old reply markup was hidden by the user //@chat_id Chat identifier @reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat updateChatReplyMarkup chat_id:int53 reply_markup_message_id:int53 = Update; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 3c529bc03..feefb0e50 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -10454,6 +10454,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_theme_name(DialogId(chat_id), std::move(chat->theme_emoticon_)); + td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(chat_id), chat->requests_pending_); + auto bot_commands = get_bot_commands(std::move(chat->bot_info_), &chat_full->participants); if (chat_full->bot_commands != bot_commands) { chat_full->bot_commands = std::move(bot_commands); @@ -10497,6 +10499,9 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_theme_name(DialogId(channel_id), std::move(channel->theme_emoticon_)); + td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(channel_id), + channel->requests_pending_); + { MessageTtlSetting message_ttl_setting; if ((channel->flags_ & CHANNEL_FULL_FLAG_HAS_MESSAGE_TTL) != 0) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 7b97656ba..c9ccf0278 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -1028,6 +1028,7 @@ class ContactsManager final : public Actor { static constexpr int32 CHAT_FULL_FLAG_HAS_FOLDER_ID = 1 << 11; static constexpr int32 CHAT_FULL_FLAG_HAS_ACTIVE_GROUP_CALL = 1 << 12; static constexpr int32 CHAT_FULL_FLAG_HAS_MESSAGE_TTL = 1 << 14; + static constexpr int32 CHAT_FULL_FLAG_HAS_PENDING_REQUEST_COUNT = 1 << 17; static constexpr int32 CHANNEL_FLAG_USER_IS_CREATOR = 1 << 0; static constexpr int32 CHANNEL_FLAG_USER_HAS_LEFT = 1 << 2; @@ -1078,6 +1079,7 @@ class ContactsManager final : public Actor { static constexpr int32 CHANNEL_FULL_FLAG_IS_BLOCKED = 1 << 22; static constexpr int32 CHANNEL_FULL_FLAG_HAS_EXPORTED_INVITE = 1 << 23; static constexpr int32 CHANNEL_FULL_FLAG_HAS_MESSAGE_TTL = 1 << 24; + static constexpr int32 CHANNEL_FULL_FLAG_HAS_PENDING_REQUEST_COUNT = 1 << 28; static constexpr int32 CHAT_INVITE_FLAG_IS_CHANNEL = 1 << 0; static constexpr int32 CHAT_INVITE_FLAG_IS_BROADCAST = 1 << 1; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index b61818e08..f8afbf4a5 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -5250,7 +5250,8 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool has_default_join_group_call_as_dialog_id = default_join_group_call_as_dialog_id.is_valid(); bool store_has_bots = dialog_type == DialogType::Chat || dialog_type == DialogType::Channel; bool has_theme_name = !theme_name.empty(); - bool has_flags3 = false; + bool has_flags3 = true; + bool has_pending_join_request_count = pending_join_request_count != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(has_draft_message); STORE_FLAG(has_last_database_message); @@ -5320,6 +5321,11 @@ void MessagesManager::Dialog::store(StorerT &storer) const { STORE_FLAG(has_flags3); END_STORE_FLAGS(); } + if (has_flags3) { + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_pending_join_request_count); + END_STORE_FLAGS(); + } store(last_new_message_id, storer); store(server_unread_count, storer); @@ -5414,6 +5420,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_theme_name) { store(theme_name, storer); } + if (has_pending_join_request_count) { + store(pending_join_request_count, storer); + } } // do not forget to resolve dialog dependencies including dependencies of last_message @@ -5448,6 +5457,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_default_join_group_call_as_dialog_id = false; bool has_theme_name = false; bool has_flags3 = false; + bool has_pending_join_request_count = false; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_draft_message); PARSE_FLAG(has_last_database_message); @@ -5541,6 +5551,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { } if (has_flags3) { BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_pending_join_request_count); END_PARSE_FLAGS(); } @@ -5670,6 +5681,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_theme_name) { parse(theme_name, parser); } + if (has_pending_join_request_count) { + parse(pending_join_request_count, parser); + } } template @@ -20141,7 +20155,8 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * d->last_read_inbox_message_id.get(), d->last_read_outbox_message_id.get(), d->unread_mention_count, get_chat_notification_settings_object(&d->notification_settings), d->message_ttl_setting.get_message_ttl_setting_object(), get_dialog_theme_name(d), get_chat_action_bar_object(d), - get_voice_chat_object(d), d->reply_markup_message_id.get(), std::move(draft_message), d->client_data); + get_voice_chat_object(d), d->pending_join_request_count, d->reply_markup_message_id.get(), + std::move(draft_message), d->client_data); } tl_object_ptr MessagesManager::get_chat_object(DialogId dialog_id) const { @@ -28834,6 +28849,20 @@ void MessagesManager::send_update_chat_theme(const Dialog *d) { send_update_secret_chats_with_user_theme(d); } +void MessagesManager::send_update_chat_pending_join_request_count(const Dialog *d) { + if (td_->auth_manager_->is_bot()) { + return; + } + + CHECK(d != nullptr); + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id + << " in send_update_chat_pending_join_request_count"; + on_dialog_updated(d->dialog_id, "send_update_chat_pending_join_request_count"); + send_closure(G()->td(), &Td::send_update, + td_api::make_object(d->dialog_id.get(), + d->pending_join_request_count)); +} + void MessagesManager::send_update_chat_voice_chat(const Dialog *d) { CHECK(d != nullptr); LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_voice_chat"; @@ -29848,14 +29877,41 @@ void MessagesManager::set_dialog_theme_name(Dialog *d, string theme_name) { } d->theme_name = std::move(theme_name); d->is_theme_name_inited = true; - on_dialog_updated(d->dialog_id, "set_dialog_theme_name"); if (is_changed) { LOG(INFO) << "Set " << d->dialog_id << " theme to \"" << theme_name << '"'; send_update_chat_theme(d); + } else { + on_dialog_updated(d->dialog_id, "set_dialog_theme_name"); } } +void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialog_id, + int32 pending_join_request_count) { + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive pending join request count in invalid " << dialog_id; + return; + } + + auto d = get_dialog_force(dialog_id, "on_update_dialog_pending_join_request_count"); + if (d == nullptr) { + // nothing to do + return; + } + + set_dialog_pending_join_request_count(d, pending_join_request_count); +} + +void MessagesManager::set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count) { + CHECK(d != nullptr); + bool is_changed = d->pending_join_request_count != pending_join_request_count; + if (!is_changed) { + return; + } + d->pending_join_request_count = pending_join_request_count; + send_update_chat_pending_join_request_count(d); +} + void MessagesManager::repair_dialog_scheduled_messages(Dialog *d) { if (td_->auth_manager_->is_bot() || d->dialog_id.get_type() == DialogType::SecretChat) { return; diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index d25b64a95..4ffc366f1 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -293,6 +293,8 @@ class MessagesManager final : public Actor { void on_update_dialog_theme_name(DialogId dialog_id, string theme_name); + void on_update_dialog_pending_join_request_count(DialogId dialog_id, int32 pending_join_request_count); + void on_update_dialog_has_scheduled_server_messages(DialogId dialog_id, bool has_scheduled_server_messages); void on_update_dialog_folder_id(DialogId dialog_id, FolderId folder_id); @@ -1178,6 +1180,7 @@ class MessagesManager final : public Actor { InputGroupCallId expected_active_group_call_id; DialogId default_join_group_call_as_dialog_id; string theme_name; + int32 pending_join_request_count = 0; FolderId folder_id; vector dialog_list_ids; // TODO replace with mask @@ -2337,6 +2340,8 @@ class MessagesManager final : public Actor { void send_update_chat_theme(const Dialog *d); + void send_update_chat_pending_join_request_count(const Dialog *d); + void send_update_chat_voice_chat(const Dialog *d); void send_update_chat_message_ttl_setting(const Dialog *d); @@ -2436,6 +2441,8 @@ class MessagesManager final : public Actor { void set_dialog_theme_name(Dialog *d, string theme_name); + void set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count); + void repair_dialog_scheduled_messages(Dialog *d); void set_dialog_has_scheduled_server_messages(Dialog *d, bool has_scheduled_server_messages); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index a2af461f1..be9a2c172 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -3212,11 +3212,14 @@ void UpdatesManager::on_update(tl_object_ptr update, td_->theme_manager_->on_update_theme(std::move(update->theme_), std::move(promise)); } -// unsupported updates - void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(update->peer_), + update->requests_pending_); + promise.set_value(Unit()); } +// unsupported updates + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { } diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 61a5e87b6..05527d8f6 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -490,10 +490,10 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); - // unsupported updates - void on_update(tl_object_ptr update, Promise &&promise); + // unsupported updates + void on_update(tl_object_ptr update, Promise &&promise); }; From aee782562c451edf873a0aa256db088d4f0c8b70 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 19:04:18 +0300 Subject: [PATCH 21/82] Add approver_user_id to chatEventMemberJoinedByInviteLink. --- td/generate/scheme/td_api.tl | 4 ++-- td/telegram/MessagesManager.cpp | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 8f96f6396..8d475e048 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2510,8 +2510,8 @@ chatEventMessageUnpinned message:message = ChatEventAction; //@description A new member joined the chat chatEventMemberJoined = ChatEventAction; -//@description A new member joined the chat by an invite link @invite_link Invite link used to join the chat -chatEventMemberJoinedByInviteLink invite_link:chatInviteLink = ChatEventAction; +//@description A new member joined the chat by an invite link @invite_link Invite link used to join the chat @approver_user_id User identifier of the chat administrator, approved user join request; 0 if the approval wasn't needed +chatEventMemberJoinedByInviteLink invite_link:chatInviteLink approver_user_id:int53 = ChatEventAction; //@description A member left the chat chatEventMemberLeft = ChatEventAction; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index f8afbf4a5..c4b07fb73 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -31743,10 +31743,23 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob return nullptr; } return make_tl_object( - invite_link.get_chat_invite_link_object(td_->contacts_manager_.get())); + invite_link.get_chat_invite_link_object(td_->contacts_manager_.get()), 0); + } + case telegram_api::channelAdminLogEventActionParticipantJoinByRequest::ID: { + auto action = move_tl_object_as(action_ptr); + DialogInviteLink invite_link(std::move(action->invite_)); + if (!invite_link.is_valid()) { + LOG(ERROR) << "Wrong invite link: " << invite_link; + return nullptr; + } + UserId approver_user_id(action->approved_by_); + if (!approver_user_id.is_valid()) { + return nullptr; + } + return make_tl_object( + invite_link.get_chat_invite_link_object(td_->contacts_manager_.get()), + td_->contacts_manager_->get_user_id_object(approver_user_id, "chatEventMemberJoinedByInviteLink")); } - case telegram_api::channelAdminLogEventActionParticipantJoinByRequest::ID: - return nullptr; case telegram_api::channelAdminLogEventActionParticipantLeave::ID: return make_tl_object(); case telegram_api::channelAdminLogEventActionParticipantInvite::ID: { From 0f6247f8569db248fa30295db815d2c6620caeda Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 19:39:03 +0300 Subject: [PATCH 22/82] Nullify pending_join_request_count if have no enough rights. --- td/telegram/ContactsManager.cpp | 29 ++++++++++++++++--------- td/telegram/ContactsManager.h | 1 + td/telegram/MessagesManager.cpp | 38 +++++++++++++++++++++++++++++---- td/telegram/MessagesManager.h | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index feefb0e50..234b664a9 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -9770,20 +9770,26 @@ void ContactsManager::update_chat(Chat *c, ChatId chat_id, bool from_binlog, boo if (c->is_photo_changed) { td_->messages_manager_->on_dialog_photo_updated(DialogId(chat_id)); drop_chat_photos(chat_id, !c->photo.small_file_id.is_valid(), true, "update_chat"); + c->is_photo_changed = false; } if (c->is_title_changed) { td_->messages_manager_->on_dialog_title_updated(DialogId(chat_id)); + c->is_title_changed = false; } if (c->is_default_permissions_changed) { td_->messages_manager_->on_dialog_permissions_updated(DialogId(chat_id)); + c->is_default_permissions_changed = false; } if (c->is_is_active_changed) { update_dialogs_for_discussion(DialogId(chat_id), c->is_active && c->status.is_creator()); + c->is_is_active_changed = false; + } + if (c->is_status_changed) { + if (!c->status.can_manage_invite_links()) { + td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(chat_id), 0); + } + c->is_status_changed = false; } - c->is_photo_changed = false; - c->is_title_changed = false; - c->is_default_permissions_changed = false; - c->is_is_active_changed = false; LOG(DEBUG) << "Update " << chat_id << ": need_save_to_database = " << c->need_save_to_database << ", is_changed = " << c->is_changed; @@ -9819,9 +9825,11 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from if (c->is_photo_changed) { td_->messages_manager_->on_dialog_photo_updated(DialogId(channel_id)); drop_channel_photos(channel_id, !c->photo.small_file_id.is_valid(), true, "update_channel"); + c->is_photo_changed = false; } if (c->is_title_changed) { td_->messages_manager_->on_dialog_title_updated(DialogId(channel_id)); + c->is_title_changed = false; } if (c->is_status_changed) { c->status.update_restrictions(); @@ -9843,6 +9851,10 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from if (!c->status.is_member()) { remove_inactive_channel(channel_id); } + if (!c->status.can_manage_invite_links()) { + td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(channel_id), 0); + } + c->is_status_changed = false; } if (c->is_username_changed) { if (c->status.is_creator() && created_public_channels_inited_[0]) { @@ -9854,6 +9866,7 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from } } } + c->is_username_changed = false; } if (c->is_default_permissions_changed) { td_->messages_manager_->on_dialog_permissions_updated(DialogId(channel_id)); @@ -9861,6 +9874,7 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from RestrictedRights(false, false, false, false, false, false, false, false, false, false, false)) { remove_dialog_suggested_action(SuggestedAction{SuggestedAction::Type::ConvertToGigagroup, DialogId(channel_id)}); } + c->is_default_permissions_changed = false; } if (!td_->auth_manager_->is_bot()) { if (c->restriction_reasons.empty()) { @@ -9870,12 +9884,6 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from } } - c->is_photo_changed = false; - c->is_title_changed = false; - c->is_default_permissions_changed = false; - c->is_status_changed = false; - c->is_username_changed = false; - LOG(DEBUG) << "Update " << channel_id << ": need_save_to_database = " << c->need_save_to_database << ", is_changed = " << c->is_changed; c->need_save_to_database |= c->is_changed; @@ -12824,6 +12832,7 @@ void ContactsManager::on_update_chat_status(Chat *c, ChatId chat_id, DialogParti bool need_drop_invite_link = c->status.can_manage_invite_links() && !status.can_manage_invite_links(); c->status = std::move(status); + c->is_status_changed = true; if (c->status.is_left()) { c->participant_count = 0; diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index c9ccf0278..37dd7c431 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -726,6 +726,7 @@ class ContactsManager final : public Actor { bool is_title_changed = true; bool is_photo_changed = true; bool is_default_permissions_changed = true; + bool is_status_changed = true; bool is_is_active_changed = true; bool is_changed = true; // have new changes that need to be sent to the client and database bool need_save_to_database = true; // have new changes that need only to be saved to the database diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index c4b07fb73..c3081b87f 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -20147,7 +20147,7 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * return make_tl_object( d->dialog_id.get(), get_chat_type_object(d->dialog_id), get_dialog_title(d->dialog_id), get_chat_photo_info_object(td_->file_manager_.get(), get_dialog_photo(d->dialog_id)), - get_dialog_permissions(d->dialog_id).get_chat_permissions_object(), + get_dialog_default_permissions(d->dialog_id).get_chat_permissions_object(), get_message_object(d->dialog_id, get_message(d, d->last_message_id), "get_chat_object"), get_chat_positions_object(d), d->is_marked_as_unread, d->is_blocked, get_dialog_has_scheduled_messages(d), can_delete_for_self, can_delete_for_all_users, can_report_dialog(d->dialog_id), @@ -29904,6 +29904,36 @@ void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialo void MessagesManager::set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count) { CHECK(d != nullptr); + switch (d->dialog_id.get_type()) { + case DialogType::User: + case DialogType::SecretChat: + pending_join_request_count = -1; + break; + case DialogType::Chat: { + auto chat_id = d->dialog_id.get_chat_id(); + auto status = td_->contacts_manager_->get_chat_status(chat_id); + if (!status.can_manage_invite_links()) { + pending_join_request_count = 0; + } + break; + } + case DialogType::Channel: { + auto channel_id = d->dialog_id.get_channel_id(); + auto status = td_->contacts_manager_->get_channel_permissions(channel_id); + if (!status.can_manage_invite_links()) { + pending_join_request_count = 0; + } + break; + } + case DialogType::None: + default: + UNREACHABLE(); + } + if (pending_join_request_count < 0) { + LOG(ERROR) << "Receive " << pending_join_request_count << " pending join requests in " << d->dialog_id; + return; + } + bool is_changed = d->pending_join_request_count != pending_join_request_count; if (!is_changed) { return; @@ -30330,7 +30360,7 @@ void MessagesManager::on_dialog_permissions_updated(DialogId dialog_id) { if (d != nullptr && d->is_update_new_chat_sent) { send_closure(G()->td(), &Td::send_update, td_api::make_object( - dialog_id.get(), get_dialog_permissions(dialog_id).get_chat_permissions_object())); + dialog_id.get(), get_dialog_default_permissions(dialog_id).get_chat_permissions_object())); } } @@ -30777,7 +30807,7 @@ string MessagesManager::get_dialog_username(DialogId dialog_id) const { } } -RestrictedRights MessagesManager::get_dialog_permissions(DialogId dialog_id) const { +RestrictedRights MessagesManager::get_dialog_default_permissions(DialogId dialog_id) const { switch (dialog_id.get_type()) { case DialogType::User: return td_->contacts_manager_->get_user_default_permissions(dialog_id.get_user_id()); @@ -31430,7 +31460,7 @@ void MessagesManager::set_dialog_permissions(DialogId dialog_id, auto new_permissions = get_restricted_rights(permissions); // TODO this can be wrong if there was previous change permissions requests - if (get_dialog_permissions(dialog_id) == new_permissions) { + if (get_dialog_default_permissions(dialog_id) == new_permissions) { return promise.set_value(Unit()); } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 4ffc366f1..cb04ee7ae 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -2827,7 +2827,7 @@ class MessagesManager final : public Actor { string get_dialog_username(DialogId dialog_id) const; - RestrictedRights get_dialog_permissions(DialogId dialog_id) const; + RestrictedRights get_dialog_default_permissions(DialogId dialog_id) const; bool get_dialog_has_scheduled_messages(const Dialog *d) const; From 250e593e3e3e71662345b9e708b53585f88ac7da Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 20:05:36 +0300 Subject: [PATCH 23/82] Add comment. --- td/telegram/ContactsManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 234b664a9..f9c6d369a 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -6022,6 +6022,7 @@ void ContactsManager::set_location_visibility_expire_date(int32 expire_date) { } else { G()->td_db()->get_binlog_pmc()->set("location_visibility_expire_date", to_string(expire_date)); } + // the caller must call update_is_location_visible() itself } void ContactsManager::update_is_location_visible() { From d6502458f58a807d0b43c8471b61b84aea352814 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 22:05:14 +0300 Subject: [PATCH 24/82] Allow to get option "is_location_visible". --- td/telegram/ContactsManager.cpp | 75 +++++++++++++++++++++++++++------ td/telegram/ContactsManager.h | 4 ++ td/telegram/Td.cpp | 8 ++++ 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index f9c6d369a..fc73d9099 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -5775,20 +5775,6 @@ void ContactsManager::search_dialogs_nearby(const Location &location, td_->create_handler(std::move(query_promise))->send(location, false, -1); } -void ContactsManager::set_location(const Location &location, Promise &&promise) { - if (location.empty()) { - return promise.set_error(Status::Error(400, "Invalid location specified")); - } - last_user_location_ = location; - try_send_set_location_visibility_query(); - - auto query_promise = PromiseCreator::lambda( - [promise = std::move(promise)](Result> result) mutable { - promise.set_value(Unit()); - }); - td_->create_handler(std::move(query_promise))->send(location, true, -1); -} - vector> ContactsManager::get_chats_nearby_object( const vector &dialogs_nearby) { return transform(dialogs_nearby, [](const DialogNearby &dialog_nearby) { @@ -5851,6 +5837,20 @@ void ContactsManager::on_get_dialogs_nearby(Result &&promise) { + if (location.empty()) { + return promise.set_error(Status::Error(400, "Invalid location specified")); + } + last_user_location_ = location; + try_send_set_location_visibility_query(); + + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result> result) mutable { + promise.set_value(Unit()); + }); + td_->create_handler(std::move(query_promise))->send(location, true, -1); +} + void ContactsManager::set_location_visibility() { bool is_location_visible = G()->shared_config().get_option_boolean("is_location_visible"); auto pending_location_visibility_expire_date = is_location_visible ? std::numeric_limits::max() : 0; @@ -5918,6 +5918,53 @@ void ContactsManager::on_set_location_visibility_expire_date(int32 set_expire_da update_is_location_visible(); } +void ContactsManager::get_is_location_visible(Promise &&promise) { + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result> result) mutable { + send_closure(actor_id, &ContactsManager::on_get_is_location_visible, std::move(result), std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(Location(), true, -1); +} + +void ContactsManager::on_get_is_location_visible(Result> &&result, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + if (result.is_error()) { + if (result.error().message() == "GEO_POINT_INVALID" && pending_location_visibility_expire_date_ == -1 && + location_visibility_expire_date_ > 0) { + set_location_visibility_expire_date(0); + update_is_location_visible(); + } + return promise.set_value(Unit()); + } + + auto updates_ptr = result.move_as_ok(); + if (updates_ptr->get_id() != telegram_api::updates::ID) { + LOG(ERROR) << "Receive " << oneline(to_string(*updates_ptr)) << " instead of updates"; + return promise.set_value(Unit()); + } + + auto updates = std::move(telegram_api::move_object_as(updates_ptr)->updates_); + if (updates.size() != 1 || updates[0]->get_id() != telegram_api::updatePeerLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(updates); + return promise.set_value(Unit()); + } + + auto peers = std::move(static_cast(updates[0].get())->peers_); + if (peers.size() != 1 || peers[0]->get_id() != telegram_api::peerSelfLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(peers); + return promise.set_value(Unit()); + } + + auto location_visibility_expire_date = static_cast(peers[0].get())->expires_; + if (location_visibility_expire_date != location_visibility_expire_date_) { + set_location_visibility_expire_date(location_visibility_expire_date); + update_is_location_visible(); + } + + promise.set_value(Unit()); +} + int32 ContactsManager::on_update_peer_located(vector> &&peers, bool from_update) { auto now = G()->unix_time(); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 37dd7c431..df4156be9 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -317,6 +317,8 @@ class ContactsManager final : public Actor { void set_location_visibility(); + void get_is_location_visible(Promise &&promise); + FileId get_profile_photo_file_id(int64 photo_id) const; void set_profile_photo(const td_api::object_ptr &input_photo, Promise &&promise); @@ -1386,6 +1388,8 @@ class ContactsManager final : public Actor { void set_location_visibility_expire_date(int32 expire_date); + void on_get_is_location_visible(Result> &&result, Promise &&promise); + void update_is_location_visible(); static bool is_channel_public(const Channel *c); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 8e0fad362..9e41dde06 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7209,6 +7209,14 @@ void Td::on_request(uint64 id, td_api::getOption &request) { send_closure_later(config_manager_, &ConfigManager::get_content_settings, std::move(promise)); return; } + if (!is_bot && request.name_ == "is_location_visible") { + auto promise = PromiseCreator::lambda([actor_id = actor_id(this), id](Result &&result) { + // the option is already updated on success, ignore errors + send_closure(actor_id, &Td::send_result, id, G()->shared_config().get_option_value("is_location_visible")); + }); + send_closure_later(contacts_manager_actor_, &ContactsManager::get_is_location_visible, std::move(promise)); + return; + } break; case 'o': if (request.name_ == "online") { From 90fea23dd79854b4b72cec77b053606ddd6e12c2 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Oct 2021 22:17:07 +0300 Subject: [PATCH 25/82] Check that content was parsed. --- td/telegram/MessagesManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index c3081b87f..67901fae9 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -5181,6 +5181,7 @@ void MessagesManager::Message::parse(ParserT &parser) { parse(max_reply_media_timestamp, parser); } + CHECK(content != nullptr); is_content_secret |= is_secret_message_content(ttl, content->get_type()); // repair is_content_secret for old messages if (hide_edit_date && content->get_type() == MessageContentType::LiveLocation) { From 1a7f4b4d3e361d111bafdc240a2080532c65c8ef Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 13 Oct 2021 22:33:31 +0300 Subject: [PATCH 26/82] Add td_api::getChatJoinRequests. --- td/generate/scheme/td_api.tl | 14 +++++ td/telegram/ContactsManager.cpp | 91 +++++++++++++++++++++++++++++++++ td/telegram/ContactsManager.h | 4 ++ td/telegram/Td.cpp | 9 ++++ td/telegram/Td.h | 2 + td/telegram/cli.cpp | 12 +++++ 6 files changed, 132 insertions(+) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 8d475e048..2c4c02c97 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -599,6 +599,12 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@is_public True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector requires_approval:Bool is_public:Bool = ChatInviteLinkInfo; +//@description Describes a user waiting administrator approval to join a chat @user_id User identifier @request_date Point in time (Unix timestamp) when the user sent the chat join request @bio A short bio of the user +chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; + +//@description Contains a list of chat join requests @total_count Approximate total count of requests found @requests List of the requests +chatJoinRequests total_count:int32 requests:vector = ChatJoinRequests; + //@description Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users) //@id Group identifier @@ -4928,6 +4934,14 @@ checkChatInviteLink invite_link:string = ChatInviteLinkInfo; //@description Uses an invite link to add the current user to the chat if possible @invite_link Invite link to use joinChatByInviteLink invite_link:string = Chat; +//@description Returns pending join requests in a chat +//@chat_id Chat identifier +//@invite_link Invite link for which to return join requests. If empty, all join requests will be returned. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links +//@query A query to search for in the first names, last names and usernames of the users to return +//@offset_request A chat join request from which to return next requests; pass null to get results from the beginning +//@limit The maximum number of chat join requests to return +getChatJoinRequests chat_id:int53 invite_link:string query:string offset_request:chatJoinRequest limit:int32 = ChatJoinRequests; + //@description Creates a new call @user_id Identifier of the user to be called @protocol Description of the call protocols supported by the application @is_video True, if a video call needs to be created createCall user_id:int53 protocol:callProtocol is_video:Bool = CallId; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index fc73d9099..942bde066 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1952,6 +1952,77 @@ class GetChatInviteImportersQuery final : public Td::ResultHandler { } }; +class GetChatJoinRequestsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetChatJoinRequestsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const string &invite_link, const string &query, int32 offset_date, + UserId offset_user_id, int32 limit) { + dialog_id_ = dialog_id; + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(0, Status::Error(400, "Can't access the chat")); + } + + auto input_user = td->contacts_manager_->get_input_user(offset_user_id); + if (input_user == nullptr) { + input_user = make_tl_object(); + } + + int32 flags = telegram_api::messages_getChatInviteImporters::REQUESTED_MASK; + if (!invite_link.empty()) { + flags |= telegram_api::messages_getChatInviteImporters::LINK_MASK; + } + if (!query.empty()) { + flags |= telegram_api::messages_getChatInviteImporters::Q_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::messages_getChatInviteImporters(flags, false /*ignored*/, std::move(input_peer), invite_link, + query, offset_date, std::move(input_user), limit))); + } + + void on_result(uint64 id, BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetChatJoinRequestsQuery: " << to_string(result); + + td->contacts_manager_->on_get_users(std::move(result->users_), "GetChatJoinRequestsQuery"); + + int32 total_count = result->count_; + if (total_count < static_cast(result->importers_.size())) { + LOG(ERROR) << "Receive wrong total count of join requests " << total_count << " in " << dialog_id_; + total_count = static_cast(result->importers_.size()); + } + vector> join_requests; + for (auto &request : result->importers_) { + UserId user_id(request->user_id_); + UserId approver_user_id(request->approved_by_); + if (!user_id.is_valid() || approver_user_id.is_valid() || !request->requested_) { + LOG(ERROR) << "Receive invalid join request: " << to_string(request); + total_count--; + continue; + } + join_requests.push_back(td_api::make_object( + td->contacts_manager_->get_user_id_object(user_id, "chatJoinRequest"), request->date_, request->about_)); + } + promise_.set_value(td_api::make_object(total_count, std::move(join_requests))); + } + + void on_error(uint64 id, Status status) final { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetChatJoinRequestsQuery"); + promise_.set_error(std::move(status)); + } +}; + class RevokeChatInviteLinkQuery final : public Td::ResultHandler { Promise> promise_; DialogId dialog_id_; @@ -7412,6 +7483,26 @@ void ContactsManager::get_dialog_invite_link_users( ->send(dialog_id, invite_link, offset_date, offset_user_id, limit); } +void ContactsManager::get_dialog_join_requests(DialogId dialog_id, const string &invite_link, const string &query, + td_api::object_ptr offset_request, int32 limit, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); + + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + + UserId offset_user_id; + int32 offset_date = 0; + if (offset_request != nullptr) { + offset_user_id = UserId(offset_request->user_id_); + offset_date = offset_request->request_date_; + } + + td_->create_handler(std::move(promise)) + ->send(dialog_id, invite_link, query, offset_date, offset_user_id, limit); +} + void ContactsManager::revoke_dialog_invite_link(DialogId dialog_id, const string &invite_link, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index df4156be9..111a1e638 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -404,6 +404,10 @@ class ContactsManager final : public Actor { td_api::object_ptr offset_member, int32 limit, Promise> &&promise); + void get_dialog_join_requests(DialogId dialog_id, const string &invite_link, const string &query, + td_api::object_ptr offset_request, int32 limit, + Promise> &&promise); + void revoke_dialog_invite_link(DialogId dialog_id, const string &link, Promise> &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 9e41dde06..42f267c0e 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6332,6 +6332,15 @@ void Td::on_request(uint64 id, td_api::getChatInviteLinkMembers &request) { std::move(promise)); } +void Td::on_request(uint64 id, td_api::getChatJoinRequests &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + contacts_manager_->get_dialog_join_requests(DialogId(request.chat_id_), request.invite_link_, request.query_, + std::move(request.offset_request_), request.limit_, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::revokeChatInviteLink &request) { CLEAN_INPUT_STRING(request.invite_link_); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index b98ba1c41..de63f13bc 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -870,6 +870,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::getChatInviteLinkMembers &request); + void on_request(uint64 id, td_api::getChatJoinRequests &request); + void on_request(uint64 id, td_api::revokeChatInviteLink &request); void on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 854e460be..b930c080f 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2986,6 +2986,18 @@ class CliClient final : public Actor { as_chat_id(chat_id), invite_link, td_api::make_object(as_user_id(offset_user_id), offset_date, 0), as_limit(limit))); + } else if (op == "gcjr") { + string chat_id; + string invite_link; + string query; + string offset_user_id; + int32 offset_date; + string limit; + get_args(args, chat_id, invite_link, query, offset_user_id, offset_date, limit); + send_request(td_api::make_object( + as_chat_id(chat_id), invite_link, query, + td_api::make_object(as_user_id(offset_user_id), offset_date, string()), + as_limit(limit))); } else if (op == "drcil") { string chat_id; string invite_link; From 0a9f6b1c91c3f48ff0d39c94fef42932252493a6 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 13 Oct 2021 23:10:47 +0300 Subject: [PATCH 27/82] Add approve/declineCjatJoinRequest. --- td/generate/scheme/td_api.tl | 6 ++++ td/telegram/ContactsManager.cpp | 51 +++++++++++++++++++++++++++++++++ td/telegram/ContactsManager.h | 2 ++ td/telegram/Td.cpp | 12 ++++++++ td/telegram/Td.h | 4 +++ td/telegram/cli.cpp | 10 +++++++ 6 files changed, 85 insertions(+) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2c4c02c97..2bd065098 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4942,6 +4942,12 @@ joinChatByInviteLink invite_link:string = Chat; //@limit The maximum number of chat join requests to return getChatJoinRequests chat_id:int53 invite_link:string query:string offset_request:chatJoinRequest limit:int32 = ChatJoinRequests; +//@description Approves pending join request in a chat @chat_id Chat identifier @user_id Identifier of the user, which request will be approved +approveChatJoinRequest chat_id:int53 user_id:int53 = Ok; + +//@description Declines pending join request in a chat @chat_id Chat identifier @user_id Identifier of the user, which request will be declined +declineChatJoinRequest chat_id:int53 user_id:int53 = Ok; + //@description Creates a new call @user_id Identifier of the user to be called @protocol Description of the call protocols supported by the application @is_video True, if a video call needs to be created createCall user_id:int53 protocol:callProtocol is_video:Bool = CallId; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 942bde066..beb963220 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -2023,6 +2023,51 @@ class GetChatJoinRequestsQuery final : public Td::ResultHandler { } }; +class HideChatJoinRequestQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit HideChatJoinRequestQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, UserId user_id, bool is_approved) { + dialog_id_ = dialog_id; + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(0, Status::Error(400, "Can't access the chat")); + } + + auto input_user = td->contacts_manager_->get_input_user(user_id); + if (input_user == nullptr) { + return on_error(0, Status::Error(400, "Can't find user")); + } + + int32 flags = 0; + if (is_approved) { + flags |= telegram_api::messages_hideChatJoinRequest::APPROVED_MASK; + } + send_query(G()->net_query_creator().create(telegram_api::messages_hideChatJoinRequest( + flags, false /*ignored*/, std::move(input_peer), std::move(input_user)))); + } + + void on_result(uint64 id, BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for HideChatJoinRequestQuery: " << to_string(result); + td->updates_manager_->on_get_updates(std::move(result), std::move(promise_)); + } + + void on_error(uint64 id, Status status) final { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "HideChatJoinRequestQuery"); + promise_.set_error(std::move(status)); + } +}; + class RevokeChatInviteLinkQuery final : public Td::ResultHandler { Promise> promise_; DialogId dialog_id_; @@ -7503,6 +7548,12 @@ void ContactsManager::get_dialog_join_requests(DialogId dialog_id, const string ->send(dialog_id, invite_link, query, offset_date, offset_user_id, limit); } +void ContactsManager::process_dialog_join_requests(DialogId dialog_id, UserId user_id, bool is_approved, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); + td_->create_handler(std::move(promise))->send(dialog_id, user_id, is_approved); +} + void ContactsManager::revoke_dialog_invite_link(DialogId dialog_id, const string &invite_link, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 111a1e638..a3e549a9b 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -408,6 +408,8 @@ class ContactsManager final : public Actor { td_api::object_ptr offset_request, int32 limit, Promise> &&promise); + void process_dialog_join_requests(DialogId dialog_id, UserId user_id, bool is_approved, Promise &&promise); + void revoke_dialog_invite_link(DialogId dialog_id, const string &link, Promise> &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 42f267c0e..ca2d8bbbb 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6341,6 +6341,18 @@ void Td::on_request(uint64 id, td_api::getChatJoinRequests &request) { std::move(request.offset_request_), request.limit_, std::move(promise)); } +void Td::on_request(uint64 id, const td_api::approveChatJoinRequest &request) { + CREATE_OK_REQUEST_PROMISE(); + contacts_manager_->process_dialog_join_requests(DialogId(request.chat_id_), UserId(request.user_id_), true, + std::move(promise)); +} + +void Td::on_request(uint64 id, const td_api::declineChatJoinRequest &request) { + CREATE_OK_REQUEST_PROMISE(); + contacts_manager_->process_dialog_join_requests(DialogId(request.chat_id_), UserId(request.user_id_), false, + std::move(promise)); +} + void Td::on_request(uint64 id, td_api::revokeChatInviteLink &request) { CLEAN_INPUT_STRING(request.invite_link_); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index de63f13bc..964a71d8d 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -872,6 +872,10 @@ class Td final : public Actor { void on_request(uint64 id, td_api::getChatJoinRequests &request); + void on_request(uint64 id, const td_api::approveChatJoinRequest &request); + + void on_request(uint64 id, const td_api::declineChatJoinRequest &request); + void on_request(uint64 id, td_api::revokeChatInviteLink &request); void on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index b930c080f..d90918443 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2998,6 +2998,16 @@ class CliClient final : public Actor { as_chat_id(chat_id), invite_link, query, td_api::make_object(as_user_id(offset_user_id), offset_date, string()), as_limit(limit))); + } else if (op == "acjr") { + string chat_id; + string user_id; + get_args(args, chat_id, user_id); + send_request(td_api::make_object(as_chat_id(chat_id), as_user_id(user_id))); + } else if (op == "dcjr") { + string chat_id; + string user_id; + get_args(args, chat_id, user_id); + send_request(td_api::make_object(as_chat_id(chat_id), as_user_id(user_id))); } else if (op == "drcil") { string chat_id; string invite_link; From cbca4679910bdabcbeb58b700b2444a5cd36c045 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 14 Oct 2021 00:18:44 +0300 Subject: [PATCH 28/82] Adjust dimensions of animated emojis. --- td/telegram/ConfigManager.cpp | 10 +++++++++ td/telegram/JsonValue.cpp | 9 ++++++++ td/telegram/JsonValue.h | 2 ++ td/telegram/StickersManager.cpp | 39 +++++++++++++++++++++++---------- td/telegram/StickersManager.h | 7 +++++- td/telegram/Td.cpp | 6 ++++- 6 files changed, 59 insertions(+), 14 deletions(-) diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 1b309c81e..91b87d0db 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -1506,6 +1506,7 @@ void ConfigManager::process_app_config(tl_object_ptr &c bool can_archive_and_mute_new_chats_from_unknown_users = false; int64 chat_read_mark_expire_period = 0; int64 chat_read_mark_size_threshold = 0; + double animated_emoji_zoom = 0.0; if (config->get_id() == telegram_api::jsonObject::ID) { for (auto &key_value : static_cast(config.get())->value_) { Slice key = key_value->key_; @@ -1533,6 +1534,10 @@ void ConfigManager::process_app_config(tl_object_ptr &c } continue; } + if (key == "emojies_animated_zoom") { + animated_emoji_zoom = get_json_value_double(std::move(key_value->value_), "emojies_animated_zoom"); + continue; + } if (key == "emojies_send_dice") { if (value->get_id() == telegram_api::jsonArray::ID) { auto emojis = std::move(static_cast(value)->value_); @@ -1786,6 +1791,11 @@ void ConfigManager::process_app_config(tl_object_ptr &c shared_config.set_option_string("emoji_sounds", implode(emoji_sounds, ',')); + if (animated_emoji_zoom <= 0 || animated_emoji_zoom > 2.0) { + shared_config.set_option_empty("animated_emoji_zoom"); + } else { + shared_config.set_option_integer("animated_emoji_zoom", static_cast(animated_emoji_zoom * 1e9)); + } if (animation_search_provider.empty()) { shared_config.set_option_empty("animation_search_provider"); } else { diff --git a/td/telegram/JsonValue.cpp b/td/telegram/JsonValue.cpp index 110bf35e7..a9a5838fe 100644 --- a/td/telegram/JsonValue.cpp +++ b/td/telegram/JsonValue.cpp @@ -217,6 +217,15 @@ int32 get_json_value_int(telegram_api::object_ptr &&jso return 0; } +double get_json_value_double(telegram_api::object_ptr &&json_value, Slice name) { + CHECK(json_value != nullptr); + if (json_value->get_id() == telegram_api::jsonNumber::ID) { + return static_cast(json_value.get())->value_; + } + LOG(ERROR) << "Expected Double as " << name << ", but found " << to_string(json_value); + return 0.0; +} + string get_json_value_string(telegram_api::object_ptr &&json_value, Slice name) { CHECK(json_value != nullptr); if (json_value->get_id() == telegram_api::jsonString::ID) { diff --git a/td/telegram/JsonValue.h b/td/telegram/JsonValue.h index 51b1a748d..4adb8b84c 100644 --- a/td/telegram/JsonValue.h +++ b/td/telegram/JsonValue.h @@ -30,6 +30,8 @@ bool get_json_value_bool(telegram_api::object_ptr &&jso int32 get_json_value_int(telegram_api::object_ptr &&json_value, Slice name); +double get_json_value_double(telegram_api::object_ptr &&json_value, Slice name); + string get_json_value_string(telegram_api::object_ptr &&json_value, Slice name); } // namespace td diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 0d6f72ef2..30edd3023 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1233,6 +1233,8 @@ class StickersManager::UploadStickerFileCallback final : public FileManager::Upl StickersManager::StickersManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { upload_sticker_file_callback_ = std::make_shared(); + on_update_animated_emoji_zoom(); + on_update_recent_stickers_limit( narrow_cast(G()->shared_config().get_option_integer("recent_stickers_limit", 200))); on_update_favorite_stickers_limit( @@ -1710,7 +1712,8 @@ vector> StickersManager::get_sticke return result; } -tl_object_ptr StickersManager::get_sticker_object(FileId file_id) const { +tl_object_ptr StickersManager::get_sticker_object(FileId file_id, bool for_animated_emoji, + bool for_clicked_animated_emoji) const { if (!file_id.is_valid()) { return nullptr; } @@ -1746,11 +1749,17 @@ tl_object_ptr StickersManager::get_sticker_object(FileId file_i } } auto thumbnail_object = get_thumbnail_object(td_->file_manager_.get(), thumbnail, thumbnail_format); + int32 width = sticker->dimensions.width; + int32 height = sticker->dimensions.height; + if (sticker->is_animated && (for_animated_emoji || for_clicked_animated_emoji)) { + double zoom = for_clicked_animated_emoji ? 3 * animated_emoji_zoom_ : animated_emoji_zoom_; + width = static_cast(width * zoom + 0.5); + height = static_cast(height * zoom + 0.5); + } return make_tl_object( - sticker->set_id.get(), sticker->dimensions.width, sticker->dimensions.height, sticker->alt, sticker->is_animated, - sticker->is_mask, std::move(mask_position), - get_sticker_minithumbnail(sticker->minithumbnail, sticker->set_id, document_id), std::move(thumbnail_object), - td_->file_manager_->get_file_object(file_id)); + sticker->set_id.get(), width, height, sticker->alt, sticker->is_animated, sticker->is_mask, + std::move(mask_position), get_sticker_minithumbnail(sticker->minithumbnail, sticker->set_id, document_id), + std::move(thumbnail_object), td_->file_manager_->get_file_object(file_id)); } tl_object_ptr StickersManager::get_stickers_object(const vector &sticker_ids) const { @@ -1787,7 +1796,7 @@ tl_object_ptr StickersManager::get_dice_stickers_object(co } auto get_sticker = [&](int32 value) { - return get_sticker_object(sticker_set->sticker_ids[value]); + return get_sticker_object(sticker_set->sticker_ids[value], true); }; if (emoji == "๐ŸŽฐ") { @@ -2011,7 +2020,7 @@ td_api::object_ptr StickersManager::get_message_content_ auto sound_file_id = it != emoji_messages_.end() ? it->second.sound_file_id : get_animated_emoji_sound_file_id(emoji); return td_api::make_object( - emoji, get_sticker_object(animated_sticker.first), get_color_replacements_object(animated_sticker.second), + emoji, get_sticker_object(animated_sticker.first, true), get_color_replacements_object(animated_sticker.second), sound_file_id.is_valid() ? td_->file_manager_->get_file_object(sound_file_id) : nullptr); } return td_api::make_object( @@ -4380,7 +4389,7 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic } if (now >= next_click_animated_emoji_message_time_) { next_click_animated_emoji_message_time_ = now + MIN_ANIMATED_EMOJI_CLICK_DELAY; - promise.set_value(get_sticker_object(result.second)); + promise.set_value(get_sticker_object(result.second, false, true)); } else { create_actor("SendClickAnimatedEmojiMessageResponse", next_click_animated_emoji_message_time_ - now, PromiseCreator::lambda([actor_id = actor_id(this), sticker_id = result.second, @@ -4396,7 +4405,7 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic void StickersManager::send_click_animated_emoji_message_response( FileId sticker_id, Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); - promise.set_value(get_sticker_object(sticker_id)); + promise.set_value(get_sticker_object(sticker_id, false, true)); } void StickersManager::timeout_expired() { @@ -4614,9 +4623,10 @@ void StickersManager::send_update_animated_emoji_clicked(FullMessageId full_mess return; } - send_closure(G()->td(), &Td::send_update, - td_api::make_object( - dialog_id.get(), full_message_id.get_message_id().get(), get_sticker_object(sticker_id))); + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + dialog_id.get(), full_message_id.get_message_id().get(), get_sticker_object(sticker_id, false, true))); } void StickersManager::view_featured_sticker_sets(const vector &sticker_set_ids) { @@ -6429,6 +6439,11 @@ void StickersManager::save_recent_stickers_to_database(bool is_attached) { } } +void StickersManager::on_update_animated_emoji_zoom() { + animated_emoji_zoom_ = + static_cast(G()->shared_config().get_option_integer("animated_emoji_zoom", 625000000)) * 1e-9; +} + void StickersManager::on_update_recent_stickers_limit(int32 recent_stickers_limit) { if (recent_stickers_limit != recent_stickers_limit_) { if (recent_stickers_limit > 0) { diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index d732aaea5..ad0bc7d9a 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -49,7 +49,8 @@ class StickersManager final : public Actor { void init(); - tl_object_ptr get_sticker_object(FileId file_id) const; + tl_object_ptr get_sticker_object(FileId file_id, bool for_animated_emoji = false, + bool for_clicked_animated_emoji = false) const; tl_object_ptr get_stickers_object(const vector &sticker_ids) const; @@ -148,6 +149,8 @@ class StickersManager final : public Actor { void on_uninstall_sticker_set(StickerSetId set_id); + void on_update_animated_emoji_zoom(); + void on_update_disable_animated_emojis(); void on_update_dice_emojis(); @@ -838,6 +841,8 @@ class StickersManager final : public Actor { string emoji_sounds_str_; std::unordered_map emoji_sounds_; + double animated_emoji_zoom_ = 0.0; + bool disable_animated_emojis_ = false; }; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index ca2d8bbbb..04162fe1e 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3265,7 +3265,8 @@ void Td::on_result(NetQueryPtr query) { bool Td::is_internal_config_option(Slice name) { switch (name[0]) { case 'a': - return name == "animation_search_emojis" || name == "animation_search_provider" || name == "auth"; + return name == "animated_emoji_zoom" || name == "animation_search_emojis" || + name == "animation_search_provider" || name == "auth"; case 'b': return name == "base_language_pack_version"; case 'c': @@ -3315,6 +3316,9 @@ void Td::on_config_option_updated(const string &name) { return animations_manager_->on_update_animation_search_emojis(G()->shared_config().get_option_string(name)); } else if (name == "animation_search_provider") { return animations_manager_->on_update_animation_search_provider(G()->shared_config().get_option_string(name)); + } else if (name == "animated_emoji_zoom") { + // update animated emoji zoom only at launch + return; } else if (name == "recent_stickers_limit") { return stickers_manager_->on_update_recent_stickers_limit( narrow_cast(G()->shared_config().get_option_integer(name))); From 34d77c7febb927737508a76e2e837b21f06e1b2e Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 14 Oct 2021 00:34:28 +0300 Subject: [PATCH 29/82] Fix drop of pending_join_request_count. --- td/telegram/ContactsManager.cpp | 4 ++-- td/telegram/MessagesManager.cpp | 34 ++++++++++++++++++++------------- td/telegram/MessagesManager.h | 4 ++++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index beb963220..01cdad0cb 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -9976,7 +9976,7 @@ void ContactsManager::update_chat(Chat *c, ChatId chat_id, bool from_binlog, boo } if (c->is_status_changed) { if (!c->status.can_manage_invite_links()) { - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(chat_id), 0); + td_->messages_manager_->drop_dialog_pending_join_request_count(DialogId(chat_id)); } c->is_status_changed = false; } @@ -10042,7 +10042,7 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from remove_inactive_channel(channel_id); } if (!c->status.can_manage_invite_links()) { - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(channel_id), 0); + td_->messages_manager_->drop_dialog_pending_join_request_count(DialogId(channel_id)); } c->is_status_changed = false; } diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 67901fae9..98a120c68 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -29887,6 +29887,14 @@ void MessagesManager::set_dialog_theme_name(Dialog *d, string theme_name) { } } +void MessagesManager::drop_dialog_pending_join_request_count(DialogId dialog_id) { + CHECK(dialog_id.is_valid()); + auto d = get_dialog(dialog_id); // called from update_chat/channel, must not create the dialog + if (d != nullptr && d->is_update_new_chat_sent) { + set_dialog_pending_join_request_count(d, 0); + } +} + void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialog_id, int32 pending_join_request_count) { if (!dialog_id.is_valid()) { @@ -29903,38 +29911,37 @@ void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialo set_dialog_pending_join_request_count(d, pending_join_request_count); } -void MessagesManager::set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count) { - CHECK(d != nullptr); - switch (d->dialog_id.get_type()) { +void MessagesManager::fix_pending_join_request_count(DialogId dialog_id, int32 &pending_join_request_count) const { + switch (dialog_id.get_type()) { case DialogType::User: case DialogType::SecretChat: - pending_join_request_count = -1; - break; + pending_join_request_count = 0; + return; case DialogType::Chat: { - auto chat_id = d->dialog_id.get_chat_id(); + auto chat_id = dialog_id.get_chat_id(); auto status = td_->contacts_manager_->get_chat_status(chat_id); if (!status.can_manage_invite_links()) { pending_join_request_count = 0; } - break; + return; } case DialogType::Channel: { - auto channel_id = d->dialog_id.get_channel_id(); + auto channel_id = dialog_id.get_channel_id(); auto status = td_->contacts_manager_->get_channel_permissions(channel_id); if (!status.can_manage_invite_links()) { pending_join_request_count = 0; } - break; + return; } case DialogType::None: default: UNREACHABLE(); } - if (pending_join_request_count < 0) { - LOG(ERROR) << "Receive " << pending_join_request_count << " pending join requests in " << d->dialog_id; - return; - } +} +void MessagesManager::set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count) { + CHECK(d != nullptr); + fix_pending_join_request_count(d->dialog_id, pending_join_request_count); bool is_changed = d->pending_join_request_count != pending_join_request_count; if (!is_changed) { return; @@ -34485,6 +34492,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&d, on_dialog_updated(dialog_id, "pending update_dialog_group_call"); } } + fix_pending_join_request_count(dialog_id, d->pending_join_request_count); if (!is_loaded_from_database) { CHECK(order == DEFAULT_ORDER); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index cb04ee7ae..4d887006f 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -779,6 +779,8 @@ class MessagesManager final : public Actor { void on_dialog_linked_channel_updated(DialogId dialog_id, ChannelId old_linked_channel_id, ChannelId new_linked_channel_id) const; + void drop_dialog_pending_join_request_count(DialogId dialog_id); + void on_resolved_username(const string &username, DialogId dialog_id); void drop_username(const string &username); @@ -2441,6 +2443,8 @@ class MessagesManager final : public Actor { void set_dialog_theme_name(Dialog *d, string theme_name); + void fix_pending_join_request_count(DialogId dialog_id, int32 &pending_join_request_count) const; + void set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count); void repair_dialog_scheduled_messages(Dialog *d); From bcf03164324e4ac8b482ef2ed42a75839edbb06a Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 14 Oct 2021 01:06:12 +0300 Subject: [PATCH 30/82] Zoom sticker's outline. --- td/telegram/StickersManager.cpp | 15 ++++++++------- td/telegram/StickersManager.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 30edd3023..0139381a2 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1475,7 +1475,7 @@ tl_object_ptr StickersManager::get_mask_point_object(int32 po } vector> StickersManager::get_sticker_minithumbnail( - CSlice path, StickerSetId sticker_set_id, int64 document_id) { + CSlice path, StickerSetId sticker_set_id, int64 document_id, double zoom) { if (path.empty()) { return {}; } @@ -1530,8 +1530,8 @@ vector> StickersManager::get_sticke } return sign * res; }; - auto make_point = [](double x, double y) { - return td_api::make_object(x, y); + auto make_point = [zoom](double x, double y) { + return td_api::make_object(x * zoom, y * zoom); }; vector> result; @@ -1751,14 +1751,15 @@ tl_object_ptr StickersManager::get_sticker_object(FileId file_i auto thumbnail_object = get_thumbnail_object(td_->file_manager_.get(), thumbnail, thumbnail_format); int32 width = sticker->dimensions.width; int32 height = sticker->dimensions.height; + double zoom = 1.0; if (sticker->is_animated && (for_animated_emoji || for_clicked_animated_emoji)) { - double zoom = for_clicked_animated_emoji ? 3 * animated_emoji_zoom_ : animated_emoji_zoom_; + zoom = for_clicked_animated_emoji ? 3 * animated_emoji_zoom_ : animated_emoji_zoom_; width = static_cast(width * zoom + 0.5); height = static_cast(height * zoom + 0.5); } return make_tl_object( sticker->set_id.get(), width, height, sticker->alt, sticker->is_animated, sticker->is_mask, - std::move(mask_position), get_sticker_minithumbnail(sticker->minithumbnail, sticker->set_id, document_id), + std::move(mask_position), get_sticker_minithumbnail(sticker->minithumbnail, sticker->set_id, document_id, zoom), std::move(thumbnail_object), td_->file_manager_->get_file_object(file_id)); } @@ -1863,7 +1864,7 @@ tl_object_ptr StickersManager::get_sticker_set_object(Sticke sticker_set->is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp); return make_tl_object( sticker_set->id.get(), sticker_set->title, sticker_set->short_name, std::move(thumbnail), - get_sticker_minithumbnail(sticker_set->minithumbnail, sticker_set->id, -2), + get_sticker_minithumbnail(sticker_set->minithumbnail, sticker_set->id, -2, 1.0), sticker_set->is_installed && !sticker_set->is_archived, sticker_set->is_archived, sticker_set->is_official, sticker_set->is_animated, sticker_set->is_masks, sticker_set->is_viewed, std::move(stickers), std::move(emojis)); } @@ -1909,7 +1910,7 @@ tl_object_ptr StickersManager::get_sticker_set_info_obje sticker_set->is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp); return make_tl_object( sticker_set->id.get(), sticker_set->title, sticker_set->short_name, std::move(thumbnail), - get_sticker_minithumbnail(sticker_set->minithumbnail, sticker_set->id, -3), + get_sticker_minithumbnail(sticker_set->minithumbnail, sticker_set->id, -3, 1.0), sticker_set->is_installed && !sticker_set->is_archived, sticker_set->is_archived, sticker_set->is_official, sticker_set->is_animated, sticker_set->is_masks, sticker_set->is_viewed, sticker_set->was_loaded ? narrow_cast(sticker_set->sticker_ids.size()) : sticker_set->sticker_count, diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index ad0bc7d9a..db1089413 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -442,7 +442,7 @@ class StickersManager final : public Actor { static vector> get_sticker_minithumbnail(CSlice path, StickerSetId sticker_set_id, - int64 document_id); + int64 document_id, double zoom); static tl_object_ptr get_mask_point_object(int32 point); From c69293e1ccc6c36f3134475a1bdb821db6d07ce0 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 14 Oct 2021 15:44:21 +0300 Subject: [PATCH 31/82] Rename voice chats to video chats. --- td/generate/scheme/td_api.tl | 96 +++++++++++++++---------------- td/telegram/DialogParticipant.cpp | 2 +- td/telegram/LinkManager.cpp | 2 +- td/telegram/MessageContent.cpp | 8 +-- td/telegram/MessagesManager.cpp | 44 +++++++------- td/telegram/MessagesManager.h | 4 +- td/telegram/Td.cpp | 6 +- td/telegram/Td.h | 6 +- td/telegram/cli.cpp | 6 +- test/link.cpp | 30 +++++----- 10 files changed, 102 insertions(+), 102 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2bd065098..288dff8f1 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -461,7 +461,7 @@ chatPermissions can_send_messages:Bool can_send_media_messages:Bool can_send_pol //@is_member True, if the user is a member of the chat chatMemberStatusCreator custom_title:string is_anonymous:Bool is_member:Bool = ChatMemberStatus; -//@description The user is a member of the chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage voice chats. In supergroups and channels, there are more detailed options for administrator privileges +//@description The user is a member of the chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage video chats. In supergroups and channels, there are more detailed options for administrator privileges //@custom_title A custom title of the administrator; 0-16 characters without emojis; applicable to supergroups only //@can_be_edited True, if the current user can edit the administrator privileges for the called user //@can_manage_chat True, if the administrator can get chat event log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other privilege; applicable to supergroups and channels only @@ -473,9 +473,9 @@ chatMemberStatusCreator custom_title:string is_anonymous:Bool is_member:Bool = C //@can_restrict_members True, if the administrator can restrict, ban, or unban chat members; always true for channels //@can_pin_messages True, if the administrator can pin messages; applicable to basic groups and supergroups only //@can_promote_members True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them -//@can_manage_voice_chats True, if the administrator can manage voice chats +//@can_manage_video_chats True, if the administrator can manage video chats //@is_anonymous True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only -chatMemberStatusAdministrator custom_title:string can_be_edited:Bool can_manage_chat:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_promote_members:Bool can_manage_voice_chats:Bool is_anonymous:Bool = ChatMemberStatus; +chatMemberStatusAdministrator custom_title:string can_be_edited:Bool can_manage_chat:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_promote_members:Bool can_manage_video_chats:Bool is_anonymous:Bool = ChatMemberStatus; //@description The user is a member of the chat, without any additional privileges or restrictions chatMemberStatusMember = ChatMemberStatus; @@ -489,7 +489,7 @@ chatMemberStatusRestricted is_member:Bool restricted_until_date:int32 permission //@description The user or the chat is not a chat member chatMemberStatusLeft = ChatMemberStatus; -//@description The user or the chat was banned (and hence is not a member of the chat). Implies the user can't return to the chat, view messages, or be used as a participant identifier to join a voice chat of the chat +//@description The user or the chat was banned (and hence is not a member of the chat). Implies the user can't return to the chat, view messages, or be used as a participant identifier to join a video chat of the chat //@banned_until_date Point in time (Unix timestamp) when the user will be unbanned; 0 if never. If the user is banned for more than 366 days or for less than 30 seconds from the current time, the user is considered to be banned forever. Always 0 in basic groups chatMemberStatusBanned banned_until_date:int32 = ChatMemberStatus; @@ -923,11 +923,11 @@ chatSourcePublicServiceAnnouncement type:string text:string = ChatSource; chatPosition list:ChatList order:int64 is_pinned:Bool source:ChatSource = ChatPosition; -//@description Describes a voice chat -//@group_call_id Group call identifier of an active voice chat; 0 if none. Full information about the voice chat can be received through the method getGroupCall -//@has_participants True, if the voice chat has participants -//@default_participant_id Default group call participant identifier to join the voice chat; may be null -voiceChat group_call_id:int32 has_participants:Bool default_participant_id:MessageSender = VoiceChat; +//@description Describes a video chat +//@group_call_id Group call identifier of an active video chat; 0 if none. Full information about the video chat can be received through the method getGroupCall +//@has_participants True, if the video chat has participants +//@default_participant_id Default group call participant identifier to join the video chat; may be null +videoChat group_call_id:int32 has_participants:Bool default_participant_id:MessageSender = VideoChat; //@description A chat. (Can be a private chat, basic group, supergroup, or secret chat) @@ -953,12 +953,12 @@ voiceChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@message_ttl_setting Current message Time To Live setting (self-destruct timer) for the chat; 0 if not defined. TTL is counted from the time message or its content is viewed in secret chats and from the send date in other chats //@theme_name If non-empty, name of a theme, set for the chat //@action_bar Describes actions which must be possible to do through a chat action bar; may be null -//@voice_chat Contains information about voice chat of the chat +//@video_chat Contains information about video chat of the chat //@pending_join_request_count Number of pending join requests, waiting administrator's approval //@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat //@draft_message A draft of a message in the chat; may be null //@client_data Contains application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used -chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar voice_chat:voiceChat pending_join_request_count:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; +chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar video_chat:videoChat pending_join_request_count:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; //@description Represents a list of chats @total_count Approximate total count of chats found @chat_ids List of chat identifiers chats total_count:int32 chat_ids:vector = Chats; @@ -1751,17 +1751,17 @@ messageInvoice title:string description:string photo:photo currency:string total //@description A message with information about an ended call @is_video True, if the call was a video call @discard_reason Reason why the call was discarded @duration Call duration, in seconds messageCall is_video:Bool discard_reason:CallDiscardReason duration:int32 = MessageContent; -//@description A new voice chat was scheduled @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall @start_date Point in time (Unix timestamp) when the group call is supposed to be started by an administrator -messageVoiceChatScheduled group_call_id:int32 start_date:int32 = MessageContent; +//@description A new video chat was scheduled @group_call_id Identifier of the video chat. The video chat can be received through the method getGroupCall @start_date Point in time (Unix timestamp) when the group call is supposed to be started by an administrator +messageVideoChatScheduled group_call_id:int32 start_date:int32 = MessageContent; -//@description A newly created voice chat @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall -messageVoiceChatStarted group_call_id:int32 = MessageContent; +//@description A newly created video chat @group_call_id Identifier of the video chat. The video chat can be received through the method getGroupCall +messageVideoChatStarted group_call_id:int32 = MessageContent; -//@description A message with information about an ended voice chat @duration Call duration, in seconds -messageVoiceChatEnded duration:int32 = MessageContent; +//@description A message with information about an ended video chat @duration Call duration, in seconds +messageVideoChatEnded duration:int32 = MessageContent; -//@description A message with information about an invite to a voice chat @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall @user_ids Invited user identifiers -messageInviteVoiceChatParticipants group_call_id:int32 user_ids:vector = MessageContent; +//@description A message with information about an invite to a video chat @group_call_id Identifier of the video chat. The video chat can be received through the method getGroupCall @user_ids Invited user identifiers +messageInviteVideoChatParticipants group_call_id:int32 user_ids:vector = MessageContent; //@description A newly created basic group @title Title of the basic group @member_user_ids User identifiers of members in the basic group messageBasicGroupChatCreate title:string member_user_ids:vector = MessageContent; @@ -2579,20 +2579,20 @@ chatEventInviteLinkRevoked invite_link:chatInviteLink = ChatEventAction; //@description A revoked chat invite link was deleted @invite_link The invite link chatEventInviteLinkDeleted invite_link:chatInviteLink = ChatEventAction; -//@description A voice chat was created @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall -chatEventVoiceChatCreated group_call_id:int32 = ChatEventAction; +//@description A video chat was created @group_call_id Identifier of the video chat. The video chat can be received through the method getGroupCall +chatEventVideoChatCreated group_call_id:int32 = ChatEventAction; -//@description A voice chat was discarded @group_call_id Identifier of the voice chat. The voice chat can be received through the method getGroupCall -chatEventVoiceChatDiscarded group_call_id:int32 = ChatEventAction; +//@description A video chat was discarded @group_call_id Identifier of the video chat. The video chat can be received through the method getGroupCall +chatEventVideoChatDiscarded group_call_id:int32 = ChatEventAction; -//@description A voice chat participant was muted or unmuted @participant_id Identifier of the affected group call participant @is_muted New value of is_muted -chatEventVoiceChatParticipantIsMutedToggled participant_id:MessageSender is_muted:Bool = ChatEventAction; +//@description A video chat participant was muted or unmuted @participant_id Identifier of the affected group call participant @is_muted New value of is_muted +chatEventVideoChatParticipantIsMutedToggled participant_id:MessageSender is_muted:Bool = ChatEventAction; -//@description A voice chat participant volume level was changed @participant_id Identifier of the affected group call participant @volume_level New value of volume_level; 1-20000 in hundreds of percents -chatEventVoiceChatParticipantVolumeLevelChanged participant_id:MessageSender volume_level:int32 = ChatEventAction; +//@description A video chat participant volume level was changed @participant_id Identifier of the affected group call participant @volume_level New value of volume_level; 1-20000 in hundreds of percents +chatEventVideoChatParticipantVolumeLevelChanged participant_id:MessageSender volume_level:int32 = ChatEventAction; -//@description The mute_new_participants setting of a voice chat was toggled @mute_new_participants New value of the mute_new_participants setting -chatEventVoiceChatMuteNewParticipantsToggled mute_new_participants:Bool = ChatEventAction; +//@description The mute_new_participants setting of a video chat was toggled @mute_new_participants New value of the mute_new_participants setting +chatEventVideoChatMuteNewParticipantsToggled mute_new_participants:Bool = ChatEventAction; //@description Represents a chat event @id Chat event identifier @date Point in time (Unix timestamp) when the event happened @user_id Identifier of the user who performed the action that triggered the event @action Action performed by the user chatEvent id:int64 date:int32 user_id:int53 action:ChatEventAction = ChatEvent; @@ -2612,8 +2612,8 @@ chatEvents events:vector = ChatEvents; //@info_changes True, if changes in chat information need to be returned //@setting_changes True, if changes in chat settings need to be returned //@invite_link_changes True, if changes to invite links need to be returned -//@voice_chat_changes True, if voice chat actions need to be returned -chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool member_joins:Bool member_leaves:Bool member_invites:Bool member_promotions:Bool member_restrictions:Bool info_changes:Bool setting_changes:Bool invite_link_changes:Bool voice_chat_changes:Bool = ChatEventLogFilters; +//@video_chat_changes True, if video chat actions need to be returned +chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool member_joins:Bool member_leaves:Bool member_invites:Bool member_promotions:Bool member_restrictions:Bool info_changes:Bool setting_changes:Bool invite_link_changes:Bool video_chat_changes:Bool = ChatEventLogFilters; //@class LanguagePackStringValue @description Represents the value of a string in a language pack @@ -3202,10 +3202,10 @@ internalLinkTypeThemeSettings = InternalLinkType; //@description The link is an unknown tg: link. Call getDeepLinkInfo to process the link @link Link to be passed to getDeepLinkInfo internalLinkTypeUnknownDeepLink link:string = InternalLinkType; -//@description The link is a link to a voice chat. Call searchPublicChat with the given chat username, and then joinGoupCall with the given invite hash to process the link -//@chat_username Username of the chat with the voice chat @invite_hash If non-empty, invite hash to be used to join the voice chat without being muted by administrators -//@is_live_stream True, if the voice chat is expected to be a live stream in a channel or a broadcast group -internalLinkTypeVoiceChat chat_username:string invite_hash:string is_live_stream:Bool = InternalLinkType; +//@description The link is a link to a video chat. Call searchPublicChat with the given chat username, and then joinGoupCall with the given invite hash to process the link +//@chat_username Username of the chat with the video chat @invite_hash If non-empty, invite hash to be used to join the video chat without being muted by administrators +//@is_live_stream True, if the video chat is expected to be a live stream in a channel or a broadcast group +internalLinkTypeVideoChat chat_username:string invite_hash:string is_live_stream:Bool = InternalLinkType; //@description Contains an HTTPS link to a message in a supergroup or channel @link Message link @is_public True, if the link will work for non-members of the chat @@ -3681,8 +3681,8 @@ updateChatIsBlocked chat_id:int53 is_blocked:Bool = Update; //@description A chat's has_scheduled_messages field has changed @chat_id Chat identifier @has_scheduled_messages New value of has_scheduled_messages updateChatHasScheduledMessages chat_id:int53 has_scheduled_messages:Bool = Update; -//@description A chat voice chat state has changed @chat_id Chat identifier @voice_chat New value of voice_chat -updateChatVoiceChat chat_id:int53 voice_chat:voiceChat = Update; +//@description A chat video chat state has changed @chat_id Chat identifier @video_chat New value of video_chat +updateChatVideoChat chat_id:int53 video_chat:videoChat = Update; //@description The value of the default disable_notification parameter, used when a message is sent to the chat, was changed @chat_id Chat identifier @default_disable_notification The new default_disable_notification value updateChatDefaultDisableNotification chat_id:int53 default_disable_notification:Bool = Update; @@ -4968,17 +4968,17 @@ sendCallRating call_id:int32 rating:int32 comment:string problems:vector = Ok; -//@description Returns invite link to a voice chat in a public chat +//@description Returns invite link to a video chat in a public chat //@group_call_id Group call identifier //@can_self_unmute Pass true if the invite link needs to contain an invite hash, passing which to joinGroupCall would allow the invited user to unmute themselves. Requires groupCall.can_be_managed group call flag getGroupCallInviteLink group_call_id:int32 can_self_unmute:Bool = HttpUrl; diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index d11e3de81..25b4a0a2d 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -422,7 +422,7 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptris_anonymous_, custom_title, true /*st->can_be_edited_*/, st->can_manage_chat_, st->can_change_info_, st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_, st->can_invite_users_, - st->can_restrict_members_, st->can_pin_messages_, st->can_promote_members_, st->can_manage_voice_chats_); + st->can_restrict_members_, st->can_pin_messages_, st->can_promote_members_, st->can_manage_video_chats_); } case td_api::chatMemberStatusMember::ID: return DialogParticipantStatus::Member(); diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index b314f6ce6..711d20a6e 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -360,7 +360,7 @@ class LinkManager::InternalLinkVoiceChat final : public InternalLink { bool is_live_stream_; td_api::object_ptr get_internal_link_type_object() const final { - return td_api::make_object(dialog_username_, invite_hash_, is_live_stream_); + return td_api::make_object(dialog_username_, invite_hash_, is_live_stream_); } public: diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 108d02306..0e2eab7b0 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -4984,19 +4984,19 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::GroupCall: { const auto *m = static_cast(content); if (m->duration >= 0) { - return make_tl_object(m->duration); + return make_tl_object(m->duration); } else { auto group_call_id = td->group_call_manager_->get_group_call_id(m->input_group_call_id, DialogId()).get(); if (m->schedule_date > 0) { - return make_tl_object(group_call_id, m->schedule_date); + return make_tl_object(group_call_id, m->schedule_date); } else { - return make_tl_object(group_call_id); + return make_tl_object(group_call_id); } } } case MessageContentType::InviteToGroupCall: { const auto *m = static_cast(content); - return make_tl_object( + return make_tl_object( td->group_call_manager_->get_group_call_id(m->input_group_call_id, DialogId()).get(), td->contacts_manager_->get_user_ids_object(m->user_ids, "MessageInviteToGroupCall")); } diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 98a120c68..6e5797e85 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -20075,13 +20075,13 @@ string MessagesManager::get_dialog_theme_name(const Dialog *d) const { return d->theme_name; } -td_api::object_ptr MessagesManager::get_voice_chat_object(const Dialog *d) const { +td_api::object_ptr MessagesManager::get_video_chat_object(const Dialog *d) const { auto active_group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, d->dialog_id); auto default_participant_alias = d->default_join_group_call_as_dialog_id.is_valid() - ? get_message_sender_object_const(d->default_join_group_call_as_dialog_id, "get_voice_chat_object") + ? get_message_sender_object_const(d->default_join_group_call_as_dialog_id, "get_video_chat_object") : nullptr; - return make_tl_object(active_group_call_id.get(), + return make_tl_object(active_group_call_id.get(), active_group_call_id.is_valid() ? !d->is_group_call_empty : false, std::move(default_participant_alias)); } @@ -20156,7 +20156,7 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * d->last_read_inbox_message_id.get(), d->last_read_outbox_message_id.get(), d->unread_mention_count, get_chat_notification_settings_object(&d->notification_settings), d->message_ttl_setting.get_message_ttl_setting_object(), get_dialog_theme_name(d), get_chat_action_bar_object(d), - get_voice_chat_object(d), d->pending_join_request_count, d->reply_markup_message_id.get(), + get_video_chat_object(d), d->pending_join_request_count, d->reply_markup_message_id.get(), std::move(draft_message), d->client_data); } @@ -28864,12 +28864,12 @@ void MessagesManager::send_update_chat_pending_join_request_count(const Dialog * d->pending_join_request_count)); } -void MessagesManager::send_update_chat_voice_chat(const Dialog *d) { +void MessagesManager::send_update_chat_video_chat(const Dialog *d) { CHECK(d != nullptr); - LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_voice_chat"; - on_dialog_updated(d->dialog_id, "send_update_chat_voice_chat"); + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_video_chat"; + on_dialog_updated(d->dialog_id, "send_update_chat_video_chat"); send_closure(G()->td(), &Td::send_update, - td_api::make_object(d->dialog_id.get(), get_voice_chat_object(d))); + td_api::make_object(d->dialog_id.get(), get_video_chat_object(d))); } void MessagesManager::send_update_chat_message_ttl_setting(const Dialog *d) { @@ -30144,10 +30144,10 @@ void MessagesManager::on_update_dialog_group_call(DialogId dialog_id, bool has_a d->active_group_call_id = InputGroupCallId(); d->has_active_group_call = false; d->is_group_call_empty = false; - send_update_chat_voice_chat(d); + send_update_chat_video_chat(d); } else if (d->has_active_group_call && has_active_group_call) { d->is_group_call_empty = is_group_call_empty; - send_update_chat_voice_chat(d); + send_update_chat_video_chat(d); } else { d->has_active_group_call = has_active_group_call; d->is_group_call_empty = is_group_call_empty; @@ -30176,7 +30176,7 @@ void MessagesManager::on_update_dialog_group_call_id(DialogId dialog_id, InputGr d->is_group_call_empty = false; } } - send_update_chat_voice_chat(d); + send_update_chat_video_chat(d); } } @@ -30206,7 +30206,7 @@ void MessagesManager::on_update_dialog_default_join_group_call_as_dialog_id(Dial if (d->default_join_group_call_as_dialog_id != default_join_as_dialog_id) { d->default_join_group_call_as_dialog_id = default_join_as_dialog_id; - send_update_chat_voice_chat(d); + send_update_chat_video_chat(d); } } @@ -31710,7 +31710,7 @@ tl_object_ptr MessagesManager::get_ch if (filters->invite_link_changes_) { flags |= telegram_api::channelAdminLogEventsFilter::INVITES_MASK; } - if (filters->voice_chat_changes_) { + if (filters->video_chat_changes_) { flags |= telegram_api::channelAdminLogEventsFilter::GROUP_CALL_MASK; } @@ -32029,7 +32029,7 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob if (!input_group_call_id.is_valid()) { return nullptr; } - return make_tl_object( + return make_tl_object( td_->group_call_manager_->get_group_call_id(input_group_call_id, DialogId(channel_id)).get()); } case telegram_api::channelAdminLogEventActionDiscardGroupCall::ID: { @@ -32038,7 +32038,7 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob if (!input_group_call_id.is_valid()) { return nullptr; } - return make_tl_object( + return make_tl_object( td_->group_call_manager_->get_group_call_id(input_group_call_id, DialogId(channel_id)).get()); } case telegram_api::channelAdminLogEventActionParticipantMute::ID: { @@ -32047,8 +32047,8 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob if (!participant.is_valid()) { return nullptr; } - return make_tl_object( - get_message_sender_object(participant.dialog_id, "chatEventVoiceChatParticipantIsMutedToggled"), true); + return make_tl_object( + get_message_sender_object(participant.dialog_id, "chatEventVideoChatParticipantIsMutedToggled"), true); } case telegram_api::channelAdminLogEventActionParticipantUnmute::ID: { auto action = move_tl_object_as(action_ptr); @@ -32056,8 +32056,8 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob if (!participant.is_valid()) { return nullptr; } - return make_tl_object( - get_message_sender_object(participant.dialog_id, "chatEventVoiceChatParticipantIsMutedToggled"), false); + return make_tl_object( + get_message_sender_object(participant.dialog_id, "chatEventVideoChatParticipantIsMutedToggled"), false); } case telegram_api::channelAdminLogEventActionParticipantVolume::ID: { auto action = move_tl_object_as(action_ptr); @@ -32065,13 +32065,13 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob if (!participant.is_valid()) { return nullptr; } - return make_tl_object( - get_message_sender_object(participant.dialog_id, "chatEventVoiceChatParticipantVolumeLevelChanged"), + return make_tl_object( + get_message_sender_object(participant.dialog_id, "chatEventVideoChatParticipantVolumeLevelChanged"), participant.volume_level); } case telegram_api::channelAdminLogEventActionToggleGroupCallSetting::ID: { auto action = move_tl_object_as(action_ptr); - return make_tl_object(action->join_muted_); + return make_tl_object(action->join_muted_); } case telegram_api::channelAdminLogEventActionChangeHistoryTTL::ID: { auto action = move_tl_object_as(action_ptr); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 4d887006f..56c5074f9 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -2344,7 +2344,7 @@ class MessagesManager final : public Actor { void send_update_chat_pending_join_request_count(const Dialog *d); - void send_update_chat_voice_chat(const Dialog *d); + void send_update_chat_video_chat(const Dialog *d); void send_update_chat_message_ttl_setting(const Dialog *d); @@ -2539,7 +2539,7 @@ class MessagesManager final : public Actor { string get_dialog_theme_name(const Dialog *d) const; - td_api::object_ptr get_voice_chat_object(const Dialog *d) const; + td_api::object_ptr get_video_chat_object(const Dialog *d) const; td_api::object_ptr get_chat_object(const Dialog *d) const; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 04162fe1e..1d76b82ce 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5773,13 +5773,13 @@ void Td::on_request(uint64 id, td_api::sendCallDebugInformation &request) { std::move(request.debug_information_), std::move(promise)); } -void Td::on_request(uint64 id, const td_api::getVoiceChatAvailableParticipants &request) { +void Td::on_request(uint64 id, const td_api::getVideoChatAvailableParticipants &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); group_call_manager_->get_group_call_join_as(DialogId(request.chat_id_), std::move(promise)); } -void Td::on_request(uint64 id, const td_api::setVoiceChatDefaultParticipant &request) { +void Td::on_request(uint64 id, const td_api::setVideoChatDefaultParticipant &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); group_call_manager_->set_group_call_default_join_as( @@ -5787,7 +5787,7 @@ void Td::on_request(uint64 id, const td_api::setVoiceChatDefaultParticipant &req std::move(promise)); } -void Td::on_request(uint64 id, td_api::createVoiceChat &request) { +void Td::on_request(uint64 id, td_api::createVideoChat &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.title_); CREATE_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 964a71d8d..63896f421 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -724,11 +724,11 @@ class Td final : public Actor { void on_request(uint64 id, td_api::sendCallDebugInformation &request); - void on_request(uint64 id, const td_api::getVoiceChatAvailableParticipants &request); + void on_request(uint64 id, const td_api::getVideoChatAvailableParticipants &request); - void on_request(uint64 id, const td_api::setVoiceChatDefaultParticipant &request); + void on_request(uint64 id, const td_api::setVideoChatDefaultParticipant &request); - void on_request(uint64 id, td_api::createVoiceChat &request); + void on_request(uint64 id, td_api::createVideoChat &request); void on_request(uint64 id, const td_api::getGroupCall &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index d90918443..f15f984a4 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2780,19 +2780,19 @@ class CliClient final : public Actor { } else if (op == "scdi" || op == "SendCallDebugInformation") { send_request(td_api::make_object(as_call_id(args), "{}")); } else if (op == "gvcap") { - send_request(td_api::make_object(as_chat_id(args))); + send_request(td_api::make_object(as_chat_id(args))); } else if (op == "svcdp") { string chat_id; string participant_id; get_args(args, chat_id, participant_id); - send_request(td_api::make_object(as_chat_id(chat_id), + send_request(td_api::make_object(as_chat_id(chat_id), as_message_sender(participant_id))); } else if (op == "cvc") { string chat_id; string title; int32 start_date; get_args(args, chat_id, title, start_date); - send_request(td_api::make_object(as_chat_id(chat_id), title, start_date)); + send_request(td_api::make_object(as_chat_id(chat_id), title, start_date)); } else if (op == "ggc") { send_request(td_api::make_object(as_group_call_id(args))); } else if (op == "ggcss") { diff --git a/test/link.cpp b/test/link.cpp index 2af303cce..86c9afd1a 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -171,8 +171,8 @@ TEST(Link, parse_internal_link) { auto unknown_deep_link = [](const td::string &link) { return td::td_api::make_object(link); }; - auto voice_chat = [](const td::string &chat_username, const td::string &invite_hash, bool is_live_stream) { - return td::td_api::make_object(chat_username, invite_hash, is_live_stream); + auto video_chat = [](const td::string &chat_username, const td::string &invite_hash, bool is_live_stream) { + return td::td_api::make_object(chat_username, invite_hash, is_live_stream); }; parse_internal_link("t.me/levlam/1", message("tg:resolve?domain=levlam&post=1")); @@ -524,27 +524,27 @@ TEST(Link, parse_internal_link) { parse_internal_link("tg:socks?server=google.com&port=8%30&user=&pass=2", proxy_socks("google.com", 80, "", "2")); parse_internal_link("tg:socks?server=google.com&port=80&user=1&pass=2", proxy_socks("google.com", 80, "1", "2")); - parse_internal_link("tg:resolve?domain=username&voice%63hat=aasdasd", voice_chat("username", "aasdasd", false)); - parse_internal_link("tg:resolve?domain=username&video%63hat=aasdasd", voice_chat("username", "aasdasd", false)); - parse_internal_link("tg:resolve?domain=username&livestream=aasdasd", voice_chat("username", "aasdasd", true)); - parse_internal_link("TG://resolve?domain=username&voicechat=", voice_chat("username", "", false)); + parse_internal_link("tg:resolve?domain=username&voice%63hat=aasdasd", video_chat("username", "aasdasd", false)); + parse_internal_link("tg:resolve?domain=username&video%63hat=aasdasd", video_chat("username", "aasdasd", false)); + parse_internal_link("tg:resolve?domain=username&livestream=aasdasd", video_chat("username", "aasdasd", true)); + parse_internal_link("TG://resolve?domain=username&voicechat=", video_chat("username", "", false)); parse_internal_link("TG://test@resolve?domain=username&voicechat=", nullptr); parse_internal_link("tg:resolve:80?domain=username&voicechat=", nullptr); parse_internal_link("tg:http://resolve?domain=username&voicechat=", nullptr); parse_internal_link("tg:https://resolve?domain=username&voicechat=", nullptr); parse_internal_link("tg:resolve?domain=&voicechat=", unknown_deep_link("tg://resolve?domain=&voicechat=")); - parse_internal_link("tg:resolve?domain=telegram&&&&&&&voicechat=%30", voice_chat("telegram", "0", false)); + parse_internal_link("tg:resolve?domain=telegram&&&&&&&voicechat=%30", video_chat("telegram", "0", false)); - parse_internal_link("t.me/username/0/a//s/as?voicechat=", voice_chat("username", "", false)); - parse_internal_link("t.me/username/0/a//s/as?videochat=2", voice_chat("username", "2", false)); - parse_internal_link("t.me/username/0/a//s/as?livestream=3", voice_chat("username", "3", true)); - parse_internal_link("t.me/username/aasdas?test=1&voicechat=#12312", voice_chat("username", "", false)); - parse_internal_link("t.me/username/0?voicechat=", voice_chat("username", "", false)); - parse_internal_link("t.me/username/-1?voicechat=asdasd", voice_chat("username", "asdasd", false)); - parse_internal_link("t.me/username?voicechat=", voice_chat("username", "", false)); + parse_internal_link("t.me/username/0/a//s/as?voicechat=", video_chat("username", "", false)); + parse_internal_link("t.me/username/0/a//s/as?videochat=2", video_chat("username", "2", false)); + parse_internal_link("t.me/username/0/a//s/as?livestream=3", video_chat("username", "3", true)); + parse_internal_link("t.me/username/aasdas?test=1&voicechat=#12312", video_chat("username", "", false)); + parse_internal_link("t.me/username/0?voicechat=", video_chat("username", "", false)); + parse_internal_link("t.me/username/-1?voicechat=asdasd", video_chat("username", "asdasd", false)); + parse_internal_link("t.me/username?voicechat=", video_chat("username", "", false)); parse_internal_link("t.me/username#voicechat=asdas", public_chat("username")); parse_internal_link("t.me//username?voicechat=", nullptr); - parse_internal_link("https://telegram.dog/tele%63ram?voi%63e%63hat=t%63st", voice_chat("telecram", "tcst", false)); + parse_internal_link("https://telegram.dog/tele%63ram?voi%63e%63hat=t%63st", video_chat("telecram", "tcst", false)); parse_internal_link("tg:resolve?domain=username&start=aasdasd", bot_start("username", "aasdasd")); parse_internal_link("TG://resolve?domain=username&start=", bot_start("username", "")); From cf77428fab4438d726493d18dd23e0289e5d4629 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 15 Oct 2021 17:40:30 +0300 Subject: [PATCH 32/82] Add td_api::getChatSparseMessagePositions. --- td/generate/scheme/td_api.tl | 13 +++++ td/telegram/MessagesManager.cpp | 96 ++++++++++++++++++++++++++++++++- td/telegram/MessagesManager.h | 9 ++++ td/telegram/Td.cpp | 10 +++- td/telegram/Td.h | 4 +- td/telegram/cli.cpp | 18 +++++-- 6 files changed, 142 insertions(+), 8 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 288dff8f1..d5017dfef 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -801,6 +801,12 @@ messages total_count:int32 messages:vector = Messages; //@description Contains a list of messages found by a search @total_count Approximate total count of messages found; -1 if unknown @messages List of messages @next_offset The offset for the next request. If empty, there are no more results foundMessages total_count:int32 messages:vector next_offset:string = FoundMessages; +//@description Contains information about a message in a specific position @position 1-based message position in the full list of suitable messages @message_id Message identifier @date Point in time (Unix timestamp) when the message was sent +messagePosition position:int32 message_id:int53 date:int32 = MessagePosition; + +//@description Contains a list of message positions @total_count Total count of messages found @positions List of message positions +messagePositions total_count:int32 positions:vector = MessagePositions; + //@description Describes a sponsored message @id Unique sponsored message identifier @sponsor_chat_id Chat identifier //@link An internal link to be opened when the sponsored message is clicked; may be null. If null, the sponsor chat needs to be opened instead @content Content of the message @@ -4271,6 +4277,13 @@ getActiveLiveLocationMessages = Messages; //@description Returns the last message sent in a chat no later than the specified date @chat_id Chat identifier @date Point in time (Unix timestamp) relative to which to search for messages getChatMessageByDate chat_id:int53 date:int32 = Message; +//@description Returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. Returns the results in reverse chronological order (i.e., in order of decreasing message_id) +//@chat_id Identifier of the chat in which to return information about message positions +//@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention, searchMessagesFilterUnreadMention and searchMessagesFilterFailedToSend are unsupported in this function +//@from_message_id The message identifier from which to return information about message positions +//@limit The expected number of message positions to be returned. A smaller number of positions can be returned, if there are not enough appropriate messages +getChatSparseMessagePositions chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 limit:int32 = MessagePositions; + //@description Returns approximate number of messages of the specified type in the chat @chat_id Identifier of the chat in which to count messages @filter Filter for message content; searchMessagesFilterEmpty is unsupported in this function @return_local If true, returns count that is available locally without sending network requests, returning -1 if the number of messages is unknown getChatMessageCount chat_id:int53 filter:SearchMessagesFilter return_local:Bool = Count; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 6e5797e85..bfd93b4be 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2272,6 +2272,45 @@ class SearchMessagesQuery final : public Td::ResultHandler { } }; +class GetSearchResultPositionsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + MessageSearchFilter filter_; + + public: + explicit GetSearchResultPositionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, int32 limit) { + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + return promise_.set_error(Status::Error(400, "Can't access the chat")); + } + dialog_id_ = dialog_id; + filter_ = filter; + + send_query(G()->net_query_creator().create( + telegram_api::messages_getSearchResultsPositions(std::move(input_peer), get_input_messages_filter(filter), + from_message_id.get_server_message_id().get(), limit))); + } + + void on_result(uint64 id, BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + td->messages_manager_->on_get_dialog_sparse_message_positions(dialog_id_, filter_, result_ptr.move_as_ok(), + std::move(promise_)); + } + + void on_error(uint64 id, Status status) final { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchResultPositionsQuery"); + promise_.set_error(std::move(status)); + } +}; + class GetSearchCountersQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -22215,6 +22254,61 @@ tl_object_ptr MessagesManager::get_dialog_message_by_date_objec return get_message_object(full_message_id, "get_dialog_message_by_date_object"); } +void MessagesManager::get_dialog_sparse_message_positions( + DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, int32 limit, + Promise> &&promise) { + const Dialog *d = get_dialog_force(dialog_id, "get_dialog_sparse_message_positions"); + if (d == nullptr) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + + if (filter == MessageSearchFilter::Empty || filter == MessageSearchFilter::Call || + filter == MessageSearchFilter::MissedCall || filter == MessageSearchFilter::Mention || + filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::FailedToSend || + filter == MessageSearchFilter::Pinned) { + return promise.set_error(Status::Error(400, "The filter is not supported")); + } + + if (from_message_id.is_scheduled()) { + return promise.set_error(Status::Error(400, "Invalid from_message_id specified")); + } + if (!from_message_id.is_valid() || from_message_id > d->last_new_message_id) { + if (d->last_new_message_id.is_valid()) { + from_message_id = d->last_new_message_id.get_next_message_id(MessageType::Server); + } else { + from_message_id = MessageId::max(); + } + } else { + from_message_id = from_message_id.get_next_server_message_id(); + } + + switch (dialog_id.get_type()) { + case DialogType::User: + case DialogType::Chat: + case DialogType::Channel: + td_->create_handler(std::move(promise)) + ->send(dialog_id, filter, from_message_id, limit); + break; + case DialogType::SecretChat: + return promise.set_error(Status::Error(400, "Secret chats aren't supported")); + case DialogType::None: + default: + UNREACHABLE(); + } +} + +void MessagesManager::on_get_dialog_sparse_message_positions( + DialogId dialog_id, MessageSearchFilter filter, + telegram_api::object_ptr positions, + Promise> &&promise) { + auto message_positions = transform( + positions->positions_, [](const telegram_api::object_ptr &position) { + return td_api::make_object( + position->offset_, MessageId(ServerMessageId(position->msg_id_)).get(), position->date_); + }); + promise.set_value(td_api::make_object(positions->count_, std::move(message_positions))); +} + void MessagesManager::get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local, Promise &&promise) { LOG(INFO) << "Get " << (return_local ? "local " : "") << "number of messages in " << dialog_id << " filtered by " @@ -22241,7 +22335,7 @@ void MessagesManager::get_dialog_message_count(DialogId dialog_id, MessageSearch LOG(INFO) << "Get number of messages in " << dialog_id << " filtered by " << filter << " from the server"; - switch (dialog_id.get_type()) { + switch (dialog_type) { case DialogType::User: case DialogType::Chat: case DialogType::Channel: diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 56c5074f9..3a424370f 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -733,6 +733,15 @@ class MessagesManager final : public Actor { void on_get_dialog_message_by_date_fail(int64 random_id); + void get_dialog_sparse_message_positions(DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, + int32 limit, + Promise> &&promise); + + void on_get_dialog_sparse_message_positions( + DialogId dialog_id, MessageSearchFilter filter, + telegram_api::object_ptr positions, + Promise> &&promise); + void get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local, Promise &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 1d76b82ce..c833a7352 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5376,7 +5376,15 @@ void Td::on_request(uint64 id, const td_api::getChatMessageByDate &request) { CREATE_REQUEST(GetChatMessageByDateRequest, request.chat_id_, request.date_); } -void Td::on_request(uint64 id, td_api::getChatMessageCount &request) { +void Td::on_request(uint64 id, const td_api::getChatSparseMessagePositions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + messages_manager_->get_dialog_sparse_message_positions( + DialogId(request.chat_id_), get_message_search_filter(request.filter_), MessageId(request.from_message_id_), + request.limit_, std::move(promise)); +} + +void Td::on_request(uint64 id, const td_api::getChatMessageCount &request) { CHECK_IS_USER(); CREATE_REQUEST_PROMISE(); auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 63896f421..324eeb955 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -628,7 +628,9 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getChatMessageByDate &request); - void on_request(uint64 id, td_api::getChatMessageCount &request); + void on_request(uint64 id, const td_api::getChatSparseMessagePositions &request); + + void on_request(uint64 id, const td_api::getChatMessageCount &request); void on_request(uint64 id, const td_api::getChatScheduledMessages &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index f15f984a4..2e046d3fc 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2105,6 +2105,19 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_chat_id(chat_id), query.query, nullptr, as_message_id(offset_message_id), 0, query.limit, as_search_messages_filter(op), 0)); + } else if (op == "gcmbd") { + string chat_id; + int32 date; + get_args(args, chat_id, date); + send_request(td_api::make_object(as_chat_id(chat_id), date)); + } else if (op == "gcsmp") { + string chat_id; + string filter; + string from_message_id; + string limit; + get_args(args, chat_id, filter, from_message_id, limit); + send_request(td_api::make_object( + as_chat_id(chat_id), as_search_messages_filter(filter), as_message_id(from_message_id), as_limit(limit))); } else if (op == "gcmc") { string chat_id; string filter; @@ -2640,11 +2653,6 @@ class CliClient final : public Actor { for_album)); } else if (op == "gmli") { send_request(td_api::make_object(args)); - } else if (op == "gcmbd") { - string chat_id; - int32 date; - get_args(args, chat_id, date); - send_request(td_api::make_object(as_chat_id(chat_id), date)); } else if (op == "gf" || op == "GetFile") { send_request(td_api::make_object(as_file_id(args))); } else if (op == "gfdps") { From d019d89d395d99c65f615c7b48032014f60c0c01 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 25 Oct 2021 20:39:22 +0300 Subject: [PATCH 33/82] Add td_api::deleteChatMessagesByDate. --- td/generate/scheme/td_api.tl | 4 + td/telegram/MessagesManager.cpp | 229 +++++++++++++++++++++++++++++++- td/telegram/MessagesManager.h | 16 ++- td/telegram/Td.cpp | 7 + td/telegram/Td.h | 2 + td/telegram/TdDb.cpp | 1 + td/telegram/cli.cpp | 8 ++ td/telegram/logevent/LogEvent.h | 1 + 8 files changed, 263 insertions(+), 5 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d5017dfef..d3b11eb68 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4392,6 +4392,10 @@ deleteMessages chat_id:int53 message_ids:vector revoke:Bool = Ok; //@description Deletes all messages sent by the specified user to a chat. Supported only for supergroups; requires can_delete_messages administrator privileges @chat_id Chat identifier @user_id User identifier deleteChatMessagesFromUser chat_id:int53 user_id:int53 = Ok; +//@description Deletes all messages between the specified dates in a chat. Supported only for private chats and basic groups. Messages sent in the last 30 seconds will not be deleted +//@chat_id Chat identifier @min_date The minimum date of the messages to delete @max_date The maximum date of the messages to delete @revoke Pass true to try to delete chat messages for all users; private chats only +deleteChatMessagesByDate chat_id:int53 min_date:int32 max_date:int32 revoke:Bool = Ok; + //@description Edits the text of a message (or a text of a game message). Returns the edited message after the edit is completed on the server side //@chat_id The chat the message belongs to diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index bfd93b4be..e74d1c282 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2715,6 +2715,74 @@ class DeleteChannelHistoryQuery final : public Td::ResultHandler { } }; +class DeleteMessagesByDateQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + int32 min_date_; + int32 max_date_; + bool revoke_; + + void send_request() { + auto input_peer = td->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return promise_.set_error(Status::Error(400, "Chat is not accessible")); + } + + int32 flags = telegram_api::messages_deleteHistory::JUST_CLEAR_MASK | + telegram_api::messages_deleteHistory::MIN_DATE_MASK | + telegram_api::messages_deleteHistory::MAX_DATE_MASK; + if (revoke_) { + flags |= telegram_api::messages_deleteHistory::REVOKE_MASK; + } + + send_query(G()->net_query_creator().create(telegram_api::messages_deleteHistory( + flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), 0, min_date_, max_date_))); + } + + public: + explicit DeleteMessagesByDateQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke) { + dialog_id_ = dialog_id; + min_date_ = min_date; + max_date_ = max_date; + revoke_ = revoke; + + send_request(); + } + + void on_result(uint64 id, BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto affected_history = result_ptr.move_as_ok(); + CHECK(affected_history->get_id() == telegram_api::messages_affectedHistory::ID); + + if (affected_history->pts_count_ > 0) { + affected_history->pts_count_ = 0; // force receiving real updates from the server + auto promise = affected_history->offset_ > 0 ? Promise() : std::move(promise_); + td->updates_manager_->add_pending_pts_update(make_tl_object(), affected_history->pts_, + affected_history->pts_count_, Time::now(), std::move(promise), + "DeleteMessagesByDateQuery"); + } else if (affected_history->offset_ <= 0) { + promise_.set_value(Unit()); + } + + if (affected_history->offset_ > 0) { + send_request(); + return; + } + } + + void on_error(uint64 id, Status status) final { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "DeleteMessagesByDateQuery"); + promise_.set_error(std::move(status)); + } +}; + class DeletePhoneCallHistoryQuery final : public Td::ResultHandler { Promise promise_; bool revoke_; @@ -10806,8 +10874,6 @@ void MessagesManager::delete_dialog_messages_from_user(DialogId dialog_id, UserI bool is_bot = td_->auth_manager_->is_bot(); CHECK(!is_bot); - LOG(INFO) << "Receive deleteChatMessagesFromUser request to delete all messages in " << dialog_id << " from the user " - << user_id; Dialog *d = get_dialog_force(dialog_id, "delete_dialog_messages_from_user"); if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); @@ -10915,6 +10981,126 @@ void MessagesManager::delete_all_channel_messages_from_user_on_server(ChannelId ->send(channel_id, user_id); } +void MessagesManager::delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, + Promise &&promise) { + bool is_bot = td_->auth_manager_->is_bot(); + CHECK(!is_bot); + + Dialog *d = get_dialog_force(dialog_id, "delete_dialog_messages_by_date"); + if (d == nullptr) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + + if (!have_input_peer(dialog_id, AccessRights::Read)) { + return promise.set_error(Status::Error(400, "Can't access the chat")); + } + + if (min_date > max_date) { + return promise.set_error(Status::Error(400, "Wrong date interval specified")); + } + + const int32 telegram_launch_date = 1376438400; + if (max_date < telegram_launch_date) { + return promise.set_value(Unit()); + } + if (min_date < telegram_launch_date) { + min_date = telegram_launch_date; + } + + auto current_date = max(G()->unix_time(), 1635000000); + if (min_date >= current_date - 30) { + return promise.set_value(Unit()); + } + if (max_date >= current_date - 30) { + max_date = current_date - 31; + } + CHECK(min_date <= max_date); + + switch (dialog_id.get_type()) { + case DialogType::User: + break; + case DialogType::Chat: + if (revoke) { + return promise.set_error(Status::Error(400, "Bulk message revocation is unsupported in basic group chats")); + } + break; + case DialogType::Channel: + return promise.set_error(Status::Error(400, "Bulk message deletion is unsupported in supergroup chats")); + case DialogType::SecretChat: + return promise.set_error(Status::Error(400, "Bulk message deletion is unsupported in secret chats")); + case DialogType::None: + default: + UNREACHABLE(); + break; + } + + // TODO delete in database by dates + + vector message_ids; + find_messages_by_date(d->messages.get(), min_date, max_date, message_ids); + + bool need_update_dialog_pos = false; + vector deleted_message_ids; + for (auto message_id : message_ids) { + auto m = delete_message(d, message_id, true, &need_update_dialog_pos, DELETE_MESSAGE_USER_REQUEST_SOURCE); + CHECK(m != nullptr); + deleted_message_ids.push_back(m->message_id.get()); + } + + if (need_update_dialog_pos) { + send_update_chat_last_message(d, "delete_dialog_messages_by_date"); + } + send_update_delete_messages(dialog_id, std::move(deleted_message_ids), true, false); + + delete_dialog_messages_by_date_on_server(dialog_id, min_date, max_date, revoke, 0, std::move(promise)); +} + +class MessagesManager::DeleteDialogMessagesByDateOnServerLogEvent { + public: + DialogId dialog_id_; + int32 min_date_; + int32 max_date_; + bool revoke_; + + template + void store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + STORE_FLAG(revoke_); + END_STORE_FLAGS(); + td::store(dialog_id_, storer); + td::store(min_date_, storer); + td::store(max_date_, storer); + } + + template + void parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(revoke_); + END_PARSE_FLAGS(); + td::parse(dialog_id_, parser); + td::parse(min_date_, parser); + td::parse(max_date_, parser); + } +}; + +uint64 MessagesManager::save_delete_dialog_messages_by_date_on_server_log_event(DialogId dialog_id, int32 min_date, + int32 max_date, bool revoke) { + DeleteDialogMessagesByDateOnServerLogEvent log_event{dialog_id, min_date, max_date, revoke}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer, + get_log_event_storer(log_event)); +} + +void MessagesManager::delete_dialog_messages_by_date_on_server(DialogId dialog_id, int32 min_date, int32 max_date, + bool revoke, uint64 log_event_id, + Promise &&promise) { + if (log_event_id == 0 && G()->parameters().use_chat_info_db) { + log_event_id = save_delete_dialog_messages_by_date_on_server_log_event(dialog_id, min_date, max_date, revoke); + } + + td_->create_handler(get_erase_log_event_promise(log_event_id, std::move(promise))) + ->send(dialog_id, min_date, max_date, revoke); +} + int32 MessagesManager::get_unload_dialog_delay() const { constexpr int32 DIALOG_UNLOAD_DELAY = 60; // seconds constexpr int32 DIALOG_UNLOAD_BOT_DELAY = 1800; // seconds @@ -20153,7 +20339,7 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * } break; case DialogType::Chat: - // chats can't be deleted only for self with deleteChatHistory + // chats can be deleted only for self with deleteChatHistory can_delete_for_self = true; break; case DialogType::Channel: @@ -22154,6 +22340,23 @@ MessageId MessagesManager::find_message_by_date(const Message *m, int32 date) { return m->message_id; } +void MessagesManager::find_messages_by_date(const Message *m, int32 min_date, int32 max_date, + vector &message_ids) { + if (m == nullptr) { + return; + } + + if (m->date >= min_date) { + find_messages_by_date(m->left.get(), min_date, max_date, message_ids); + if (m->date <= max_date) { + message_ids.push_back(m->message_id); + } + } + if (m->date <= max_date) { + find_messages_by_date(m->right.get(), min_date, max_date, message_ids); + } +} + void MessagesManager::on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, int64 random_id, Result result, Promise promise) { @@ -37415,6 +37618,26 @@ void MessagesManager::on_binlog_events(vector &&events) { delete_all_channel_messages_from_user_on_server(channel_id, user_id, event.id_, Auto()); break; } + case LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer: { + if (!G()->parameters().use_message_db) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + DeleteDialogMessagesByDateOnServerLogEvent log_event; + log_event_parse(log_event, event.data_).ensure(); + + auto dialog_id = log_event.dialog_id_; + Dialog *d = get_dialog_force(dialog_id, "DeleteDialogMessagesByDateOnServerLogEvent"); + if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + delete_dialog_messages_by_date_on_server(dialog_id, log_event.min_date_, log_event.max_date_, log_event.revoke_, + event.id_, Auto()); + break; + } case LogEvent::HandlerType::ReadHistoryOnServer: { if (!G()->parameters().use_message_db) { binlog_erase(G()->td_db()->get_binlog(), event.id_); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 3a424370f..d00f50b42 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -365,6 +365,9 @@ class MessagesManager final : public Actor { void delete_dialog_messages_from_user(DialogId dialog_id, UserId user_id, Promise &&promise); + void delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, + Promise &&promise); + void on_dialog_deleted(DialogId dialog_id, Promise &&promise); void on_update_dialog_group_call_rights(DialogId dialog_id); @@ -1640,10 +1643,10 @@ class MessagesManager final : public Actor { }; class BlockMessageSenderFromRepliesOnServerLogEvent; - class ToggleDialogReportSpamStateOnServerLogEvent; + class DeleteAllCallMessagesFromServerLogEvent; class DeleteAllChannelMessagesFromUserOnServerLogEvent; class DeleteDialogHistoryFromServerLogEvent; - class DeleteAllCallMessagesFromServerLogEvent; + class DeleteDialogMessagesByDateOnServerLogEvent; class DeleteMessageLogEvent; class DeleteMessagesFromServerLogEvent; class DeleteScheduledMessagesFromServerLogEvent; @@ -1666,6 +1669,7 @@ class MessagesManager final : public Actor { class ToggleDialogIsBlockedOnServerLogEvent; class ToggleDialogIsMarkedAsUnreadOnServerLogEvent; class ToggleDialogIsPinnedOnServerLogEvent; + class ToggleDialogReportSpamStateOnServerLogEvent; class UnpinAllDialogMessagesOnServerLogEvent; class UpdateDialogNotificationSettingsOnServerLogEvent; class UpdateScopeNotificationSettingsOnServerLogEvent; @@ -2007,12 +2011,17 @@ class MessagesManager final : public Actor { void delete_all_channel_messages_from_user_on_server(ChannelId channel_id, UserId user_id, uint64 log_event_id, Promise &&promise); + void delete_dialog_messages_by_date_on_server(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, + uint64 log_event_id, Promise &&promise); + void read_all_dialog_mentions_on_server(DialogId dialog_id, uint64 log_event_id, Promise &&promise); void unpin_all_dialog_messages_on_server(DialogId dialog_id, uint64 log_event_id, Promise &&promise); static MessageId find_message_by_date(const Message *m, int32 date); + static void find_messages_by_date(const Message *m, int32 min_date, int32 max_date, vector &message_ids); + static void find_messages(const Message *m, vector &message_ids, const std::function &condition); @@ -3080,6 +3089,9 @@ class MessagesManager final : public Actor { static uint64 save_delete_all_channel_messages_from_user_on_server_log_event(ChannelId channel_id, UserId user_id); + static uint64 save_delete_dialog_messages_by_date_on_server_log_event(DialogId dialog_id, int32 min_date, + int32 max_date, bool revoke); + static uint64 save_read_all_dialog_mentions_on_server_log_event(DialogId dialog_id); static uint64 save_toggle_dialog_is_pinned_on_server_log_event(DialogId dialog_id, bool is_pinned); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index c833a7352..e3da5f0d1 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5440,6 +5440,13 @@ void Td::on_request(uint64 id, const td_api::deleteChatMessagesFromUser &request std::move(promise)); } +void Td::on_request(uint64 id, const td_api::deleteChatMessagesByDate &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + messages_manager_->delete_dialog_messages_by_date(DialogId(request.chat_id_), request.min_date_, request.max_date_, + request.revoke_, std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::readAllChatMentions &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 324eeb955..d697d0f1c 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -644,6 +644,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::deleteChatMessagesFromUser &request); + void on_request(uint64 id, const td_api::deleteChatMessagesByDate &request); + void on_request(uint64 id, const td_api::readAllChatMentions &request); void on_request(uint64 id, td_api::sendMessage &request); diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 6449ba5e8..315cd5daa 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -119,6 +119,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::BlockMessageSenderFromRepliesOnServer: case LogEvent::HandlerType::UnpinAllDialogMessagesOnServer: case LogEvent::HandlerType::DeleteAllCallMessagesFromServer: + case LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer: events.to_messages_manager.push_back(event.clone()); break; case LogEvent::HandlerType::AddMessagePushNotification: diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 2e046d3fc..b670b58f4 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3711,6 +3711,14 @@ class CliClient final : public Actor { get_args(args, chat_id, remove_from_the_chat_list, revoke); send_request( td_api::make_object(as_chat_id(chat_id), remove_from_the_chat_list, revoke)); + } else if (op == "dcmbd") { + string chat_id; + int32 min_date; + int32 max_date; + bool revoke; + get_args(args, chat_id, min_date, max_date, revoke); + send_request( + td_api::make_object(as_chat_id(chat_id), min_date, max_date, revoke)); } else if (op == "dmfu") { string chat_id; string user_id; diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index dded1e5ff..042460bc5 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -99,6 +99,7 @@ class LogEvent { BlockMessageSenderFromRepliesOnServer = 0x120, UnpinAllDialogMessagesOnServer = 0x121, DeleteAllCallMessagesFromServer = 0x122, + DeleteDialogMessagesByDateOnServer = 0x123, GetChannelDifference = 0x140, AddMessagePushNotification = 0x200, EditMessagePushNotification = 0x201, From 9addfaf6fe9482a47140d40304cb8b0de2845649 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Oct 2021 16:15:01 +0300 Subject: [PATCH 34/82] Add class td_api::animatedEmoji. --- td/generate/scheme/td_api.tl | 14 ++++++++------ td/telegram/MessageContent.cpp | 5 ++++- td/telegram/StickersManager.cpp | 18 +++++++----------- td/telegram/StickersManager.h | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d3b11eb68..a547be450 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -298,6 +298,12 @@ videoNote duration:int32 length:int32 minithumbnail:minithumbnail thumbnail:thum //@waveform A waveform representation of the voice note in 5-bit format @mime_type MIME type of the file; as defined by the sender @voice File containing the voice note voiceNote duration:int32 waveform:bytes mime_type:string voice:file = VoiceNote; +//@description Describes an animated representation of an emoji +//@sticker Animated sticker for the emoji +//@color_replacements List of colors to be replaced while the sticker is rendered +//@sound File containing the sound to be played when the animated emoji is clicked if any; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container +animatedEmoji sticker:sticker color_replacements:vector sound:file = AnimatedEmoji; + //@description Describes a user contact @phone_number Phone number of the user @first_name First name of the user; 1-255 characters in length @last_name Last name of the user @vcard Additional data about the user in a form of vCard; 0-2048 bytes in length @user_id Identifier of the user, if known; otherwise 0 contact phone_number:string first_name:string last_name:string vcard:string user_id:int53 = Contact; @@ -1728,12 +1734,8 @@ messageVenue venue:venue = MessageContent; //@description A message with a user contact @contact The contact description messageContact contact:contact = MessageContent; -//@description A message with an animated emoji -//@emoji The corresponding emoji -//@sticker Animated sticker with the emoji animation -//@color_replacements List of colors to be replaced while the sticker is rendered -//@sound File containing the sound to be played when the animated emoji is clicked if any; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container -messageAnimatedEmoji emoji:string sticker:sticker color_replacements:vector sound:file = MessageContent; +//@description A message with an animated emoji @animated_emoji Description of the animated emoji @emoji The corresponding emoji +messageAnimatedEmoji animated_emoji:animatedEmoji emoji:string = MessageContent; //@description A dice message. The dice value is randomly generated by the server //@initial_state The animated stickers with the initial dice animation; may be null if unknown. updateMessageContent will be sent when the sticker became known diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 0e2eab7b0..dd4712ffd 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -4830,7 +4830,10 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::Text: { const auto *m = static_cast(content); if (can_be_animated_emoji(m->text) && !m->web_page_id.is_valid()) { - return td->stickers_manager_->get_message_content_animated_emoji_object(m->text.text); + auto animated_emoji = td->stickers_manager_->get_animated_emoji_object(m->text.text); + if (animated_emoji != nullptr) { + return td_api::make_object(std::move(animated_emoji), m->text.text); + } } return make_tl_object( get_formatted_text_object(m->text, skip_bot_commands, max_media_timestamp), diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 0139381a2..0f0636aeb 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -2012,21 +2012,17 @@ vector> StickersManager::get_color_ return result; } -td_api::object_ptr StickersManager::get_message_content_animated_emoji_object( - const string &emoji) { +td_api::object_ptr StickersManager::get_animated_emoji_object(const string &emoji) { auto it = emoji_messages_.find(emoji); auto animated_sticker = it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji); - if (animated_sticker.first.is_valid()) { - auto sound_file_id = - it != emoji_messages_.end() ? it->second.sound_file_id : get_animated_emoji_sound_file_id(emoji); - return td_api::make_object( - emoji, get_sticker_object(animated_sticker.first, true), get_color_replacements_object(animated_sticker.second), - sound_file_id.is_valid() ? td_->file_manager_->get_file_object(sound_file_id) : nullptr); + if (!animated_sticker.first.is_valid()) { + return nullptr; } - return td_api::make_object( - td_api::make_object(emoji, std::vector>()), - nullptr); + auto sound_file_id = it != emoji_messages_.end() ? it->second.sound_file_id : get_animated_emoji_sound_file_id(emoji); + return td_api::make_object( + get_sticker_object(animated_sticker.first, true), get_color_replacements_object(animated_sticker.second), + sound_file_id.is_valid() ? td_->file_manager_->get_file_object(sound_file_id) : nullptr); } tl_object_ptr StickersManager::get_input_sticker_set(StickerSetId sticker_set_id) const { diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index db1089413..32557e508 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -64,7 +64,7 @@ class StickersManager final : public Actor { const vector &sticker_set_ids, size_t covers_limit) const; - td_api::object_ptr get_message_content_animated_emoji_object(const string &emoji); + td_api::object_ptr get_animated_emoji_object(const string &emoji); tl_object_ptr get_input_sticker_set(StickerSetId sticker_set_id) const; From 1dd054d8963253a335f438e2bf5e49c855ba9fc1 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Oct 2021 16:50:18 +0300 Subject: [PATCH 35/82] Add const get_animated_emoji_object. --- td/telegram/StickersManager.cpp | 12 +++++++++--- td/telegram/StickersManager.h | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 0f0636aeb..d88c6a17e 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -2014,12 +2014,18 @@ vector> StickersManager::get_color_ td_api::object_ptr StickersManager::get_animated_emoji_object(const string &emoji) { auto it = emoji_messages_.find(emoji); - auto animated_sticker = - it != emoji_messages_.end() ? it->second.animated_emoji_sticker : get_animated_emoji_sticker(emoji); + if (it == emoji_messages_.end()) { + return get_animated_emoji_object(get_animated_emoji_sticker(emoji), get_animated_emoji_sound_file_id(emoji)); + } else { + return get_animated_emoji_object(it->second.animated_emoji_sticker, it->second.sound_file_id); + } +} + +td_api::object_ptr StickersManager::get_animated_emoji_object( + std::pair animated_sticker, FileId sound_file_id) const { if (!animated_sticker.first.is_valid()) { return nullptr; } - auto sound_file_id = it != emoji_messages_.end() ? it->second.sound_file_id : get_animated_emoji_sound_file_id(emoji); return td_api::make_object( get_sticker_object(animated_sticker.first, true), get_color_replacements_object(animated_sticker.second), sound_file_id.is_valid() ? td_->file_manager_->get_file_object(sound_file_id) : nullptr); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index 32557e508..ec6090681 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -620,6 +620,9 @@ class StickersManager final : public Actor { FileId get_animated_emoji_sound_file_id(const string &emoji) const; + td_api::object_ptr get_animated_emoji_object(std::pair animated_sticker, + FileId sound_file_id) const; + void try_update_animated_emoji_messages(); static int get_emoji_number(Slice emoji); From 6893c49be70ebafdb561651e5aaf3eb241ffad36 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Oct 2021 17:59:15 +0300 Subject: [PATCH 36/82] Add td_api::getAnimatedEmoji. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/StickersManager.cpp | 33 +++++++++++++++++++++++++++++++++ td/telegram/StickersManager.h | 7 ++++++- td/telegram/Td.cpp | 7 +++++++ td/telegram/Td.h | 2 ++ td/telegram/cli.cpp | 2 ++ 6 files changed, 53 insertions(+), 1 deletion(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a547be450..5aa071d2a 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -5219,6 +5219,9 @@ getStickerEmojis sticker:InputFile = Emojis; //@description Searches for emojis by keywords. Supported only if the file database is enabled @text Text to search for @exact_match True, if only emojis, which exactly match text needs to be returned @input_language_codes List of possible IETF language tags of the user's input language; may be empty if unknown searchEmojis text:string exact_match:Bool input_language_codes:vector = Emojis; +//@description Returns an animated emoji corresponding to a given emoji. Returns a 404 error if the emoji has no animated emoji @emoji The emoji +getAnimatedEmoji emoji:string = AnimatedEmoji; + //@description Returns an HTTP URL which can be used to automatically log in to the translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation @language_code Language code for which the emoji replacements will be suggested getEmojiSuggestionsUrl language_code:string = HttpUrl; diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index d88c6a17e..e8f90d733 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1433,6 +1433,11 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t schedule_update_animated_emoji_clicked(sticker_set, pending_request.emoji_, pending_request.full_message_id_, std::move(pending_request.clicks_)); } + auto promises = std::move(pending_get_animated_emoji_queries_); + reset_to_empty(pending_get_animated_emoji_queries_); + for (auto &promise : promises) { + promise.set_value(Unit()); + } return; } @@ -4277,6 +4282,34 @@ void StickersManager::unregister_emoji(const string &emoji, FullMessageId full_m } } +void StickersManager::get_animated_emoji(string emoji, bool is_recursive, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji()); + auto sticker_set = get_sticker_set(special_sticker_set.id_); + if (sticker_set == nullptr || !sticker_set->was_loaded) { + if (is_recursive) { + return promise.set_value(nullptr); + } + + pending_get_animated_emoji_queries_.push_back( + PromiseCreator::lambda([actor_id = actor_id(this), emoji = std::move(emoji), + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &StickersManager::get_animated_emoji, std::move(emoji), true, std::move(promise)); + } + })); + load_special_sticker_set(special_sticker_set); + return; + } + + promise.set_value(get_animated_emoji_object(get_animated_emoji_sticker(sticker_set, emoji), + get_animated_emoji_sound_file_id(emoji))); +} + void StickersManager::get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, Promise> &&promise) { auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji_click()); diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index ec6090681..dd9e1e13e 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -76,6 +76,9 @@ class StickersManager final : public Actor { void unregister_emoji(const string &emoji, FullMessageId full_message_id, const char *source); + void get_animated_emoji(string emoji, bool is_recursive, + Promise> &&promise); + void get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, Promise> &&promise); @@ -621,7 +624,7 @@ class StickersManager final : public Actor { FileId get_animated_emoji_sound_file_id(const string &emoji) const; td_api::object_ptr get_animated_emoji_object(std::pair animated_sticker, - FileId sound_file_id) const; + FileId sound_file_id) const; void try_update_animated_emoji_messages(); @@ -798,6 +801,8 @@ class StickersManager final : public Actor { std::unordered_map> pending_set_sticker_set_thumbnails_; + vector> pending_get_animated_emoji_queries_; + double next_click_animated_emoji_message_time_ = 0; double next_update_animated_emoji_clicked_time_ = 0; vector pending_get_animated_emoji_click_stickers_; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index e3da5f0d1..389332da7 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7002,6 +7002,13 @@ void Td::on_request(uint64 id, td_api::searchEmojis &request) { std::move(request.input_language_codes_)); } +void Td::on_request(uint64 id, td_api::getAnimatedEmoji &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.emoji_); + CREATE_REQUEST_PROMISE(); + stickers_manager_->get_animated_emoji(std::move(request.emoji_), false, std::move(promise)); +} + void Td::on_request(uint64 id, td_api::getEmojiSuggestionsUrl &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.language_code_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index d697d0f1c..cb93c33b7 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1042,6 +1042,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::searchEmojis &request); + void on_request(uint64 id, td_api::getAnimatedEmoji &request); + void on_request(uint64 id, td_api::getEmojiSuggestionsUrl &request); void on_request(uint64 id, const td_api::getFavoriteStickers &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index b670b58f4..13aa61408 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2527,6 +2527,8 @@ class CliClient final : public Actor { send_request(td_api::make_object(args, true, vector())); } else if (op == "seru") { send_request(td_api::make_object(args, false, vector{"ru_RU"})); + } else if (op == "gae") { + send_request(td_api::make_object(args)); } else if (op == "gesu") { send_request(td_api::make_object(args)); } else { From 8d458f30382aaf887b7e0cdfa147e02a9d65fb86 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Oct 2021 20:51:06 +0300 Subject: [PATCH 37/82] Add chatJoinRequestsInfo with user identifiers. --- td/generate/scheme/td_api.tl | 15 ++-- td/telegram/ContactsManager.cpp | 11 +-- td/telegram/MessagesManager.cpp | 124 ++++++++++++++++++++------------ td/telegram/MessagesManager.h | 16 +++-- td/telegram/UpdatesManager.cpp | 4 +- 5 files changed, 106 insertions(+), 64 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5aa071d2a..d593d3bc2 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -611,6 +611,9 @@ chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; //@description Contains a list of chat join requests @total_count Approximate total count of requests found @requests List of the requests chatJoinRequests total_count:int32 requests:vector = ChatJoinRequests; +//@description Contains information about pending chat join requests @total_count Number of pending join requests, which wait administrator approval @user_ids List of identifiers, of users with newest pending requests +chatJoinRequestsInfo total_count:int32 user_ids:vector = ChatJoinRequestsInfo; + //@description Represents a basic group of 0-200 users (must be upgraded to a supergroup to accommodate more than 200 users) //@id Group identifier @@ -965,12 +968,12 @@ videoChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@message_ttl_setting Current message Time To Live setting (self-destruct timer) for the chat; 0 if not defined. TTL is counted from the time message or its content is viewed in secret chats and from the send date in other chats //@theme_name If non-empty, name of a theme, set for the chat //@action_bar Describes actions which must be possible to do through a chat action bar; may be null -//@video_chat Contains information about video chat of the chat -//@pending_join_request_count Number of pending join requests, waiting administrator's approval +//@video_chat Information about video chat of the chat +//@pending_join_requests Information about pending join requests; may be null //@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat //@draft_message A draft of a message in the chat; may be null -//@client_data Contains application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used -chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar video_chat:videoChat pending_join_request_count:int53 reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; +//@client_data Application-specific data associated with the chat. (For example, the chat scroll position or local chat notification settings can be stored here.) Persistent if the message database is used +chat id:int53 type:ChatType title:string photo:chatPhotoInfo permissions:chatPermissions last_message:message positions:vector is_marked_as_unread:Bool is_blocked:Bool has_scheduled_messages:Bool can_be_deleted_only_for_self:Bool can_be_deleted_for_all_users:Bool can_be_reported:Bool default_disable_notification:Bool unread_count:int32 last_read_inbox_message_id:int53 last_read_outbox_message_id:int53 unread_mention_count:int32 notification_settings:chatNotificationSettings message_ttl_setting:int32 theme_name:string action_bar:ChatActionBar video_chat:videoChat pending_join_requests:chatJoinRequestsInfo reply_markup_message_id:int53 draft_message:draftMessage client_data:string = Chat; //@description Represents a list of chats @total_count Approximate total count of chats found @chat_ids List of chat identifiers chats total_count:int32 chat_ids:vector = Chats; @@ -3719,8 +3722,8 @@ updateChatActionBar chat_id:int53 action_bar:ChatActionBar = Update; //@description The chat theme was changed @chat_id Chat identifier @theme_name The new name of the chat theme; may be empty if theme was reset to default updateChatTheme chat_id:int53 theme_name:string = Update; -//@description The number of chat pending join requests was changed @chat_id Chat identifier @pending_join_request_count The new number of pending join requests -updateChatPendingJoinRequestCount chat_id:int53 pending_join_request_count:int32 = Update; +//@description The chat pending join requests were changed @chat_id Chat identifier @pending_join_requests The new data about pending join requests; may be null +updateChatPendingJoinRequests chat_id:int53 pending_join_requests:chatJoinRequestsInfo = Update; //@description The default chat reply markup was changed. Can occur because new messages with reply markup were received or because an old reply markup was hidden by the user //@chat_id Chat identifier @reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 01cdad0cb..eb4f6f766 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -9976,7 +9976,7 @@ void ContactsManager::update_chat(Chat *c, ChatId chat_id, bool from_binlog, boo } if (c->is_status_changed) { if (!c->status.can_manage_invite_links()) { - td_->messages_manager_->drop_dialog_pending_join_request_count(DialogId(chat_id)); + td_->messages_manager_->drop_dialog_pending_join_requests(DialogId(chat_id)); } c->is_status_changed = false; } @@ -10042,7 +10042,7 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from remove_inactive_channel(channel_id); } if (!c->status.can_manage_invite_links()) { - td_->messages_manager_->drop_dialog_pending_join_request_count(DialogId(channel_id)); + td_->messages_manager_->drop_dialog_pending_join_requests(DialogId(channel_id)); } c->is_status_changed = false; } @@ -10652,7 +10652,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_theme_name(DialogId(chat_id), std::move(chat->theme_emoticon_)); - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(chat_id), chat->requests_pending_); + td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(chat_id), chat->requests_pending_, + std::move(chat->recent_requesters_)); auto bot_commands = get_bot_commands(std::move(chat->bot_info_), &chat_full->participants); if (chat_full->bot_commands != bot_commands) { @@ -10697,8 +10698,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_theme_name(DialogId(channel_id), std::move(channel->theme_emoticon_)); - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(channel_id), - channel->requests_pending_); + td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(channel_id), channel->requests_pending_, + std::move(channel->recent_requesters_)); { MessageTtlSetting message_ttl_setting; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index e74d1c282..5f9200c59 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -5359,7 +5359,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool store_has_bots = dialog_type == DialogType::Chat || dialog_type == DialogType::Channel; bool has_theme_name = !theme_name.empty(); bool has_flags3 = true; - bool has_pending_join_request_count = pending_join_request_count != 0; + bool has_pending_join_requests = pending_join_request_count != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(has_draft_message); STORE_FLAG(has_last_database_message); @@ -5431,7 +5431,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { } if (has_flags3) { BEGIN_STORE_FLAGS(); - STORE_FLAG(has_pending_join_request_count); + STORE_FLAG(has_pending_join_requests); END_STORE_FLAGS(); } @@ -5528,8 +5528,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_theme_name) { store(theme_name, storer); } - if (has_pending_join_request_count) { + if (has_pending_join_requests) { store(pending_join_request_count, storer); + store(pending_join_request_user_ids, storer); } } @@ -5565,7 +5566,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_default_join_group_call_as_dialog_id = false; bool has_theme_name = false; bool has_flags3 = false; - bool has_pending_join_request_count = false; + bool has_pending_join_requests = false; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_draft_message); PARSE_FLAG(has_last_database_message); @@ -5659,7 +5660,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { } if (has_flags3) { BEGIN_PARSE_FLAGS(); - PARSE_FLAG(has_pending_join_request_count); + PARSE_FLAG(has_pending_join_requests); END_PARSE_FLAGS(); } @@ -5789,8 +5790,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_theme_name) { parse(theme_name, parser); } - if (has_pending_join_request_count) { + if (has_pending_join_requests) { parse(pending_join_request_count, parser); + parse(pending_join_request_user_ids, parser); } } @@ -20300,6 +20302,16 @@ string MessagesManager::get_dialog_theme_name(const Dialog *d) const { return d->theme_name; } +td_api::object_ptr MessagesManager::get_chat_join_requests_info_object( + const Dialog *d) const { + if (d->pending_join_request_count == 0) { + return nullptr; + } + return td_api::make_object( + d->pending_join_request_count, td_->contacts_manager_->get_user_ids_object(d->pending_join_request_user_ids, + "get_chat_join_requests_info_object")); +} + td_api::object_ptr MessagesManager::get_video_chat_object(const Dialog *d) const { auto active_group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, d->dialog_id); auto default_participant_alias = @@ -20381,7 +20393,7 @@ td_api::object_ptr MessagesManager::get_chat_object(const Dialog * d->last_read_inbox_message_id.get(), d->last_read_outbox_message_id.get(), d->unread_mention_count, get_chat_notification_settings_object(&d->notification_settings), d->message_ttl_setting.get_message_ttl_setting_object(), get_dialog_theme_name(d), get_chat_action_bar_object(d), - get_video_chat_object(d), d->pending_join_request_count, d->reply_markup_message_id.get(), + get_video_chat_object(d), get_chat_join_requests_info_object(d), d->reply_markup_message_id.get(), std::move(draft_message), d->client_data); } @@ -29147,18 +29159,17 @@ void MessagesManager::send_update_chat_theme(const Dialog *d) { send_update_secret_chats_with_user_theme(d); } -void MessagesManager::send_update_chat_pending_join_request_count(const Dialog *d) { +void MessagesManager::send_update_chat_pending_join_requests(const Dialog *d) { if (td_->auth_manager_->is_bot()) { return; } CHECK(d != nullptr); - LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id - << " in send_update_chat_pending_join_request_count"; - on_dialog_updated(d->dialog_id, "send_update_chat_pending_join_request_count"); + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_pending_join_requests"; + on_dialog_updated(d->dialog_id, "send_update_chat_pending_join_requests"); send_closure(G()->td(), &Td::send_update, - td_api::make_object(d->dialog_id.get(), - d->pending_join_request_count)); + td_api::make_object(d->dialog_id.get(), + get_chat_join_requests_info_object(d))); } void MessagesManager::send_update_chat_video_chat(const Dialog *d) { @@ -30184,16 +30195,16 @@ void MessagesManager::set_dialog_theme_name(Dialog *d, string theme_name) { } } -void MessagesManager::drop_dialog_pending_join_request_count(DialogId dialog_id) { +void MessagesManager::drop_dialog_pending_join_requests(DialogId dialog_id) { CHECK(dialog_id.is_valid()); auto d = get_dialog(dialog_id); // called from update_chat/channel, must not create the dialog if (d != nullptr && d->is_update_new_chat_sent) { - set_dialog_pending_join_request_count(d, 0); + set_dialog_pending_join_requests(d, 0, {}); } } -void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialog_id, - int32 pending_join_request_count) { +void MessagesManager::on_update_dialog_pending_join_requests(DialogId dialog_id, int32 pending_join_request_count, + vector pending_requesters) { if (!dialog_id.is_valid()) { LOG(ERROR) << "Receive pending join request count in invalid " << dialog_id; return; @@ -30205,46 +30216,64 @@ void MessagesManager::on_update_dialog_pending_join_request_count(DialogId dialo return; } - set_dialog_pending_join_request_count(d, pending_join_request_count); + auto pending_join_request_user_ids = UserId::get_user_ids(pending_requesters); + td::remove_if(pending_join_request_user_ids, [](UserId user_id) { return !user_id.is_valid(); }); + set_dialog_pending_join_requests(d, pending_join_request_count, std::move(pending_join_request_user_ids)); } -void MessagesManager::fix_pending_join_request_count(DialogId dialog_id, int32 &pending_join_request_count) const { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::SecretChat: - pending_join_request_count = 0; - return; - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_status(chat_id); - if (!status.can_manage_invite_links()) { - pending_join_request_count = 0; - } - return; +void MessagesManager::fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count, + vector &pending_join_request_user_ids) const { + bool need_drop_pending_join_requests = [&] { + if (pending_join_request_count < 0) { + return true; } - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - auto status = td_->contacts_manager_->get_channel_permissions(channel_id); - if (!status.can_manage_invite_links()) { - pending_join_request_count = 0; + switch (dialog_id.get_type()) { + case DialogType::User: + case DialogType::SecretChat: + return true; + case DialogType::Chat: { + auto chat_id = dialog_id.get_chat_id(); + auto status = td_->contacts_manager_->get_chat_status(chat_id); + if (!status.can_manage_invite_links()) { + return true; + } + break; } - return; + case DialogType::Channel: { + auto channel_id = dialog_id.get_channel_id(); + auto status = td_->contacts_manager_->get_channel_permissions(channel_id); + if (!status.can_manage_invite_links()) { + return true; + } + break; + } + case DialogType::None: + default: + UNREACHABLE(); } - case DialogType::None: - default: - UNREACHABLE(); + return false; + }(); + if (need_drop_pending_join_requests) { + pending_join_request_count = 0; + pending_join_request_user_ids.clear(); + } else if (static_cast(pending_join_request_count) < pending_join_request_user_ids.size()) { + LOG(ERROR) << "Fix pending join request count from " << pending_join_request_count << " to " + << pending_join_request_user_ids.size(); + pending_join_request_count = narrow_cast(pending_join_request_user_ids.size()); } } -void MessagesManager::set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count) { +void MessagesManager::set_dialog_pending_join_requests(Dialog *d, int32 pending_join_request_count, + vector pending_join_request_user_ids) { CHECK(d != nullptr); - fix_pending_join_request_count(d->dialog_id, pending_join_request_count); - bool is_changed = d->pending_join_request_count != pending_join_request_count; - if (!is_changed) { + fix_pending_join_requests(d->dialog_id, pending_join_request_count, pending_join_request_user_ids); + if (d->pending_join_request_count == pending_join_request_count && + d->pending_join_request_user_ids == pending_join_request_user_ids) { return; } d->pending_join_request_count = pending_join_request_count; - send_update_chat_pending_join_request_count(d); + d->pending_join_request_user_ids = std::move(pending_join_request_user_ids); + send_update_chat_pending_join_requests(d); } void MessagesManager::repair_dialog_scheduled_messages(Dialog *d) { @@ -34789,7 +34818,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&d, on_dialog_updated(dialog_id, "pending update_dialog_group_call"); } } - fix_pending_join_request_count(dialog_id, d->pending_join_request_count); + fix_pending_join_requests(dialog_id, d->pending_join_request_count, d->pending_join_request_user_ids); if (!is_loaded_from_database) { CHECK(order == DEFAULT_ORDER); @@ -35852,6 +35881,9 @@ unique_ptr MessagesManager::parse_dialog(DialogId dialo if (d->draft_message != nullptr) { add_formatted_text_dependencies(dependencies, &d->draft_message->input_message_text.text); } + for (auto user_id : d->pending_join_request_user_ids) { + dependencies.user_ids.insert(user_id); + } if (!resolve_dependencies_force(td_, dependencies, source)) { send_get_dialog_query(dialog_id, Auto(), 0, source); } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index d00f50b42..199f1fd8d 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -293,7 +293,8 @@ class MessagesManager final : public Actor { void on_update_dialog_theme_name(DialogId dialog_id, string theme_name); - void on_update_dialog_pending_join_request_count(DialogId dialog_id, int32 pending_join_request_count); + void on_update_dialog_pending_join_requests(DialogId dialog_id, int32 pending_join_request_count, + vector pending_requesters); void on_update_dialog_has_scheduled_server_messages(DialogId dialog_id, bool has_scheduled_server_messages); @@ -791,7 +792,7 @@ class MessagesManager final : public Actor { void on_dialog_linked_channel_updated(DialogId dialog_id, ChannelId old_linked_channel_id, ChannelId new_linked_channel_id) const; - void drop_dialog_pending_join_request_count(DialogId dialog_id); + void drop_dialog_pending_join_requests(DialogId dialog_id); void on_resolved_username(const string &username, DialogId dialog_id); void drop_username(const string &username); @@ -1195,6 +1196,7 @@ class MessagesManager final : public Actor { DialogId default_join_group_call_as_dialog_id; string theme_name; int32 pending_join_request_count = 0; + vector pending_join_request_user_ids; FolderId folder_id; vector dialog_list_ids; // TODO replace with mask @@ -2360,7 +2362,7 @@ class MessagesManager final : public Actor { void send_update_chat_theme(const Dialog *d); - void send_update_chat_pending_join_request_count(const Dialog *d); + void send_update_chat_pending_join_requests(const Dialog *d); void send_update_chat_video_chat(const Dialog *d); @@ -2461,9 +2463,11 @@ class MessagesManager final : public Actor { void set_dialog_theme_name(Dialog *d, string theme_name); - void fix_pending_join_request_count(DialogId dialog_id, int32 &pending_join_request_count) const; + void fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count, + vector &pending_join_request_user_ids) const; - void set_dialog_pending_join_request_count(Dialog *d, int32 pending_join_request_count); + void set_dialog_pending_join_requests(Dialog *d, int32 pending_join_request_count, + vector pending_join_request_user_ids); void repair_dialog_scheduled_messages(Dialog *d); @@ -2557,6 +2561,8 @@ class MessagesManager final : public Actor { string get_dialog_theme_name(const Dialog *d) const; + td_api::object_ptr get_chat_join_requests_info_object(const Dialog *d) const; + td_api::object_ptr get_video_chat_object(const Dialog *d) const; td_api::object_ptr get_chat_object(const Dialog *d) const; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index be9a2c172..31dbf68f0 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -3213,8 +3213,8 @@ void UpdatesManager::on_update(tl_object_ptr update, } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_update_dialog_pending_join_request_count(DialogId(update->peer_), - update->requests_pending_); + td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(update->peer_), update->requests_pending_, + std::move(update->recent_requesters_)); promise.set_value(Unit()); } From 97243b53e4fc87463c4db381de16af223ab2dfbf Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 13:04:34 +0300 Subject: [PATCH 38/82] Allow to create and edit chat invite links with title. --- td/generate/scheme/td_api.tl | 6 +++-- td/telegram/ContactsManager.cpp | 40 ++++++++++++++++++++------------- td/telegram/ContactsManager.h | 16 ++++++++----- td/telegram/Td.cpp | 17 +++++++++----- td/telegram/Td.h | 2 +- td/telegram/cli.cpp | 12 +++++----- 6 files changed, 57 insertions(+), 36 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d593d3bc2..71835b78f 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4902,18 +4902,20 @@ replacePrimaryChatInviteLink chat_id:int53 = ChatInviteLink; //@description Creates a new invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat //@chat_id Chat identifier +//@title Invite link title; 0-32 characters //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited //@requires_approval True, if users joining the chat by the link need to be approved by chat administrators -createChatInviteLink chat_id:int53 expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; +createChatInviteLink chat_id:int53 title:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; //@description Edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links //@chat_id Chat identifier //@invite_link Invite link to be edited +//@title Invite link title; 0-32 characters //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited //@requires_approval True, if users joining the chat by the link need to be approved by chat administrators -editChatInviteLink chat_id:int53 invite_link:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; +editChatInviteLink chat_id:int53 invite_link:string title:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; //@description Returns information about an invite link. Requires administrator privileges and can_invite_users right in the chat to get own links and owner privileges to get other links //@chat_id Chat identifier diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index eb4f6f766..ebab9cca2 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1610,7 +1610,8 @@ class ExportChatInviteQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool requires_approval, bool is_permanent) { + void send(DialogId dialog_id, const string &title, int32 expire_date, int32 usage_limit, bool requires_approval, + bool is_permanent) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { @@ -1630,9 +1631,12 @@ class ExportChatInviteQuery final : public Td::ResultHandler { if (is_permanent) { flags |= telegram_api::messages_exportChatInvite::LEGACY_REVOKE_PERMANENT_MASK; } + if (!title.empty()) { + flags |= telegram_api::messages_exportChatInvite::TITLE_MASK; + } send_query(G()->net_query_creator().create(telegram_api::messages_exportChatInvite( - flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), expire_date, usage_limit, string()))); + flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), expire_date, usage_limit, title))); } void on_result(uint64 id, BufferSlice packet) final { @@ -1672,7 +1676,7 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, const string &invite_link, int32 expire_date, int32 usage_limit, + void send(DialogId dialog_id, const string &invite_link, const string &title, int32 expire_date, int32 usage_limit, bool requires_approval) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); @@ -1682,10 +1686,11 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { int32 flags = telegram_api::messages_editExportedChatInvite::EXPIRE_DATE_MASK | telegram_api::messages_editExportedChatInvite::USAGE_LIMIT_MASK | - telegram_api::messages_editExportedChatInvite::REQUEST_NEEDED_MASK; + telegram_api::messages_editExportedChatInvite::REQUEST_NEEDED_MASK | + telegram_api::messages_editExportedChatInvite::TITLE_MASK; send_query(G()->net_query_creator().create( telegram_api::messages_editExportedChatInvite(flags, false /*ignored*/, std::move(input_peer), invite_link, - expire_date, usage_limit, requires_approval, string()))); + expire_date, usage_limit, requires_approval, title))); } void on_result(uint64 id, BufferSlice packet) final { @@ -7432,32 +7437,34 @@ Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool return Status::OK(); } -void ContactsManager::export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, +void ContactsManager::export_dialog_invite_link(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit, bool requires_approval, bool is_permanent, Promise> &&promise) { - get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, expire_date, usage_limit, requires_approval, - is_permanent, promise = std::move(promise)](Result &&result) mutable { + get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, title = std::move(title), expire_date, + usage_limit, requires_approval, is_permanent, + promise = std::move(promise)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { - send_closure(actor_id, &ContactsManager::export_dialog_invite_link_impl, dialog_id, expire_date, usage_limit, - requires_approval, is_permanent, std::move(promise)); + send_closure(actor_id, &ContactsManager::export_dialog_invite_link_impl, dialog_id, std::move(title), expire_date, + usage_limit, requires_approval, is_permanent, std::move(promise)); } })); } -void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, - bool requires_approval, bool is_permanent, +void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, string title, int32 expire_date, + int32 usage_limit, bool requires_approval, bool is_permanent, Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); + auto new_title = clean_name(std::move(title), MAX_INVITE_LINK_TITLE_LENGTH); td_->create_handler(std::move(promise)) - ->send(dialog_id, expire_date, usage_limit, requires_approval, is_permanent); + ->send(dialog_id, new_title, expire_date, usage_limit, requires_approval, is_permanent); } -void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string &invite_link, int32 expire_date, - int32 usage_limit, bool requires_approval, +void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string &invite_link, string title, + int32 expire_date, int32 usage_limit, bool requires_approval, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); @@ -7465,8 +7472,9 @@ void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string & return promise.set_error(Status::Error(400, "Invite link must be non-empty")); } + auto new_title = clean_name(std::move(title), MAX_INVITE_LINK_TITLE_LENGTH); td_->create_handler(std::move(promise)) - ->send(dialog_id, invite_link, expire_date, requires_approval, usage_limit); + ->send(dialog_id, invite_link, new_title, expire_date, requires_approval, usage_limit); } void ContactsManager::get_dialog_invite_link(DialogId dialog_id, const string &invite_link, diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index a3e549a9b..52761b0c6 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -384,11 +384,13 @@ class ContactsManager final : public Actor { void transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, Promise &&promise); - void export_dialog_invite_link(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool requires_approval, - bool is_permanent, Promise> &&promise); + void export_dialog_invite_link(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit, + bool requires_approval, bool is_permanent, + Promise> &&promise); - void edit_dialog_invite_link(DialogId dialog_id, const string &link, int32 expire_date, int32 usage_limit, - bool requires_approval, Promise> &&promise); + void edit_dialog_invite_link(DialogId dialog_id, const string &link, string title, int32 expire_date, + int32 usage_limit, bool requires_approval, + Promise> &&promise); void get_dialog_invite_link(DialogId dialog_id, const string &invite_link, Promise> &&promise); @@ -982,6 +984,7 @@ class ContactsManager final : public Actor { static constexpr size_t MAX_NAME_LENGTH = 64; // server side limit for first/last name static constexpr size_t MAX_DESCRIPTION_LENGTH = 255; // server side limit for chat/channel description static constexpr size_t MAX_BIO_LENGTH = 70; // server side limit + static constexpr size_t MAX_INVITE_LINK_TITLE_LENGTH = 32; // server side limit static constexpr int32 MAX_GET_CHANNEL_PARTICIPANTS = 200; // server side limit static constexpr int32 CHANNEL_PARTICIPANT_CACHE_TIME = 1800; // some reasonable limit @@ -1400,8 +1403,9 @@ class ContactsManager final : public Actor { static bool is_channel_public(const Channel *c); - void export_dialog_invite_link_impl(DialogId dialog_id, int32 expire_date, int32 usage_limit, bool requires_approval, - bool is_permanent, Promise> &&promise); + void export_dialog_invite_link_impl(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit, + bool requires_approval, bool is_permanent, + Promise> &&promise); void remove_dialog_access_by_invite_link(DialogId dialog_id); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 389332da7..ab5076352 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6304,20 +6304,25 @@ void Td::on_request(uint64 id, td_api::getChatAdministrators &request) { void Td::on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request) { CREATE_REQUEST_PROMISE(); - contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), 0, 0, false, true, std::move(promise)); + contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), string(), 0, 0, false, true, + std::move(promise)); } -void Td::on_request(uint64 id, const td_api::createChatInviteLink &request) { +void Td::on_request(uint64 id, td_api::createChatInviteLink &request) { + CLEAN_INPUT_STRING(request.title_); CREATE_REQUEST_PROMISE(); - contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), request.expire_date_, request.member_limit_, - request.requires_approval_, false, std::move(promise)); + contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), std::move(request.title_), + request.expire_date_, request.member_limit_, request.requires_approval_, + false, std::move(promise)); } void Td::on_request(uint64 id, td_api::editChatInviteLink &request) { + CLEAN_INPUT_STRING(request.title_); CLEAN_INPUT_STRING(request.invite_link_); CREATE_REQUEST_PROMISE(); - contacts_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, request.expire_date_, - request.member_limit_, request.requires_approval_, std::move(promise)); + contacts_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, + std::move(request.title_), request.expire_date_, request.member_limit_, + request.requires_approval_, std::move(promise)); } void Td::on_request(uint64 id, td_api::getChatInviteLink &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index cb93c33b7..90eb04802 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -862,7 +862,7 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request); - void on_request(uint64 id, const td_api::createChatInviteLink &request); + void on_request(uint64 id, td_api::createChatInviteLink &request); void on_request(uint64 id, td_api::editChatInviteLink &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 13aa61408..6e2db512c 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2947,20 +2947,22 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_chat_id(chat_id))); } else if (op == "ccilt") { string chat_id; + string title; int32 expire_date; int32 member_limit; bool requires_approval; - get_args(args, chat_id, expire_date, member_limit, requires_approval); - send_request(td_api::make_object(as_chat_id(chat_id), expire_date, member_limit, - requires_approval)); + get_args(args, chat_id, title, expire_date, member_limit, requires_approval); + send_request(td_api::make_object(as_chat_id(chat_id), title, expire_date, + member_limit, requires_approval)); } else if (op == "ecil") { string chat_id; string invite_link; + string title; int32 expire_date; int32 member_limit; bool requires_approval; - get_args(args, chat_id, invite_link, expire_date, member_limit, requires_approval); - send_request(td_api::make_object(as_chat_id(chat_id), invite_link, expire_date, + get_args(args, chat_id, invite_link, title, expire_date, member_limit, requires_approval); + send_request(td_api::make_object(as_chat_id(chat_id), invite_link, title, expire_date, member_limit, requires_approval)); } else if (op == "rcil") { string chat_id; From c63fa2e743d10e3c016f767acc5c94d122241fe9 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 13:21:50 +0300 Subject: [PATCH 39/82] Add chatInviteLink.title. --- td/generate/scheme/td_api.tl | 9 ++- td/telegram/DialogInviteLink.cpp | 102 +++++++++++++++---------------- td/telegram/DialogInviteLink.h | 11 ++++ 3 files changed, 65 insertions(+), 57 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 71835b78f..24e60cf2d 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -562,7 +562,10 @@ supergroupMembersFilterMention query:string message_thread_id:int53 = Supergroup supergroupMembersFilterBots = SupergroupMembersFilter; -//@description Contains a chat invite link @invite_link Chat invite link @creator_user_id User identifier of an administrator created the link +//@description Contains a chat invite link +//@invite_link Chat invite link +//@title Title of the chat invite link +//@creator_user_id User identifier of an administrator created the link //@date Point in time (Unix timestamp) when the link was created //@edit_date Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown //@expire_date Point in time (Unix timestamp) when the link will expire; 0 if never @@ -570,9 +573,9 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@member_count Number of chat members, which joined the chat using the link //@pending_join_request_count Number of pending join requests, created using this link //@requires_approval True, if users joining the chat by the link need to be approved by chat administrators -//@is_primary True, if the link is primary. Primary invite link can't have expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time +//@is_primary True, if the link is primary. Primary invite link can't have title, expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time //@is_revoked True, if the link was revoked -chatInviteLink invite_link:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 pending_join_request_count:int32 requires_approval:Bool is_primary:Bool is_revoked:Bool = ChatInviteLink; +chatInviteLink invite_link:string title:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 pending_join_request_count:int32 requires_approval:Bool is_primary:Bool is_revoked:Bool = ChatInviteLink; //@description Contains a list of chat invite links @total_count Approximate total count of chat invite links found @invite_links List of invite links chatInviteLinks total_count:int32 invite_links:vector = ChatInviteLinks; diff --git a/td/telegram/DialogInviteLink.cpp b/td/telegram/DialogInviteLink.cpp index c35b3f1bb..a66b9f444 100644 --- a/td/telegram/DialogInviteLink.cpp +++ b/td/telegram/DialogInviteLink.cpp @@ -19,59 +19,52 @@ DialogInviteLink::DialogInviteLink(tl_object_ptrlink_); - LOG_IF(ERROR, !is_valid_invite_link(invite_link_)) << "Unsupported invite link " << invite_link_; + title_ = std::move(exported_invite->title_); creator_user_id_ = UserId(exported_invite->admin_id_); - if (!creator_user_id_.is_valid()) { - LOG(ERROR) << "Receive invalid " << creator_user_id_ << " as creator of a link " << invite_link_; - creator_user_id_ = UserId(); - } date_ = exported_invite->date_; - if (date_ < 1000000000) { - LOG(ERROR) << "Receive wrong date " << date_ << " as a creation date of a link " << invite_link_; - date_ = 0; - } - if ((exported_invite->flags_ & telegram_api::chatInviteExported::EXPIRE_DATE_MASK) != 0) { - expire_date_ = exported_invite->expire_date_; - if (expire_date_ < 1000000000) { - LOG(ERROR) << "Receive wrong date " << expire_date_ << " as an expire date of a link " << invite_link_; - expire_date_ = 0; - } - } - if ((exported_invite->flags_ & telegram_api::chatInviteExported::USAGE_LIMIT_MASK) != 0) { - usage_limit_ = exported_invite->usage_limit_; - if (usage_limit_ < 0) { - LOG(ERROR) << "Receive wrong usage limit " << usage_limit_ << " for a link " << invite_link_; - usage_limit_ = 0; - } - } - if ((exported_invite->flags_ & telegram_api::chatInviteExported::USAGE_MASK) != 0) { - usage_count_ = exported_invite->usage_; - if (usage_count_ < 0) { - LOG(ERROR) << "Receive wrong usage count " << usage_count_ << " for a link " << invite_link_; - usage_count_ = 0; - } - } - if ((exported_invite->flags_ & telegram_api::chatInviteExported::START_DATE_MASK) != 0) { - edit_date_ = exported_invite->start_date_; - if (edit_date_ < 1000000000) { - LOG(ERROR) << "Receive wrong date " << edit_date_ << " as an edit date of a link " << invite_link_; - edit_date_ = 0; - } - } - if ((exported_invite->flags_ & telegram_api::chatInviteExported::REQUESTED_MASK) != 0) { - request_count_ = exported_invite->requested_; - if (request_count_ < 0) { - LOG(ERROR) << "Receive wrong pending join request count " << request_count_ << " for a link " << invite_link_; - request_count_ = 0; - } - } + expire_date_ = exported_invite->expire_date_; + usage_limit_ = exported_invite->usage_limit_; + usage_count_ = exported_invite->usage_; + edit_date_ = exported_invite->start_date_; + request_count_ = exported_invite->requested_; requires_approval_ = exported_invite->request_needed_; is_revoked_ = exported_invite->revoked_; is_permanent_ = exported_invite->permanent_; - if (is_permanent_ && - (usage_limit_ > 0 || expire_date_ > 0 || edit_date_ > 0 || request_count_ > 0 || requires_approval_)) { + LOG_IF(ERROR, !is_valid_invite_link(invite_link_)) << "Unsupported invite link " << invite_link_; + if (!creator_user_id_.is_valid()) { + LOG(ERROR) << "Receive invalid " << creator_user_id_ << " as creator of a link " << invite_link_; + creator_user_id_ = UserId(); + } + if (date_ < 1000000000) { + LOG(ERROR) << "Receive wrong date " << date_ << " as a creation date of a link " << invite_link_; + date_ = 0; + } + if (expire_date_ < 1000000000) { + LOG(ERROR) << "Receive wrong date " << expire_date_ << " as an expire date of a link " << invite_link_; + expire_date_ = 0; + } + if (usage_limit_ < 0) { + LOG(ERROR) << "Receive wrong usage limit " << usage_limit_ << " for a link " << invite_link_; + usage_limit_ = 0; + } + if (usage_count_ < 0) { + LOG(ERROR) << "Receive wrong usage count " << usage_count_ << " for a link " << invite_link_; + usage_count_ = 0; + } + if (edit_date_ < 1000000000) { + LOG(ERROR) << "Receive wrong date " << edit_date_ << " as an edit date of a link " << invite_link_; + edit_date_ = 0; + } + if (request_count_ < 0) { + LOG(ERROR) << "Receive wrong pending join request count " << request_count_ << " for a link " << invite_link_; + request_count_ = 0; + } + + if (is_permanent_ && (!title_.empty() || expire_date_ > 0 || usage_limit_ > 0 || edit_date_ > 0 || + request_count_ > 0 || requires_approval_)) { LOG(ERROR) << "Receive wrong permanent " << *this; + title_.clear(); expire_date_ = 0; usage_limit_ = 0; edit_date_ = 0; @@ -92,17 +85,18 @@ td_api::object_ptr DialogInviteLink::get_chat_invite_lin } return td_api::make_object( - invite_link_, contacts_manager->get_user_id_object(creator_user_id_, "get_chat_invite_link_object"), date_, - edit_date_, expire_date_, usage_limit_, usage_count_, request_count_, requires_approval_, is_permanent_, + invite_link_, title_, contacts_manager->get_user_id_object(creator_user_id_, "get_chat_invite_link_object"), + date_, edit_date_, expire_date_, usage_limit_, usage_count_, request_count_, requires_approval_, is_permanent_, is_revoked_); } bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { - return lhs.invite_link_ == rhs.invite_link_ && lhs.creator_user_id_ == rhs.creator_user_id_ && - lhs.date_ == rhs.date_ && lhs.edit_date_ == rhs.edit_date_ && lhs.expire_date_ == rhs.expire_date_ && - lhs.usage_limit_ == rhs.usage_limit_ && lhs.usage_count_ == rhs.usage_count_ && - lhs.request_count_ == rhs.request_count_ && lhs.requires_approval_ == rhs.requires_approval_ && - lhs.is_permanent_ == rhs.is_permanent_ && lhs.is_revoked_ == rhs.is_revoked_; + return lhs.invite_link_ == rhs.invite_link_ && lhs.title_ == rhs.title_ && + lhs.creator_user_id_ == rhs.creator_user_id_ && lhs.date_ == rhs.date_ && lhs.edit_date_ == rhs.edit_date_ && + lhs.expire_date_ == rhs.expire_date_ && lhs.usage_limit_ == rhs.usage_limit_ && + lhs.usage_count_ == rhs.usage_count_ && lhs.request_count_ == rhs.request_count_ && + lhs.requires_approval_ == rhs.requires_approval_ && lhs.is_permanent_ == rhs.is_permanent_ && + lhs.is_revoked_ == rhs.is_revoked_; } bool operator!=(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { @@ -110,7 +104,7 @@ bool operator!=(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { } StringBuilder &operator<<(StringBuilder &string_builder, const DialogInviteLink &invite_link) { - return string_builder << "ChatInviteLink[" << invite_link.invite_link_ + return string_builder << "ChatInviteLink[" << invite_link.invite_link_ << '(' << invite_link.title_ << ')' << (invite_link.requires_approval_ ? " requiring approval" : "") << " by " << invite_link.creator_user_id_ << " created at " << invite_link.date_ << " edited at " << invite_link.edit_date_ << " expiring at " << invite_link.expire_date_ << " used by " diff --git a/td/telegram/DialogInviteLink.h b/td/telegram/DialogInviteLink.h index eb92ec853..accfdd396 100644 --- a/td/telegram/DialogInviteLink.h +++ b/td/telegram/DialogInviteLink.h @@ -21,6 +21,7 @@ class ContactsManager; class DialogInviteLink { string invite_link_; + string title_; UserId creator_user_id_; int32 date_ = 0; int32 edit_date_ = 0; @@ -69,6 +70,7 @@ class DialogInviteLink { bool has_usage_count = usage_count_ != 0; bool has_edit_date = edit_date_ != 0; bool has_request_count = request_count_ != 0; + bool has_title = !title_.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_revoked_); STORE_FLAG(is_permanent_); @@ -78,6 +80,7 @@ class DialogInviteLink { STORE_FLAG(has_edit_date); STORE_FLAG(has_request_count); STORE_FLAG(requires_approval_); + STORE_FLAG(has_title); END_STORE_FLAGS(); store(invite_link_, storer); store(creator_user_id_, storer); @@ -97,6 +100,9 @@ class DialogInviteLink { if (has_request_count) { store(request_count_, storer); } + if (has_title) { + store(title_, storer); + } } template @@ -107,6 +113,7 @@ class DialogInviteLink { bool has_usage_count; bool has_edit_date; bool has_request_count; + bool has_title; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_revoked_); PARSE_FLAG(is_permanent_); @@ -116,6 +123,7 @@ class DialogInviteLink { PARSE_FLAG(has_edit_date); PARSE_FLAG(has_request_count); PARSE_FLAG(requires_approval_); + PARSE_FLAG(has_title); END_PARSE_FLAGS(); parse(invite_link_, parser); parse(creator_user_id_, parser); @@ -135,6 +143,9 @@ class DialogInviteLink { if (has_request_count) { parse(request_count_, parser); } + if (has_title) { + parse(title_, parser); + } } }; From 1f75f7b4947afae4dd73dc53cd6b08eeddc53a95 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 13:46:01 +0300 Subject: [PATCH 40/82] Improve documentation. --- td/generate/scheme/td_api.tl | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 24e60cf2d..2d93c1e82 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -56,7 +56,7 @@ authenticationCodeTypeCall length:int32 = AuthenticationCodeType; authenticationCodeTypeFlashCall pattern:string = AuthenticationCodeType; -//@description Information about the authentication code that was sent @phone_number A phone number that is being authenticated @type Describes the way the code was sent to the user @next_type Describes the way the next code will be sent to the user; may be null @timeout Timeout before the code can be re-sent, in seconds +//@description Information about the authentication code that was sent @phone_number A phone number that is being authenticated @type The way the code was sent to the user @next_type The way the next code will be sent to the user; may be null @timeout Timeout before the code can be re-sent, in seconds authenticationCodeInfo phone_number:string type:AuthenticationCodeType next_type:AuthenticationCodeType timeout:int32 = AuthenticationCodeInfo; //@description Information about the email address authentication code that was sent @email_address_pattern Pattern of the email address to which an authentication code was sent @length Length of the code; 0 if unknown @@ -500,7 +500,7 @@ chatMemberStatusLeft = ChatMemberStatus; chatMemberStatusBanned banned_until_date:int32 = ChatMemberStatus; -//@description Information about a user or a chat as a member of another chat +//@description Describes a user or a chat as a member of another chat //@member_id Identifier of the chat member. Currently, other chats can be only Left or Banned. Only supergroups and channels can have other chats as Left or Banned members and these chats must be supergroups or channels //@inviter_user_id Identifier of a user that invited/promoted/banned this member in the chat; 0 if unknown //@joined_chat_date Point in time (Unix timestamp) when the user joined the chat @@ -598,7 +598,7 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@description Contains information about a chat invite link //@chat_id Chat identifier of the invite link; 0 if the user has no access to the chat before joining //@accessible_for If non-zero, the amount of time for which read access to the chat will remain available, in seconds -//@type Contains information about the type of the chat +//@type Type of the chat //@title Title of the chat //@photo Chat photo; may be null //@param_description Chat description @@ -757,7 +757,7 @@ messageReplyInfo reply_count:int32 recent_repliers:vector last_re //@description Contains information about interactions with a message //@view_count Number of times the message was viewed //@forward_count Number of times the message was forwarded -//@reply_info Contains information about direct or indirect replies to the message; may be null. Currently, available only in channels with a discussion supergroup and discussion supergroups for messages, which are not replies itself +//@reply_info Information about direct or indirect replies to the message; may be null. Currently, available only in channels with a discussion supergroup and discussion supergroups for messages, which are not replies itself messageInteractionInfo view_count:int32 forward_count:int32 reply_info:messageReplyInfo = MessageInteractionInfo; @@ -775,8 +775,8 @@ messageSendingStateFailed error_code:int32 error_message:string can_retry:Bool r //@id Message identifier; unique for the chat to which the message belongs //@sender The sender of the message //@chat_id Chat identifier -//@sending_state Information about the sending state of the message; may be null -//@scheduling_state Information about the scheduling state of the message; may be null +//@sending_state The sending state of the message; may be null +//@scheduling_state The scheduling state of the message; may be null //@is_outgoing True, if the message is outgoing //@is_pinned True, if the message is pinned //@can_be_edited True, if the message can be edited. For live location and poll messages this fields shows whether editMessageLiveLocation or stopPoll can be used with this message by the application @@ -970,7 +970,7 @@ videoChat group_call_id:int32 has_participants:Bool default_participant_id:Messa //@notification_settings Notification settings for this chat //@message_ttl_setting Current message Time To Live setting (self-destruct timer) for the chat; 0 if not defined. TTL is counted from the time message or its content is viewed in secret chats and from the send date in other chats //@theme_name If non-empty, name of a theme, set for the chat -//@action_bar Describes actions which must be possible to do through a chat action bar; may be null +//@action_bar Information about actions which must be possible to do through the chat action bar; may be null //@video_chat Information about video chat of the chat //@pending_join_requests Information about pending join requests; may be null //@reply_markup_message_id Identifier of the message from which reply markup needs to be used; 0 if there is no default custom reply markup in the chat @@ -1106,7 +1106,7 @@ loginUrlInfoRequestConfirmation url:string domain:string bot_user_id:int53 reque //@description Contains information about a message thread //@chat_id Identifier of the chat to which the message thread belongs //@message_thread_id Message thread identifier, unique within the chat -//@reply_info Contains information about the message thread +//@reply_info Information about the message thread //@unread_message_count Approximate number of unread messages in the message thread //@messages The messages from which the thread starts. The messages are returned in a reverse chronological order (i.e., in order of decreasing message_id) //@draft_message A draft of a message in the message thread; may be null @@ -1392,7 +1392,7 @@ savedCredentials id:string title:string = SavedCredentials; //@description Applies if a user chooses some previously saved payment credentials. To use their previously saved credentials, the user must have a valid temporary password @saved_credentials_id Identifier of the saved credentials inputCredentialsSaved saved_credentials_id:string = InputCredentials; -//@description Applies if a user enters new credentials on a payment provider website @data Contains JSON-encoded data with a credential identifier from the payment provider @allow_save True, if the credential identifier can be saved on the server side +//@description Applies if a user enters new credentials on a payment provider website @data JSON-encoded data with the credential identifier from the payment provider @allow_save True, if the credential identifier can be saved on the server side inputCredentialsNew data:string allow_save:Bool = InputCredentials; //@description Applies if a user enters new credentials using Apple Pay @data JSON-encoded data with the credential identifier @@ -1415,9 +1415,9 @@ paymentFormTheme background_color:int32 text_color:int32 hint_color:int32 link_c //@url Payment form URL //@seller_bot_user_id User identifier of the seller bot //@payments_provider_user_id User identifier of the payment provider bot -//@payments_provider Contains information about the payment provider, if available, to support it natively without the need for opening the URL; may be null +//@payments_provider Information about the payment provider, if available, to support it natively without the need for opening the URL; may be null //@saved_order_info Saved server-side order information; may be null -//@saved_credentials Contains information about saved card credentials; may be null +//@saved_credentials Information about saved card credentials; may be null //@can_save_credentials True, if the user can choose to save credentials //@need_password True, if the user will be able to save credentials protected by a password they set up paymentForm id:int64 invoice:invoice url:string seller_bot_user_id:int53 payments_provider_user_id:int53 payments_provider:paymentsProviderStripe saved_order_info:orderInfo saved_credentials:savedCredentials can_save_credentials:Bool need_password:Bool = PaymentForm; @@ -1435,7 +1435,7 @@ paymentResult success:Bool verification_url:string = PaymentResult; //@date Point in time (Unix timestamp) when the payment was made //@seller_bot_user_id User identifier of the seller bot //@payments_provider_user_id User identifier of the payment provider bot -//@invoice Contains information about the invoice +//@invoice Information about the invoice //@order_info Order information; may be null //@shipping_option Chosen shipping option; may be null //@credentials_title Title of the saved credentials chosen by the buyer @@ -1643,7 +1643,7 @@ passportSuitableElement type:PassportElementType is_selfie_required:Bool is_tran passportRequiredElement suitable_elements:vector = PassportRequiredElement; //@description Contains information about a Telegram Passport authorization form that was requested @id Unique identifier of the authorization form -//@required_elements Information about the Telegram Passport elements that must be provided to complete the form +//@required_elements Telegram Passport elements that must be provided to complete the form //@privacy_policy_url URL for the privacy policy of the service; may be empty passportAuthorizationForm id:int32 required_elements:vector privacy_policy_url:string = PassportAuthorizationForm; @@ -1740,7 +1740,7 @@ messageVenue venue:venue = MessageContent; //@description A message with a user contact @contact The contact description messageContact contact:contact = MessageContent; -//@description A message with an animated emoji @animated_emoji Description of the animated emoji @emoji The corresponding emoji +//@description A message with an animated emoji @animated_emoji The animated emoji @emoji The corresponding emoji messageAnimatedEmoji animated_emoji:animatedEmoji emoji:string = MessageContent; //@description A dice message. The dice value is randomly generated by the server @@ -2154,7 +2154,7 @@ stickerSet id:int64 title:string name:string thumbnail:thumbnail thumbnail_outli //@thumbnail_outline Sticker set thumbnail's outline represented as a list of closed vector paths; may be empty. The coordinate system origin is in the upper-left corner //@is_installed True, if the sticker set has been installed by the current user @is_archived True, if the sticker set has been archived. A sticker set can't be installed and archived simultaneously //@is_official True, if the sticker set is official @is_animated True, is the stickers in the set are animated @is_masks True, if the stickers in the set are masks @is_viewed True for already viewed trending sticker sets -//@size Total number of stickers in the set @covers Contains up to the first 5 stickers from the set, depending on the context. If the application needs more stickers the full sticker set needs to be requested +//@size Total number of stickers in the set @covers Up to the first 5 stickers from the set, depending on the context. If the application needs more stickers the full sticker set needs to be requested stickerSetInfo id:int64 title:string name:string thumbnail:thumbnail thumbnail_outline:vector is_installed:Bool is_archived:Bool is_official:Bool is_animated:Bool is_masks:Bool is_viewed:Bool size:int32 covers:vector = StickerSetInfo; //@description Represents a list of sticker sets @total_count Approximate total number of sticker sets found @sets List of sticker sets @@ -2726,13 +2726,13 @@ backgroundFillFreeformGradient colors:vector = BackgroundFill; backgroundTypeWallpaper is_blurred:Bool is_moving:Bool = BackgroundType; //@description A PNG or TGV (gzipped subset of SVG with MIME type "application/x-tgwallpattern") pattern to be combined with the background fill chosen by the user -//@fill Description of the background fill +//@fill Fill of the background //@intensity Intensity of the pattern when it is shown above the filled background; 0-100. //@is_inverted True, if the background fill must be applied only to the pattern itself. All other pixels are black in this case. For dark themes only //@is_moving True, if the background needs to be slightly moved when device is tilted backgroundTypePattern fill:BackgroundFill intensity:int32 is_inverted:Bool is_moving:Bool = BackgroundType; -//@description A filled background @fill Description of the background fill +//@description A filled background @fill The background fill backgroundTypeFill fill:BackgroundFill = BackgroundType; @@ -3639,11 +3639,11 @@ updateNewMessage message:message = Update; //@chat_id The chat identifier of the sent message @message_id A temporary message identifier updateMessageSendAcknowledged chat_id:int53 message_id:int53 = Update; -//@description A message has been successfully sent @message Information about the sent message. Usually only the message identifier, date, and content are changed, but almost all other fields can also change @old_message_id The previous temporary message identifier +//@description A message has been successfully sent @message The sent message. Usually only the message identifier, date, and content are changed, but almost all other fields can also change @old_message_id The previous temporary message identifier updateMessageSendSucceeded message:message old_message_id:int53 = Update; //@description A message failed to send. Be aware that some messages being sent can be irrecoverably deleted, in which case updateDeleteMessages will be received instead of this update -//@message Contains information about the message which failed to send @old_message_id The previous temporary message identifier @error_code An error code @error_message Error message +//@message The failed to send message @old_message_id The previous temporary message identifier @error_code An error code @error_message Error message updateMessageSendFailed message:message old_message_id:int53 error_code:int32 error_message:string = Update; //@description The message content has changed @chat_id Chat identifier @message_id Message identifier @new_content New message content @@ -3892,7 +3892,7 @@ updateAnimationSearchParameters provider:string emojis:vector = Update; updateSuggestedActions added_actions:vector removed_actions:vector = Update; //@description A new incoming inline query; for bots only @id Unique query identifier @sender_user_id Identifier of the user who sent the query @user_location User location; may be null -//@chat_type Contains information about the type of the chat, from which the query originated; may be null if unknown @query Text of the query @offset Offset of the first entry to return +//@chat_type The type of the chat, from which the query originated; may be null if unknown @query Text of the query @offset Offset of the first entry to return updateNewInlineQuery id:int64 sender_user_id:int53 user_location:location chat_type:ChatType query:string offset:string = Update; //@description The user has chosen a result of an inline query; for bots only @sender_user_id Identifier of the user who sent the query @user_location User location; may be null @@ -4976,10 +4976,10 @@ approveChatJoinRequest chat_id:int53 user_id:int53 = Ok; declineChatJoinRequest chat_id:int53 user_id:int53 = Ok; -//@description Creates a new call @user_id Identifier of the user to be called @protocol Description of the call protocols supported by the application @is_video True, if a video call needs to be created +//@description Creates a new call @user_id Identifier of the user to be called @protocol The call protocols supported by the application @is_video True, if a video call needs to be created createCall user_id:int53 protocol:callProtocol is_video:Bool = CallId; -//@description Accepts an incoming call @call_id Call identifier @protocol Description of the call protocols supported by the application +//@description Accepts an incoming call @call_id Call identifier @protocol The call protocols supported by the application acceptCall call_id:int32 protocol:callProtocol = Ok; //@description Sends call signaling data @call_id Call identifier @data The data From 2cd186f7b8d2323cbe9fa4244ef5e0044ef77b1b Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 15:02:50 +0300 Subject: [PATCH 41/82] Fix invite link field checks. --- td/telegram/DialogInviteLink.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/td/telegram/DialogInviteLink.cpp b/td/telegram/DialogInviteLink.cpp index a66b9f444..3cc8e2324 100644 --- a/td/telegram/DialogInviteLink.cpp +++ b/td/telegram/DialogInviteLink.cpp @@ -36,11 +36,11 @@ DialogInviteLink::DialogInviteLink(tl_object_ptr Date: Wed, 27 Oct 2021 15:19:07 +0300 Subject: [PATCH 42/82] Fix getAnimatedEmoji. --- td/telegram/StickersManager.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index e8f90d733..0fcab4dcb 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1286,7 +1286,6 @@ void StickersManager::init() { on_update_emoji_sounds(); on_update_disable_animated_emojis(); - if (!disable_animated_emojis_) { load_special_sticker_set(add_special_sticker_set(SpecialStickerSetType::animated_emoji())); } @@ -1374,6 +1373,7 @@ void StickersManager::load_special_sticker_set(SpecialStickerSet &sticker_set) { return; } sticker_set.is_being_loaded_ = true; + LOG(INFO) << "Load " << sticker_set.type_.type_ << " " << sticker_set.id_; if (sticker_set.id_.is_valid()) { auto promise = PromiseCreator::lambda([actor_id = actor_id(this), type = sticker_set.type_](Result &&result) { send_closure(actor_id, &StickersManager::on_load_special_sticker_set, type, @@ -1412,6 +1412,11 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t special_sticker_set.is_being_loaded_ = false; if (type.type_ == SpecialStickerSetType::animated_emoji()) { + auto promises = std::move(pending_get_animated_emoji_queries_); + reset_to_empty(pending_get_animated_emoji_queries_); + for (auto &promise : promises) { + promise.set_value(Unit()); + } return; } @@ -1433,11 +1438,6 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t schedule_update_animated_emoji_clicked(sticker_set, pending_request.emoji_, pending_request.full_message_id_, std::move(pending_request.clicks_)); } - auto promises = std::move(pending_get_animated_emoji_queries_); - reset_to_empty(pending_get_animated_emoji_queries_); - for (auto &promise : promises) { - promise.set_value(Unit()); - } return; } From 8916cacd21866d78ba682a6e63b1460e513fefd4 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 15:27:09 +0300 Subject: [PATCH 43/82] Improve log event name. --- td/telegram/MessagesManager.cpp | 21 ++++++++++----------- td/telegram/MessagesManager.h | 4 ++-- td/telegram/TdDb.cpp | 2 +- td/telegram/logevent/LogEvent.h | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 5f9200c59..a3ed012a1 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -30925,7 +30925,7 @@ void MessagesManager::on_get_dialog_notification_settings_query_finished(DialogI } } -class MessagesManager::GetDialogFromServerLogEvent { +class MessagesManager::RegetDialogLogEvent { public: DialogId dialog_id_; @@ -30940,10 +30940,9 @@ class MessagesManager::GetDialogFromServerLogEvent { } }; -uint64 MessagesManager::save_get_dialog_from_server_log_event(DialogId dialog_id) { - GetDialogFromServerLogEvent log_event{dialog_id}; - return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::GetDialogFromServer, - get_log_event_storer(log_event)); +uint64 MessagesManager::save_reget_dialog_log_event(DialogId dialog_id) { + RegetDialogLogEvent log_event{dialog_id}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::RegetDialog, get_log_event_storer(log_event)); } void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise &&promise, uint64 log_event_id, @@ -30975,7 +30974,7 @@ void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise && } if (log_event_id == 0 && G()->parameters().use_message_db) { - log_event_id = save_get_dialog_from_server_log_event(dialog_id); + log_event_id = save_reget_dialog_log_event(dialog_id); } if (log_event_id != 0) { auto result = get_dialog_query_log_event_id_.emplace(dialog_id, log_event_id); @@ -37963,28 +37962,28 @@ void MessagesManager::on_binlog_events(vector &&events) { set_dialog_folder_id_on_server(dialog_id, true); break; } - case LogEvent::HandlerType::GetDialogFromServer: { + case LogEvent::HandlerType::RegetDialog: { if (!G()->parameters().use_message_db) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - GetDialogFromServerLogEvent log_event; + RegetDialogLogEvent log_event; log_event_parse(log_event, event.data_).ensure(); auto dialog_id = log_event.dialog_id_; Dependencies dependencies; add_dialog_dependencies(dependencies, dialog_id); - resolve_dependencies_force(td_, dependencies, "GetDialogFromServerLogEvent"); + resolve_dependencies_force(td_, dependencies, "RegetDialogLogEvent"); - get_dialog_force(dialog_id, "GetDialogFromServerLogEvent"); // load it if exists + get_dialog_force(dialog_id, "RegetDialogLogEvent"); // load it if exists if (!have_input_peer(dialog_id, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - send_get_dialog_query(dialog_id, Auto(), event.id_, "GetDialogFromServerLogEvent"); + send_get_dialog_query(dialog_id, Auto(), event.id_, "RegetDialogLogEvent"); break; } case LogEvent::HandlerType::UnpinAllDialogMessagesOnServer: { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 199f1fd8d..e2c289bab 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1654,12 +1654,12 @@ class MessagesManager final : public Actor { class DeleteScheduledMessagesFromServerLogEvent; class ForwardMessagesLogEvent; class GetChannelDifferenceLogEvent; - class GetDialogFromServerLogEvent; class ReadAllDialogMentionsOnServerLogEvent; class ReadHistoryInSecretChatLogEvent; class ReadHistoryOnServerLogEvent; class ReadMessageContentsOnServerLogEvent; class ReadMessageThreadHistoryOnServerLogEvent; + class RegetDialogLogEvent; class ReorderPinnedDialogsOnServerLogEvent; class ResetAllNotificationSettingsOnServerLogEvent; class SaveDialogDraftMessageOnServerLogEvent; @@ -3116,7 +3116,7 @@ class MessagesManager final : public Actor { static uint64 save_reset_all_notification_settings_on_server_log_event(); - static uint64 save_get_dialog_from_server_log_event(DialogId dialog_id); + static uint64 save_reget_dialog_log_event(DialogId dialog_id); static uint64 save_forward_messages_log_event(DialogId to_dialog_id, DialogId from_dialog_id, const vector &messages, diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 315cd5daa..05e9cc624 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -108,7 +108,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::UpdateScopeNotificationSettingsOnServer: case LogEvent::HandlerType::ResetAllNotificationSettingsOnServer: case LogEvent::HandlerType::ToggleDialogReportSpamStateOnServer: - case LogEvent::HandlerType::GetDialogFromServer: + case LogEvent::HandlerType::RegetDialog: case LogEvent::HandlerType::GetChannelDifference: case LogEvent::HandlerType::ReadHistoryInSecretChat: case LogEvent::HandlerType::ToggleDialogIsMarkedAsUnreadOnServer: diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index 042460bc5..1b23c87a5 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -89,7 +89,7 @@ class LogEvent { UpdateScopeNotificationSettingsOnServer = 0x110, ResetAllNotificationSettingsOnServer = 0x111, ToggleDialogReportSpamStateOnServer = 0x112, - GetDialogFromServer = 0x113, + RegetDialog = 0x113, ReadHistoryInSecretChat = 0x114, ToggleDialogIsMarkedAsUnreadOnServer = 0x115, SetDialogFolderIdOnServer = 0x116, From 93f2436f0eaf117f8e09d051b88b543ed8ce1b3e Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 15:38:09 +0300 Subject: [PATCH 44/82] Use Delete..OnServer instead of Delete..FromServer. --- td/telegram/MessagesManager.cpp | 132 ++++++++++++++++---------------- td/telegram/MessagesManager.h | 38 ++++----- td/telegram/SecretChatActor.cpp | 2 +- td/telegram/TdDb.cpp | 8 +- td/telegram/logevent/LogEvent.h | 8 +- 5 files changed, 94 insertions(+), 94 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index a3ed012a1..409d3dbb9 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -10436,13 +10436,13 @@ void MessagesManager::delete_messages(DialogId dialog_id, const vector message_ids_; @@ -10524,15 +10524,15 @@ class MessagesManager::DeleteMessagesFromServerLogEvent { } }; -uint64 MessagesManager::save_delete_messages_from_server_log_event(DialogId dialog_id, - const vector &message_ids, bool revoke) { - DeleteMessagesFromServerLogEvent log_event{dialog_id, message_ids, revoke}; - return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteMessagesFromServer, +uint64 MessagesManager::save_delete_messages_on_server_log_event(DialogId dialog_id, + const vector &message_ids, bool revoke) { + DeleteMessagesOnServerLogEvent log_event{dialog_id, message_ids, revoke}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteMessagesOnServer, get_log_event_storer(log_event)); } -void MessagesManager::delete_messages_from_server(DialogId dialog_id, vector message_ids, bool revoke, - uint64 log_event_id, Promise &&promise) { +void MessagesManager::delete_messages_on_server(DialogId dialog_id, vector message_ids, bool revoke, + uint64 log_event_id, Promise &&promise) { if (message_ids.empty()) { return promise.set_value(Unit()); } @@ -10540,7 +10540,7 @@ void MessagesManager::delete_messages_from_server(DialogId dialog_id, vectorparameters().use_message_db) { - log_event_id = save_delete_messages_from_server_log_event(dialog_id, message_ids, revoke); + log_event_id = save_delete_messages_on_server_log_event(dialog_id, message_ids, revoke); } auto new_promise = get_erase_log_event_promise(log_event_id, std::move(promise)); @@ -10557,7 +10557,7 @@ void MessagesManager::delete_messages_from_server(DialogId dialog_id, vector random_ids; - auto d = get_dialog_force(dialog_id, "delete_messages_from_server"); + auto d = get_dialog_force(dialog_id, "delete_messages_on_server"); CHECK(d != nullptr); for (auto &message_id : message_ids) { auto *m = get_message(d, message_id); @@ -10579,7 +10579,7 @@ void MessagesManager::delete_messages_from_server(DialogId dialog_id, vector message_ids_; @@ -10597,22 +10597,22 @@ class MessagesManager::DeleteScheduledMessagesFromServerLogEvent { } }; -uint64 MessagesManager::save_delete_scheduled_messages_from_server_log_event(DialogId dialog_id, - const vector &message_ids) { - DeleteScheduledMessagesFromServerLogEvent log_event{dialog_id, message_ids}; - return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteScheduledMessagesFromServer, +uint64 MessagesManager::save_delete_scheduled_messages_on_server_log_event(DialogId dialog_id, + const vector &message_ids) { + DeleteScheduledMessagesOnServerLogEvent log_event{dialog_id, message_ids}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteScheduledMessagesOnServer, get_log_event_storer(log_event)); } -void MessagesManager::delete_scheduled_messages_from_server(DialogId dialog_id, vector message_ids, - uint64 log_event_id, Promise &&promise) { +void MessagesManager::delete_scheduled_messages_on_server(DialogId dialog_id, vector message_ids, + uint64 log_event_id, Promise &&promise) { if (message_ids.empty()) { return promise.set_value(Unit()); } LOG(INFO) << "Delete " << format::as_array(message_ids) << " in " << dialog_id << " from server"; if (log_event_id == 0 && G()->parameters().use_message_db) { - log_event_id = save_delete_scheduled_messages_from_server_log_event(dialog_id, message_ids); + log_event_id = save_delete_scheduled_messages_on_server_log_event(dialog_id, message_ids); } auto new_promise = get_erase_log_event_promise(log_event_id, std::move(promise)); @@ -10695,11 +10695,11 @@ void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from set_dialog_max_unavailable_message_id(dialog_id, last_new_message_id, false, "delete_dialog_history"); - delete_dialog_history_from_server(dialog_id, last_new_message_id, remove_from_dialog_list, revoke, allow_error, 0, - std::move(promise)); + delete_dialog_history_on_server(dialog_id, last_new_message_id, remove_from_dialog_list, revoke, allow_error, 0, + std::move(promise)); } -class MessagesManager::DeleteDialogHistoryFromServerLogEvent { +class MessagesManager::DeleteDialogHistoryOnServerLogEvent { public: DialogId dialog_id_; MessageId max_message_id_; @@ -10729,21 +10729,21 @@ class MessagesManager::DeleteDialogHistoryFromServerLogEvent { } }; -uint64 MessagesManager::save_delete_dialog_history_from_server_log_event(DialogId dialog_id, MessageId max_message_id, - bool remove_from_dialog_list, bool revoke) { - DeleteDialogHistoryFromServerLogEvent log_event{dialog_id, max_message_id, remove_from_dialog_list, revoke}; - return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteDialogHistoryFromServer, +uint64 MessagesManager::save_delete_dialog_history_on_server_log_event(DialogId dialog_id, MessageId max_message_id, + bool remove_from_dialog_list, bool revoke) { + DeleteDialogHistoryOnServerLogEvent log_event{dialog_id, max_message_id, remove_from_dialog_list, revoke}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteDialogHistoryOnServer, get_log_event_storer(log_event)); } -void MessagesManager::delete_dialog_history_from_server(DialogId dialog_id, MessageId max_message_id, - bool remove_from_dialog_list, bool revoke, bool allow_error, - uint64 log_event_id, Promise &&promise) { +void MessagesManager::delete_dialog_history_on_server(DialogId dialog_id, MessageId max_message_id, + bool remove_from_dialog_list, bool revoke, bool allow_error, + uint64 log_event_id, Promise &&promise) { LOG(INFO) << "Delete history in " << dialog_id << " up to " << max_message_id << " from server"; if (log_event_id == 0 && G()->parameters().use_message_db) { log_event_id = - save_delete_dialog_history_from_server_log_event(dialog_id, max_message_id, remove_from_dialog_list, revoke); + save_delete_dialog_history_on_server_log_event(dialog_id, max_message_id, remove_from_dialog_list, revoke); } auto new_promise = get_erase_log_event_promise(log_event_id, std::move(promise)); @@ -10771,10 +10771,10 @@ void MessagesManager::delete_dialog_history_from_server(DialogId dialog_id, Mess } void MessagesManager::delete_all_call_messages(bool revoke, Promise &&promise) { - delete_all_call_messages_from_server(revoke, 0, std::move(promise)); + delete_all_call_messages_on_server(revoke, 0, std::move(promise)); } -class MessagesManager::DeleteAllCallMessagesFromServerLogEvent { +class MessagesManager::DeleteAllCallMessagesOnServerLogEvent { public: bool revoke_; @@ -10793,15 +10793,15 @@ class MessagesManager::DeleteAllCallMessagesFromServerLogEvent { } }; -uint64 MessagesManager::save_delete_all_call_messages_from_server_log_event(bool revoke) { - DeleteAllCallMessagesFromServerLogEvent log_event{revoke}; - return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteAllCallMessagesFromServer, +uint64 MessagesManager::save_delete_all_call_messages_on_server_log_event(bool revoke) { + DeleteAllCallMessagesOnServerLogEvent log_event{revoke}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteAllCallMessagesOnServer, get_log_event_storer(log_event)); } -void MessagesManager::delete_all_call_messages_from_server(bool revoke, uint64 log_event_id, Promise &&promise) { +void MessagesManager::delete_all_call_messages_on_server(bool revoke, uint64 log_event_id, Promise &&promise) { if (log_event_id == 0) { - log_event_id = save_delete_all_call_messages_from_server_log_event(revoke); + log_event_id = save_delete_all_call_messages_on_server_log_event(revoke); } auto new_promise = get_erase_log_event_promise(log_event_id, std::move(promise)); @@ -13872,7 +13872,7 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, bool f unique_ptr old_message = delete_message(d, old_message_id, false, &need_update_dialog_pos, "add sent message"); if (old_message == nullptr) { - delete_sent_message_from_server(dialog_id, new_message->message_id); + delete_sent_message_on_server(dialog_id, new_message->message_id); being_readded_message_id_ = FullMessageId(); return FullMessageId(); } @@ -15680,7 +15680,7 @@ void MessagesManager::load_dialog_filter(const DialogFilter *filter, bool force, if (!input_dialog_ids.empty() && !force) { const size_t MAX_SLICE_SIZE = 100; - MultiPromiseActorSafe mpas{"GetFilterDialogsFromServerMultiPromiseActor"}; + MultiPromiseActorSafe mpas{"GetFilterDialogsOnServerMultiPromiseActor"}; mpas.add_promise(std::move(promise)); mpas.set_ignore_errors(true); auto lock = mpas.get_promise(); @@ -17700,7 +17700,7 @@ void MessagesManager::get_messages_from_server(vector &&message_i } } - MultiPromiseActorSafe mpas{"GetMessagesFromServerMultiPromiseActor"}; + MultiPromiseActorSafe mpas{"GetMessagesOnServerMultiPromiseActor"}; mpas.add_promise(std::move(promise)); auto lock = mpas.get_promise(); @@ -27414,7 +27414,7 @@ bool MessagesManager::on_update_message_id(int64 random_id, MessageId new_messag being_sent_messages_.erase(it); if (!have_message_force({dialog_id, old_message_id}, "on_update_message_id")) { - delete_sent_message_from_server(dialog_id, new_message_id); + delete_sent_message_on_server(dialog_id, new_message_id); return true; } @@ -27444,7 +27444,7 @@ bool MessagesManager::on_update_scheduled_message_id(int64 random_id, ScheduledS being_sent_messages_.erase(it); if (!have_message_force({dialog_id, old_message_id}, "on_update_scheduled_message_id")) { - delete_sent_message_from_server(dialog_id, MessageId(new_message_id, std::numeric_limits::max())); + delete_sent_message_on_server(dialog_id, MessageId(new_message_id, std::numeric_limits::max())); return true; } @@ -29324,7 +29324,7 @@ FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageI being_readded_message_id_ = {dialog_id, old_message_id}; unique_ptr sent_message = delete_message(d, old_message_id, false, &need_update_dialog_pos, source); if (sent_message == nullptr) { - delete_sent_message_from_server(dialog_id, new_message_id); + delete_sent_message_on_server(dialog_id, new_message_id); being_readded_message_id_ = FullMessageId(); return {}; } @@ -37542,17 +37542,17 @@ void MessagesManager::on_binlog_events(vector &&events) { do_delete_message_log_event(log_event); break; } - case LogEvent::HandlerType::DeleteMessagesFromServer: { + case LogEvent::HandlerType::DeleteMessagesOnServer: { if (!G()->parameters().use_message_db) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - DeleteMessagesFromServerLogEvent log_event; + DeleteMessagesOnServerLogEvent log_event; log_event_parse(log_event, event.data_).ensure(); auto dialog_id = log_event.dialog_id_; - Dialog *d = get_dialog_force(dialog_id, "DeleteMessagesFromServerLogEvent"); + Dialog *d = get_dialog_force(dialog_id, "DeleteMessagesOnServerLogEvent"); if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; @@ -37560,20 +37560,20 @@ void MessagesManager::on_binlog_events(vector &&events) { d->deleted_message_ids.insert(log_event.message_ids_.begin(), log_event.message_ids_.end()); - delete_messages_from_server(dialog_id, std::move(log_event.message_ids_), log_event.revoke_, event.id_, Auto()); + delete_messages_on_server(dialog_id, std::move(log_event.message_ids_), log_event.revoke_, event.id_, Auto()); break; } - case LogEvent::HandlerType::DeleteScheduledMessagesFromServer: { + case LogEvent::HandlerType::DeleteScheduledMessagesOnServer: { if (!G()->parameters().use_message_db) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - DeleteScheduledMessagesFromServerLogEvent log_event; + DeleteScheduledMessagesOnServerLogEvent log_event; log_event_parse(log_event, event.data_).ensure(); auto dialog_id = log_event.dialog_id_; - Dialog *d = get_dialog_force(dialog_id, "DeleteScheduledMessagesFromServerLogEvent"); + Dialog *d = get_dialog_force(dialog_id, "DeleteScheduledMessagesOnServerLogEvent"); if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; @@ -37584,34 +37584,34 @@ void MessagesManager::on_binlog_events(vector &&events) { d->deleted_scheduled_server_message_ids.insert(message_id.get_scheduled_server_message_id()); } - delete_scheduled_messages_from_server(dialog_id, std::move(log_event.message_ids_), event.id_, Auto()); + delete_scheduled_messages_on_server(dialog_id, std::move(log_event.message_ids_), event.id_, Auto()); break; } - case LogEvent::HandlerType::DeleteDialogHistoryFromServer: { + case LogEvent::HandlerType::DeleteDialogHistoryOnServer: { if (!G()->parameters().use_message_db) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - DeleteDialogHistoryFromServerLogEvent log_event; + DeleteDialogHistoryOnServerLogEvent log_event; log_event_parse(log_event, event.data_).ensure(); auto dialog_id = log_event.dialog_id_; - Dialog *d = get_dialog_force(dialog_id, "DeleteDialogHistoryFromServerLogEvent"); + Dialog *d = get_dialog_force(dialog_id, "DeleteDialogHistoryOnServerLogEvent"); if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - delete_dialog_history_from_server(dialog_id, log_event.max_message_id_, log_event.remove_from_dialog_list_, - log_event.revoke_, true, event.id_, Auto()); + delete_dialog_history_on_server(dialog_id, log_event.max_message_id_, log_event.remove_from_dialog_list_, + log_event.revoke_, true, event.id_, Auto()); break; } - case LogEvent::HandlerType::DeleteAllCallMessagesFromServer: { - DeleteAllCallMessagesFromServerLogEvent log_event; + case LogEvent::HandlerType::DeleteAllCallMessagesOnServer: { + DeleteAllCallMessagesOnServerLogEvent log_event; log_event_parse(log_event, event.data_).ensure(); - delete_all_call_messages_from_server(log_event.revoke_, event.id_, Auto()); + delete_all_call_messages_on_server(log_event.revoke_, event.id_, Auto()); break; } case LogEvent::HandlerType::BlockMessageSenderFromRepliesOnServer: { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index e2c289bab..c81f16405 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1645,13 +1645,13 @@ class MessagesManager final : public Actor { }; class BlockMessageSenderFromRepliesOnServerLogEvent; - class DeleteAllCallMessagesFromServerLogEvent; + class DeleteAllCallMessagesOnServerLogEvent; class DeleteAllChannelMessagesFromUserOnServerLogEvent; - class DeleteDialogHistoryFromServerLogEvent; + class DeleteDialogHistoryOnServerLogEvent; class DeleteDialogMessagesByDateOnServerLogEvent; class DeleteMessageLogEvent; - class DeleteMessagesFromServerLogEvent; - class DeleteScheduledMessagesFromServerLogEvent; + class DeleteMessagesOnServerLogEvent; + class DeleteScheduledMessagesOnServerLogEvent; class ForwardMessagesLogEvent; class GetChannelDifferenceLogEvent; class ReadAllDialogMentionsOnServerLogEvent; @@ -1993,18 +1993,18 @@ class MessagesManager final : public Actor { void do_delete_all_dialog_messages(Dialog *d, unique_ptr &message, bool is_permanently_deleted, vector &deleted_message_ids); - void delete_sent_message_from_server(DialogId dialog_id, MessageId message_id); + void delete_sent_message_on_server(DialogId dialog_id, MessageId message_id); - void delete_messages_from_server(DialogId dialog_id, vector message_ids, bool revoke, uint64 log_event_id, - Promise &&promise); + void delete_messages_on_server(DialogId dialog_id, vector message_ids, bool revoke, uint64 log_event_id, + Promise &&promise); - void delete_scheduled_messages_from_server(DialogId dialog_id, vector message_ids, uint64 log_event_id, - Promise &&promise); + void delete_scheduled_messages_on_server(DialogId dialog_id, vector message_ids, uint64 log_event_id, + Promise &&promise); - void delete_dialog_history_from_server(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list, - bool revoke, bool allow_error, uint64 log_event_id, Promise &&promise); + void delete_dialog_history_on_server(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list, + bool revoke, bool allow_error, uint64 log_event_id, Promise &&promise); - void delete_all_call_messages_from_server(bool revoke, uint64 log_event_id, Promise &&promise); + void delete_all_call_messages_on_server(bool revoke, uint64 log_event_id, Promise &&promise); void block_message_sender_from_replies_on_server(MessageId message_id, bool need_delete_message, bool need_delete_all_messages, bool report_spam, uint64 log_event_id, @@ -3077,16 +3077,16 @@ class MessagesManager final : public Actor { static uint64 save_toggle_dialog_report_spam_state_on_server_log_event(DialogId dialog_id, bool is_spam_dialog); - static uint64 save_delete_messages_from_server_log_event(DialogId dialog_id, const vector &message_ids, - bool revoke); + static uint64 save_delete_messages_on_server_log_event(DialogId dialog_id, const vector &message_ids, + bool revoke); - static uint64 save_delete_scheduled_messages_from_server_log_event(DialogId dialog_id, - const vector &message_ids); + static uint64 save_delete_scheduled_messages_on_server_log_event(DialogId dialog_id, + const vector &message_ids); - static uint64 save_delete_dialog_history_from_server_log_event(DialogId dialog_id, MessageId max_message_id, - bool remove_from_dialog_list, bool revoke); + static uint64 save_delete_dialog_history_on_server_log_event(DialogId dialog_id, MessageId max_message_id, + bool remove_from_dialog_list, bool revoke); - static uint64 save_delete_all_call_messages_from_server_log_event(bool revoke); + static uint64 save_delete_all_call_messages_on_server_log_event(bool revoke); static uint64 save_block_message_sender_from_replies_on_server_log_event(MessageId message_id, bool need_delete_message, diff --git a/td/telegram/SecretChatActor.cpp b/td/telegram/SecretChatActor.cpp index 94628cfa2..adc4d6058 100644 --- a/td/telegram/SecretChatActor.cpp +++ b/td/telegram/SecretChatActor.cpp @@ -693,7 +693,7 @@ void SecretChatActor::do_close_chat_impl(bool delete_history, bool is_already_di context_->secret_chat_db()->erase_value(pfs_state_); context_->secret_chat_db()->erase_value(seq_no_state_); - MultiPromiseActorSafe mpas{"DeleteMessagesFromServerMultiPromiseActor"}; + MultiPromiseActorSafe mpas{"CloseSecretChatMultiPromiseActor"}; mpas.add_promise( PromiseCreator::lambda([actor_id = actor_id(this), log_event_id, promise = std::move(promise)](Unit) mutable { send_closure(actor_id, &SecretChatActor::on_closed, log_event_id, std::move(promise)); diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 05e9cc624..56c09e075 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -91,14 +91,14 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p break; case LogEvent::HandlerType::SendMessage: case LogEvent::HandlerType::DeleteMessage: - case LogEvent::HandlerType::DeleteMessagesFromServer: + case LogEvent::HandlerType::DeleteMessagesOnServer: case LogEvent::HandlerType::ReadHistoryOnServer: case LogEvent::HandlerType::ReadMessageContentsOnServer: case LogEvent::HandlerType::ForwardMessages: case LogEvent::HandlerType::SendBotStartMessage: case LogEvent::HandlerType::SendScreenshotTakenNotificationMessage: case LogEvent::HandlerType::SendInlineQueryResultMessage: - case LogEvent::HandlerType::DeleteDialogHistoryFromServer: + case LogEvent::HandlerType::DeleteDialogHistoryOnServer: case LogEvent::HandlerType::ReadAllDialogMentionsOnServer: case LogEvent::HandlerType::DeleteAllChannelMessagesFromUserOnServer: case LogEvent::HandlerType::ToggleDialogIsPinnedOnServer: @@ -113,12 +113,12 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::ReadHistoryInSecretChat: case LogEvent::HandlerType::ToggleDialogIsMarkedAsUnreadOnServer: case LogEvent::HandlerType::SetDialogFolderIdOnServer: - case LogEvent::HandlerType::DeleteScheduledMessagesFromServer: + case LogEvent::HandlerType::DeleteScheduledMessagesOnServer: case LogEvent::HandlerType::ToggleDialogIsBlockedOnServer: case LogEvent::HandlerType::ReadMessageThreadHistoryOnServer: case LogEvent::HandlerType::BlockMessageSenderFromRepliesOnServer: case LogEvent::HandlerType::UnpinAllDialogMessagesOnServer: - case LogEvent::HandlerType::DeleteAllCallMessagesFromServer: + case LogEvent::HandlerType::DeleteAllCallMessagesOnServer: case LogEvent::HandlerType::DeleteDialogMessagesByDateOnServer: events.to_messages_manager.push_back(event.clone()); break; diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index 1b23c87a5..cd5641546 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -72,14 +72,14 @@ class LogEvent { StopPoll = 0x21, SendMessage = 0x100, DeleteMessage = 0x101, - DeleteMessagesFromServer = 0x102, + DeleteMessagesOnServer = 0x102, ReadHistoryOnServer = 0x103, ForwardMessages = 0x104, ReadMessageContentsOnServer = 0x105, SendBotStartMessage = 0x106, SendScreenshotTakenNotificationMessage = 0x107, SendInlineQueryResultMessage = 0x108, - DeleteDialogHistoryFromServer = 0x109, + DeleteDialogHistoryOnServer = 0x109, ReadAllDialogMentionsOnServer = 0x10a, DeleteAllChannelMessagesFromUserOnServer = 0x10b, ToggleDialogIsPinnedOnServer = 0x10c, @@ -93,12 +93,12 @@ class LogEvent { ReadHistoryInSecretChat = 0x114, ToggleDialogIsMarkedAsUnreadOnServer = 0x115, SetDialogFolderIdOnServer = 0x116, - DeleteScheduledMessagesFromServer = 0x117, + DeleteScheduledMessagesOnServer = 0x117, ToggleDialogIsBlockedOnServer = 0x118, ReadMessageThreadHistoryOnServer = 0x119, BlockMessageSenderFromRepliesOnServer = 0x120, UnpinAllDialogMessagesOnServer = 0x121, - DeleteAllCallMessagesFromServer = 0x122, + DeleteAllCallMessagesOnServer = 0x122, DeleteDialogMessagesByDateOnServer = 0x123, GetChannelDifference = 0x140, AddMessagePushNotification = 0x200, From 6f34c5c6a198253840f25e711d34945847aa1db1 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 16:52:22 +0300 Subject: [PATCH 45/82] Make PhotoSizeSource constructors named. --- td/telegram/DocumentsManager.cpp | 11 ++-- td/telegram/MessageContent.cpp | 3 +- td/telegram/Photo.cpp | 39 +++++++------ td/telegram/PhotoSizeSource.cpp | 2 +- td/telegram/PhotoSizeSource.h | 91 +++++++++++++++++------------- td/telegram/PhotoSizeSource.hpp | 4 +- td/telegram/StickersManager.cpp | 14 +++-- td/telegram/files/FileLocation.h | 4 +- td/telegram/files/FileLocation.hpp | 11 ++-- 9 files changed, 99 insertions(+), 80 deletions(-) diff --git a/td/telegram/DocumentsManager.cpp b/td/telegram/DocumentsManager.cpp index 9829f1e08..c40a210a3 100644 --- a/td/telegram/DocumentsManager.cpp +++ b/td/telegram/DocumentsManager.cpp @@ -270,9 +270,9 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo if (document_type != Document::Type::VoiceNote) { for (auto &thumb : document->thumbs_) { - auto photo_size = - get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, id, access_hash, file_reference, - DcId::create(dc_id), owner_dialog_id, std::move(thumb), thumbnail_format); + auto photo_size = get_photo_size(td_->file_manager_.get(), PhotoSizeSource::thumbnail(FileType::Thumbnail, 0), + id, access_hash, file_reference, DcId::create(dc_id), owner_dialog_id, + std::move(thumb), thumbnail_format); if (photo_size.get_offset() == 0) { if (!thumbnail.file_id.is_valid()) { thumbnail = std::move(photo_size.get<0>()); @@ -284,8 +284,9 @@ Document DocumentsManager::on_get_document(RemoteDocument remote_document, Dialo } for (auto &thumb : document->video_thumbs_) { if (thumb->type_ == "v") { - animated_thumbnail = get_animation_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, id, access_hash, - file_reference, DcId::create(dc_id), owner_dialog_id, std::move(thumb)); + animated_thumbnail = + get_animation_size(td_->file_manager_.get(), PhotoSizeSource::thumbnail(FileType::Thumbnail, 0), id, + access_hash, file_reference, DcId::create(dc_id), owner_dialog_id, std::move(thumb)); if (animated_thumbnail.file_id.is_valid()) { break; } diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index dd4712ffd..0d38a6bd1 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -3159,7 +3159,8 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo old_file_view.main_remote_location().get_access_hash() != new_file_view.remote_location().get_access_hash()) { FileId file_id = td->file_manager_->register_remote( - FullRemoteFileLocation({FileType::Photo, 'i'}, new_file_view.remote_location().get_id(), + FullRemoteFileLocation(PhotoSizeSource::thumbnail(FileType::Photo, 'i'), + new_file_view.remote_location().get_id(), new_file_view.remote_location().get_access_hash(), DcId::invalid(), new_file_view.remote_location().get_file_reference().str()), FileLocationSource::FromServer, dialog_id, old_photo->photos.back().size, 0, ""); diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index 61cf18f0a..fc44bf0f7 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -162,12 +162,12 @@ ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64 result.has_animation = (profile_photo->flags_ & telegram_api::userProfilePhoto::HAS_VIDEO_MASK) != 0; result.id = profile_photo->photo_id_; result.minithumbnail = profile_photo->stripped_thumb_.as_slice().str(); - result.small_file_id = - register_photo(file_manager, {DialogId(user_id), user_access_hash, false}, result.id, 0 /*access_hash*/, - "" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id, PhotoFormat::Jpeg); - result.big_file_id = - register_photo(file_manager, {DialogId(user_id), user_access_hash, true}, result.id, 0 /*access_hash*/, - "" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id, PhotoFormat::Jpeg); + result.small_file_id = register_photo( + file_manager, PhotoSizeSource::dialog_photo(DialogId(user_id), user_access_hash, false), result.id, + 0 /*access_hash*/, "" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id, PhotoFormat::Jpeg); + result.big_file_id = register_photo( + file_manager, PhotoSizeSource::dialog_photo(DialogId(user_id), user_access_hash, true), result.id, + 0 /*access_hash*/, "" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id, PhotoFormat::Jpeg); break; } default: @@ -223,10 +223,12 @@ DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int6 auto dc_id = DcId::create(chat_photo->dc_id_); result.has_animation = (chat_photo->flags_ & telegram_api::chatPhoto::HAS_VIDEO_MASK) != 0; result.minithumbnail = chat_photo->stripped_thumb_.as_slice().str(); - result.small_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, false}, chat_photo->photo_id_, - 0, "", DialogId(), 0, dc_id, PhotoFormat::Jpeg); - result.big_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, true}, chat_photo->photo_id_, 0, - "", DialogId(), 0, dc_id, PhotoFormat::Jpeg); + result.small_file_id = + register_photo(file_manager, PhotoSizeSource::dialog_photo(dialog_id, dialog_access_hash, false), + chat_photo->photo_id_, 0, "", DialogId(), 0, dc_id, PhotoFormat::Jpeg); + result.big_file_id = + register_photo(file_manager, PhotoSizeSource::dialog_photo(dialog_id, dialog_access_hash, true), + chat_photo->photo_id_, 0, "", DialogId(), 0, dc_id, PhotoFormat::Jpeg); break; } @@ -293,7 +295,7 @@ ProfilePhoto as_profile_photo(FileManager *file_manager, UserId user_id, int64 u auto remote = file_view.remote_location(); CHECK(remote.is_photo()); CHECK(!remote.is_web()); - remote.set_source({DialogId(user_id), user_access_hash, is_big}); + remote.set_source(PhotoSizeSource::dialog_photo(DialogId(user_id), user_access_hash, is_big)); return file_manager->register_remote(std::move(remote), FileLocationSource::FromServer, DialogId(), file_view.size(), file_view.expected_size(), file_view.remote_name()); }; @@ -335,7 +337,8 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice auto photo_id = -(Random::secure_int64() & std::numeric_limits::max()); res.file_id = file_manager->register_remote( - FullRemoteFileLocation(PhotoSizeSource(FileType::EncryptedThumbnail, 't'), photo_id, 0, dc_id, string()), + FullRemoteFileLocation(PhotoSizeSource::thumbnail(FileType::EncryptedThumbnail, 't'), photo_id, 0, dc_id, + string()), FileLocationSource::FromServer, owner_dialog_id, res.size, 0, PSTRING() << static_cast(photo_id) << ".jpg"); file_manager->set_content(res.file_id, std::move(bytes)); @@ -708,9 +711,9 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && DcId dc_id = DcId::create(photo->dc_id_); for (auto &size_ptr : photo->sizes_) { - auto photo_size = get_photo_size(file_manager, {FileType::Photo, 0}, photo->id_, photo->access_hash_, - photo->file_reference_.as_slice().str(), dc_id, owner_dialog_id, - std::move(size_ptr), PhotoFormat::Jpeg); + auto photo_size = get_photo_size(file_manager, PhotoSizeSource::thumbnail(FileType::Photo, 0), photo->id_, + photo->access_hash_, photo->file_reference_.as_slice().str(), dc_id, + owner_dialog_id, std::move(size_ptr), PhotoFormat::Jpeg); if (photo_size.get_offset() == 0) { PhotoSize &size = photo_size.get<0>(); if (size.type == 0 || size.type == 't' || size.type == 'i' || size.type == 'u' || size.type == 'v') { @@ -724,9 +727,9 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && } for (auto &size_ptr : photo->video_sizes_) { - auto animation = - get_animation_size(file_manager, {FileType::Photo, 0}, photo->id_, photo->access_hash_, - photo->file_reference_.as_slice().str(), dc_id, owner_dialog_id, std::move(size_ptr)); + auto animation = get_animation_size(file_manager, PhotoSizeSource::thumbnail(FileType::Photo, 0), photo->id_, + photo->access_hash_, photo->file_reference_.as_slice().str(), dc_id, + owner_dialog_id, std::move(size_ptr)); if (animation.type != 0 && animation.dimensions.width == animation.dimensions.height) { res.animations.push_back(std::move(animation)); } diff --git a/td/telegram/PhotoSizeSource.cpp b/td/telegram/PhotoSizeSource.cpp index a3923a2fe..e7b57908d 100644 --- a/td/telegram/PhotoSizeSource.cpp +++ b/td/telegram/PhotoSizeSource.cpp @@ -218,7 +218,7 @@ static bool operator==(const PhotoSizeSource::StickerSetThumbnailVersion &lhs, } bool operator==(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs) { - return lhs.variant == rhs.variant; + return lhs.variant_ == rhs.variant_; } bool operator!=(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs) { diff --git a/td/telegram/PhotoSizeSource.h b/td/telegram/PhotoSizeSource.h index c67f5c69e..731f5ae85 100644 --- a/td/telegram/PhotoSizeSource.h +++ b/td/telegram/PhotoSizeSource.h @@ -8,15 +8,12 @@ #include "td/telegram/DialogId.h" #include "td/telegram/files/FileType.h" - #include "td/telegram/telegram_api.h" #include "td/utils/common.h" #include "td/utils/StringBuilder.h" #include "td/utils/Variant.h" -#include - namespace td { struct PhotoSizeSource { @@ -141,37 +138,47 @@ struct PhotoSizeSource { }; PhotoSizeSource() = default; - PhotoSizeSource(FileType file_type, int32 thumbnail_type) : variant(Thumbnail(file_type, thumbnail_type)) { + + static PhotoSizeSource thumbnail(FileType file_type, int32 thumbnail_type) { + return PhotoSizeSource(Thumbnail(file_type, thumbnail_type)); } - PhotoSizeSource(DialogId dialog_id, int64 dialog_access_hash, bool is_big) { + + static PhotoSizeSource dialog_photo(DialogId dialog_id, int64 dialog_access_hash, bool is_big) { if (is_big) { - variant = DialogPhotoBig(dialog_id, dialog_access_hash); + return PhotoSizeSource(DialogPhotoBig(dialog_id, dialog_access_hash)); } else { - variant = DialogPhotoSmall(dialog_id, dialog_access_hash); + return PhotoSizeSource(DialogPhotoSmall(dialog_id, dialog_access_hash)); } } - PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash) - : variant(StickerSetThumbnail(sticker_set_id, sticker_set_access_hash)) { + + static PhotoSizeSource sticker_set_thumbnail(int64 sticker_set_id, int64 sticker_set_access_hash) { + return PhotoSizeSource(StickerSetThumbnail(sticker_set_id, sticker_set_access_hash)); } - PhotoSizeSource(std::nullptr_t, int64 volume_id, int32 local_id, int64 secret) - : variant(FullLegacy(volume_id, local_id, secret)) { + + static PhotoSizeSource full_legacy(int64 volume_id, int32 local_id, int64 secret) { + return PhotoSizeSource(FullLegacy(volume_id, local_id, secret)); } - PhotoSizeSource(DialogId dialog_id, int64 dialog_access_hash, bool is_big, int64 volume_id, int32 local_id) { + + static PhotoSizeSource dialog_photo_legacy(DialogId dialog_id, int64 dialog_access_hash, bool is_big, int64 volume_id, + int32 local_id) { if (is_big) { - variant = DialogPhotoBigLegacy(dialog_id, dialog_access_hash, volume_id, local_id); + return PhotoSizeSource(DialogPhotoBigLegacy(dialog_id, dialog_access_hash, volume_id, local_id)); } else { - variant = DialogPhotoSmallLegacy(dialog_id, dialog_access_hash, volume_id, local_id); + return PhotoSizeSource(DialogPhotoSmallLegacy(dialog_id, dialog_access_hash, volume_id, local_id)); } } - PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash, int64 volume_id, int32 local_id) - : variant(StickerSetThumbnailLegacy(sticker_set_id, sticker_set_access_hash, volume_id, local_id)) { + + static PhotoSizeSource sticker_set_thumbnail_legacy(int64 sticker_set_id, int64 sticker_set_access_hash, + int64 volume_id, int32 local_id) { + return PhotoSizeSource(StickerSetThumbnailLegacy(sticker_set_id, sticker_set_access_hash, volume_id, local_id)); } - PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash, int32 version) - : variant(StickerSetThumbnailVersion(sticker_set_id, sticker_set_access_hash, version)) { + + static PhotoSizeSource sticker_set_thumbnail(int64 sticker_set_id, int64 sticker_set_access_hash, int32 version) { + return PhotoSizeSource(StickerSetThumbnailVersion(sticker_set_id, sticker_set_access_hash, version)); } Type get_type() const { - auto offset = variant.get_offset(); + auto offset = variant_.get_offset(); CHECK(offset >= 0); return static_cast(offset); } @@ -179,58 +186,58 @@ struct PhotoSizeSource { FileType get_file_type() const; Thumbnail &thumbnail() { - return variant.get(); + return variant_.get(); } const Legacy &legacy() const { - return variant.get(); + return variant_.get(); } const Thumbnail &thumbnail() const { - return variant.get(); + return variant_.get(); } const DialogPhoto &dialog_photo() const { - switch (variant.get_offset()) { + switch (variant_.get_offset()) { case 2: - return variant.get(); + return variant_.get(); case 3: - return variant.get(); + return variant_.get(); case 6: - return variant.get(); + return variant_.get(); case 7: - return variant.get(); + return variant_.get(); default: UNREACHABLE(); - return variant.get(); + return variant_.get(); } } const StickerSetThumbnail &sticker_set_thumbnail() const { - switch (variant.get_offset()) { + switch (variant_.get_offset()) { case 4: - return variant.get(); + return variant_.get(); case 8: - return variant.get(); + return variant_.get(); case 9: - return variant.get(); + return variant_.get(); default: UNREACHABLE(); - return variant.get(); + return variant_.get(); } } const FullLegacy &full_legacy() const { - return variant.get(); + return variant_.get(); } const DialogPhotoLegacy &dialog_photo_legacy() const { - if (variant.get_offset() == 6) { - return variant.get(); + if (variant_.get_offset() == 6) { + return variant_.get(); } else { - return variant.get(); + return variant_.get(); } } const StickerSetThumbnailLegacy &sticker_set_thumbnail_legacy() const { - return variant.get(); + return variant_.get(); } const StickerSetThumbnailVersion &sticker_set_thumbnail_version() const { - return variant.get(); + return variant_.get(); } // returns unique representation of the source @@ -249,7 +256,11 @@ struct PhotoSizeSource { private: Variant - variant; + variant_; + + template + explicit PhotoSizeSource(const T &variant) : variant_(variant) { + } }; bool operator==(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs); diff --git a/td/telegram/PhotoSizeSource.hpp b/td/telegram/PhotoSizeSource.hpp index 838a70439..c1ce48207 100644 --- a/td/telegram/PhotoSizeSource.hpp +++ b/td/telegram/PhotoSizeSource.hpp @@ -180,12 +180,12 @@ void parse(PhotoSizeSource::StickerSetThumbnailVersion &source, ParserT &parser) template void PhotoSizeSource::store(StorerT &storer) const { - td::store(variant, storer); + td::store(variant_, storer); } template void PhotoSizeSource::parse(ParserT &parser) { - td::parse(variant, parser); + td::parse(variant_, parser); } } // namespace td diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 0fcab4dcb..cbf549213 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -2164,9 +2164,9 @@ std::pair StickersManager::on_get_sticker_document( string minithumbnail; auto thumbnail_format = has_webp_thumbnail(document->thumbs_) ? PhotoFormat::Webp : PhotoFormat::Jpeg; for (auto &thumb : document->thumbs_) { - auto photo_size = get_photo_size(td_->file_manager_.get(), {FileType::Thumbnail, 0}, document_id, - document->access_hash_, document->file_reference_.as_slice().str(), dc_id, - DialogId(), std::move(thumb), thumbnail_format); + auto photo_size = get_photo_size(td_->file_manager_.get(), PhotoSizeSource::thumbnail(FileType::Thumbnail, 0), + document_id, document->access_hash_, document->file_reference_.as_slice().str(), + dc_id, DialogId(), std::move(thumb), thumbnail_format); if (photo_size.get_offset() == 0) { if (!thumbnail.file_id.is_valid()) { thumbnail = std::move(photo_size.get<0>()); @@ -2698,9 +2698,11 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrthumbs_) { - auto photo_size = get_photo_size(td_->file_manager_.get(), {set_id.get(), s->access_hash, set->thumb_version_}, 0, - 0, "", DcId::create(set->thumb_dc_id_), DialogId(), std::move(thumb), - is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp); + auto photo_size = + get_photo_size(td_->file_manager_.get(), + PhotoSizeSource::sticker_set_thumbnail(set_id.get(), s->access_hash, set->thumb_version_), 0, 0, + "", DcId::create(set->thumb_dc_id_), DialogId(), std::move(thumb), + is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp); if (photo_size.get_offset() == 0) { if (!thumbnail.file_id.is_valid()) { thumbnail = std::move(photo_size.get<0>()); diff --git a/td/telegram/files/FileLocation.h b/td/telegram/files/FileLocation.h index 03f44129a..b3fdd6737 100644 --- a/td/telegram/files/FileLocation.h +++ b/td/telegram/files/FileLocation.h @@ -325,11 +325,11 @@ class FullRemoteFileLocation { return photo().source_; case LocationType::Common: case LocationType::Web: - return PhotoSizeSource(nullptr, 0, 0, 0); + return PhotoSizeSource::full_legacy(0, 0, 0); case LocationType::None: default: UNREACHABLE(); - return PhotoSizeSource(nullptr, 0, 0, 0); + return PhotoSizeSource::full_legacy(0, 0, 0); } } diff --git a/td/telegram/files/FileLocation.hpp b/td/telegram/files/FileLocation.hpp index 0c5c10cbf..06e5f72eb 100644 --- a/td/telegram/files/FileLocation.hpp +++ b/td/telegram/files/FileLocation.hpp @@ -66,7 +66,7 @@ void PhotoRemoteFileLocation::parse(ParserT &parser) { int64 secret; parse(secret, parser); parse(local_id, parser); - source = PhotoSizeSource(nullptr, volume_id, local_id, secret); + source = PhotoSizeSource::full_legacy(volume_id, local_id, secret); } if (parser.get_error() != nullptr) { @@ -75,7 +75,7 @@ void PhotoRemoteFileLocation::parse(ParserT &parser) { switch (source.get_type()) { case PhotoSizeSource::Type::Legacy: - source_ = PhotoSizeSource(nullptr, volume_id, local_id, source.legacy().secret); + source_ = PhotoSizeSource::full_legacy(volume_id, local_id, source.legacy().secret); break; case PhotoSizeSource::Type::FullLegacy: case PhotoSizeSource::Type::Thumbnail: @@ -85,13 +85,14 @@ void PhotoRemoteFileLocation::parse(ParserT &parser) { case PhotoSizeSource::Type::DialogPhotoBig: { auto &dialog_photo = source.dialog_photo(); bool is_big = source.get_type() == PhotoSizeSource::Type::DialogPhotoBig; - source_ = PhotoSizeSource(dialog_photo.dialog_id, dialog_photo.dialog_access_hash, is_big, volume_id, local_id); + source_ = PhotoSizeSource::dialog_photo_legacy(dialog_photo.dialog_id, dialog_photo.dialog_access_hash, is_big, + volume_id, local_id); break; } case PhotoSizeSource::Type::StickerSetThumbnail: { auto &sticker_set_thumbnail = source.sticker_set_thumbnail(); - source_ = PhotoSizeSource(sticker_set_thumbnail.sticker_set_id, sticker_set_thumbnail.sticker_set_access_hash, - volume_id, local_id); + source_ = PhotoSizeSource::sticker_set_thumbnail_legacy( + sticker_set_thumbnail.sticker_set_id, sticker_set_thumbnail.sticker_set_access_hash, volume_id, local_id); break; } default: From 00a349656d04672a5592439e4cc82c8227aa3e25 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 27 Oct 2021 17:32:09 +0300 Subject: [PATCH 46/82] Unify td/telegram/include order. --- td/telegram/AudiosManager.cpp | 2 -- td/telegram/AudiosManager.h | 5 ++--- td/telegram/AuthManager.cpp | 3 --- td/telegram/AuthManager.hpp | 1 + td/telegram/BackgroundManager.cpp | 3 --- td/telegram/CallActor.cpp | 5 +---- td/telegram/CallManager.h | 1 - td/telegram/CallbackQueriesManager.h | 5 ++--- td/telegram/ClientActor.cpp | 2 -- td/telegram/ConfigManager.h | 1 - td/telegram/DialogId.h | 3 +-- td/telegram/DocumentsManager.h | 7 +++---- td/telegram/Game.cpp | 3 --- td/telegram/InlineQueriesManager.cpp | 10 +++------- td/telegram/LanguagePackManager.cpp | 4 ---- td/telegram/LanguagePackManager.h | 1 - td/telegram/Location.h | 3 +-- td/telegram/Log.cpp | 1 - td/telegram/MessagesManager.h | 5 ++--- td/telegram/PrivacyManager.cpp | 3 --- td/telegram/SecretChatActor.cpp | 6 ++---- td/telegram/SecureManager.h | 3 +-- td/telegram/SecureValue.cpp | 3 --- td/telegram/SecureValue.h | 5 ++--- td/telegram/TermsOfService.h | 5 ++--- td/telegram/UpdatesManager.cpp | 5 ++--- td/telegram/VideoNotesManager.h | 5 ++--- td/telegram/VideosManager.h | 5 ++--- td/telegram/VoiceNotesManager.h | 5 ++--- td/telegram/WebPagesManager.cpp | 3 +-- td/telegram/WebPagesManager.h | 5 ++--- td/telegram/files/FileDownloader.cpp | 2 -- td/telegram/files/FileDownloader.h | 3 +-- td/telegram/files/FileGenerateManager.cpp | 5 ++--- td/telegram/files/FileHashUploader.cpp | 3 +-- td/telegram/files/FileLocation.h | 3 +-- td/telegram/files/FileManager.cpp | 2 -- td/telegram/files/FileManager.h | 5 ++--- td/telegram/files/FileStats.cpp | 3 +-- td/telegram/files/FileUploader.cpp | 4 +--- td/telegram/net/ConnectionCreator.h | 3 +-- td/telegram/net/PublicRsaKeyWatchdog.h | 4 +--- td/telegram/net/Session.cpp | 3 +-- td/telegram/td_c_client.cpp | 1 - 44 files changed, 46 insertions(+), 113 deletions(-) diff --git a/td/telegram/AudiosManager.cpp b/td/telegram/AudiosManager.cpp index b9f13cee0..68b57098a 100644 --- a/td/telegram/AudiosManager.cpp +++ b/td/telegram/AudiosManager.cpp @@ -10,8 +10,6 @@ #include "td/telegram/files/FileManager.h" #include "td/telegram/secret_api.h" #include "td/telegram/Td.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" #include "td/utils/logging.h" #include "td/utils/misc.h" diff --git a/td/telegram/AudiosManager.h b/td/telegram/AudiosManager.h index 84c34fa06..752132840 100644 --- a/td/telegram/AudiosManager.h +++ b/td/telegram/AudiosManager.h @@ -6,12 +6,11 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileId.h" #include "td/telegram/Photo.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/buffer.h" #include "td/utils/common.h" diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index e2a6f39e1..77b1ca269 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/AuthManager.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/AuthManager.hpp" #include "td/telegram/ConfigManager.h" #include "td/telegram/ConfigShared.h" diff --git a/td/telegram/AuthManager.hpp b/td/telegram/AuthManager.hpp index cf0afc8f8..a531e68c5 100644 --- a/td/telegram/AuthManager.hpp +++ b/td/telegram/AuthManager.hpp @@ -7,6 +7,7 @@ #pragma once #include "td/telegram/AuthManager.h" + #include "td/telegram/logevent/LogEventHelper.h" #include "td/telegram/SendCodeHelper.hpp" #include "td/telegram/Version.h" diff --git a/td/telegram/BackgroundManager.cpp b/td/telegram/BackgroundManager.cpp index 1d1bf447a..b5e87c3a4 100644 --- a/td/telegram/BackgroundManager.cpp +++ b/td/telegram/BackgroundManager.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/BackgroundManager.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/AuthManager.h" #include "td/telegram/BackgroundType.hpp" #include "td/telegram/ConfigShared.h" diff --git a/td/telegram/CallActor.cpp b/td/telegram/CallActor.cpp index 225ac6605..d7e82d1a4 100644 --- a/td/telegram/CallActor.cpp +++ b/td/telegram/CallActor.cpp @@ -6,10 +6,6 @@ // #include "td/telegram/CallActor.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" -#include "td/telegram/telegram_api.hpp" - #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/DhCache.h" @@ -20,6 +16,7 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/NotificationManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.hpp" #include "td/telegram/UpdatesManager.h" #include "td/utils/algorithm.h" diff --git a/td/telegram/CallManager.h b/td/telegram/CallManager.h index 85fb3f6b2..46b1a38bd 100644 --- a/td/telegram/CallManager.h +++ b/td/telegram/CallManager.h @@ -8,7 +8,6 @@ #include "td/telegram/CallActor.h" #include "td/telegram/CallId.h" - #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" diff --git a/td/telegram/CallbackQueriesManager.h b/td/telegram/CallbackQueriesManager.h index 77a220883..6400b2070 100644 --- a/td/telegram/CallbackQueriesManager.h +++ b/td/telegram/CallbackQueriesManager.h @@ -6,12 +6,11 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/DialogId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" #include "td/actor/PromiseFuture.h" diff --git a/td/telegram/ClientActor.cpp b/td/telegram/ClientActor.cpp index a1b4a8d91..74740549d 100644 --- a/td/telegram/ClientActor.cpp +++ b/td/telegram/ClientActor.cpp @@ -6,8 +6,6 @@ // #include "td/telegram/ClientActor.h" -#include "td/telegram/td_api.h" - #include "td/telegram/net/NetQueryCounter.h" #include "td/telegram/net/NetQueryStats.h" #include "td/telegram/Td.h" diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index 6e868d415..ac4de3823 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -10,7 +10,6 @@ #include "td/telegram/net/DcOptions.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/SuggestedAction.h" - #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" diff --git a/td/telegram/DialogId.h b/td/telegram/DialogId.h index 64f3cbfc5..afd593d08 100644 --- a/td/telegram/DialogId.h +++ b/td/telegram/DialogId.h @@ -6,11 +6,10 @@ // #pragma once -#include "td/telegram/telegram_api.h" - #include "td/telegram/ChannelId.h" #include "td/telegram/ChatId.h" #include "td/telegram/SecretChatId.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" #include "td/utils/common.h" diff --git a/td/telegram/DocumentsManager.h b/td/telegram/DocumentsManager.h index 0b4ac96e1..7dfa01af7 100644 --- a/td/telegram/DocumentsManager.h +++ b/td/telegram/DocumentsManager.h @@ -6,16 +6,15 @@ // #pragma once -#include "td/telegram/secret_api.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #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/secret_api.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/buffer.h" #include "td/utils/common.h" diff --git a/td/telegram/Game.cpp b/td/telegram/Game.cpp index ca3ce7469..84cff59c6 100644 --- a/td/telegram/Game.cpp +++ b/td/telegram/Game.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/Game.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/AnimationsManager.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Document.h" diff --git a/td/telegram/InlineQueriesManager.cpp b/td/telegram/InlineQueriesManager.cpp index f615bdc4e..905f2abcc 100644 --- a/td/telegram/InlineQueriesManager.cpp +++ b/td/telegram/InlineQueriesManager.cpp @@ -6,11 +6,6 @@ // #include "td/telegram/InlineQueriesManager.h" -#include "td/telegram/td_api.h" -#include "td/telegram/td_api.hpp" -#include "td/telegram/telegram_api.h" -#include "td/telegram/telegram_api.hpp" - #include "td/telegram/AccessRights.h" #include "td/telegram/AnimationsManager.h" #include "td/telegram/AudiosManager.h" @@ -30,19 +25,20 @@ #include "td/telegram/MessageEntity.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" +#include "td/telegram/net/DcId.h" #include "td/telegram/Payments.h" #include "td/telegram/Photo.h" #include "td/telegram/ReplyMarkup.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" +#include "td/telegram/td_api.hpp" #include "td/telegram/TdDb.h" #include "td/telegram/TdParameters.h" +#include "td/telegram/telegram_api.hpp" #include "td/telegram/Venue.h" #include "td/telegram/VideosManager.h" #include "td/telegram/VoiceNotesManager.h" -#include "td/telegram/net/DcId.h" - #include "td/utils/algorithm.h" #include "td/utils/base64.h" #include "td/utils/buffer.h" diff --git a/td/telegram/LanguagePackManager.cpp b/td/telegram/LanguagePackManager.cpp index 32d3a66be..6c1ccdcad 100644 --- a/td/telegram/LanguagePackManager.cpp +++ b/td/telegram/LanguagePackManager.cpp @@ -12,11 +12,7 @@ #include "td/telegram/misc.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" - -#include "td/telegram/misc.h" -#include "td/telegram/td_api.h" #include "td/telegram/td_api.hpp" -#include "td/telegram/telegram_api.h" #include "td/db/DbKey.h" #include "td/db/SqliteDb.h" diff --git a/td/telegram/LanguagePackManager.h b/td/telegram/LanguagePackManager.h index 9fb45e49d..a6ca0927d 100644 --- a/td/telegram/LanguagePackManager.h +++ b/td/telegram/LanguagePackManager.h @@ -7,7 +7,6 @@ #pragma once #include "td/telegram/net/NetQuery.h" - #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" diff --git a/td/telegram/Location.h b/td/telegram/Location.h index 04432130b..6f27d7e68 100644 --- a/td/telegram/Location.h +++ b/td/telegram/Location.h @@ -7,9 +7,8 @@ #pragma once #include "td/telegram/Global.h" -#include "td/telegram/SecretInputMedia.h" - #include "td/telegram/secret_api.h" +#include "td/telegram/SecretInputMedia.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" diff --git a/td/telegram/Log.cpp b/td/telegram/Log.cpp index 884ca5661..366fec9de 100644 --- a/td/telegram/Log.cpp +++ b/td/telegram/Log.cpp @@ -8,7 +8,6 @@ #include "td/telegram/Client.h" #include "td/telegram/Logging.h" - #include "td/telegram/td_api.h" #include "td/utils/common.h" diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index c81f16405..3ce4089d7 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -48,14 +48,13 @@ #include "td/telegram/ReportReason.h" #include "td/telegram/RestrictionReason.h" #include "td/telegram/ScheduledServerMessageId.h" +#include "td/telegram/secret_api.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/ServerMessageId.h" -#include "td/telegram/UserId.h" - -#include "td/telegram/secret_api.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" diff --git a/td/telegram/PrivacyManager.cpp b/td/telegram/PrivacyManager.cpp index 60c426c15..6355fba9d 100644 --- a/td/telegram/PrivacyManager.cpp +++ b/td/telegram/PrivacyManager.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/PrivacyManager.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/ChannelId.h" #include "td/telegram/ChatId.h" #include "td/telegram/ContactsManager.h" diff --git a/td/telegram/SecretChatActor.cpp b/td/telegram/SecretChatActor.cpp index adc4d6058..3f89aab37 100644 --- a/td/telegram/SecretChatActor.cpp +++ b/td/telegram/SecretChatActor.cpp @@ -8,12 +8,10 @@ #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQueryCreator.h" -#include "td/telegram/SecretChatId.h" -#include "td/telegram/ServerMessageId.h" -#include "td/telegram/UniqueId.h" - #include "td/telegram/secret_api.hpp" +#include "td/telegram/ServerMessageId.h" #include "td/telegram/telegram_api.hpp" +#include "td/telegram/UniqueId.h" #include "td/mtproto/PacketInfo.h" #include "td/mtproto/PacketStorer.h" diff --git a/td/telegram/SecureManager.h b/td/telegram/SecureManager.h index b26766fd9..4919cfcec 100644 --- a/td/telegram/SecureManager.h +++ b/td/telegram/SecureManager.h @@ -9,10 +9,9 @@ #include "td/telegram/net/NetQuery.h" #include "td/telegram/SecureStorage.h" #include "td/telegram/SecureValue.h" -#include "td/telegram/UserId.h" - #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" #include "td/actor/actor.h" #include "td/actor/PromiseFuture.h" diff --git a/td/telegram/SecureValue.cpp b/td/telegram/SecureValue.cpp index ccc09867f..9cc8cc0b3 100644 --- a/td/telegram/SecureValue.cpp +++ b/td/telegram/SecureValue.cpp @@ -15,9 +15,6 @@ #include "td/telegram/misc.h" #include "td/telegram/net/DcId.h" #include "td/telegram/Payments.h" - -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.hpp" #include "td/utils/algorithm.h" diff --git a/td/telegram/SecureValue.h b/td/telegram/SecureValue.h index ba8b38861..e177609e6 100644 --- a/td/telegram/SecureValue.h +++ b/td/telegram/SecureValue.h @@ -6,11 +6,10 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileId.h" #include "td/telegram/SecureStorage.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/common.h" #include "td/utils/optional.h" diff --git a/td/telegram/TermsOfService.h b/td/telegram/TermsOfService.h index 344c57e0a..07dff58e2 100644 --- a/td/telegram/TermsOfService.h +++ b/td/telegram/TermsOfService.h @@ -6,11 +6,10 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/MessageEntity.h" #include "td/telegram/MessageEntity.hpp" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/actor/PromiseFuture.h" diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 31dbf68f0..f403ee835 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/UpdatesManager.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.hpp" - #include "td/telegram/AnimationsManager.h" #include "td/telegram/AuthManager.h" #include "td/telegram/CallbackQueriesManager.h" @@ -46,7 +43,9 @@ #include "td/telegram/StickerSetId.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" +#include "td/telegram/td_api.h" #include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.hpp" #include "td/telegram/ThemeManager.h" #include "td/telegram/WebPagesManager.h" diff --git a/td/telegram/VideoNotesManager.h b/td/telegram/VideoNotesManager.h index 5e1356e29..82bd2dac5 100644 --- a/td/telegram/VideoNotesManager.h +++ b/td/telegram/VideoNotesManager.h @@ -6,12 +6,11 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileId.h" #include "td/telegram/Photo.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/buffer.h" #include "td/utils/common.h" diff --git a/td/telegram/VideosManager.h b/td/telegram/VideosManager.h index b47c20d6f..5476dd3e8 100644 --- a/td/telegram/VideosManager.h +++ b/td/telegram/VideosManager.h @@ -6,12 +6,11 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileId.h" #include "td/telegram/Photo.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/buffer.h" #include "td/utils/common.h" diff --git a/td/telegram/VoiceNotesManager.h b/td/telegram/VoiceNotesManager.h index 21a920d33..0e54999d4 100644 --- a/td/telegram/VoiceNotesManager.h +++ b/td/telegram/VoiceNotesManager.h @@ -6,11 +6,10 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileId.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/common.h" diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index 90c8c453d..74ff295f4 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -6,8 +6,6 @@ // #include "td/telegram/WebPagesManager.h" -#include "td/telegram/secret_api.h" - #include "td/telegram/AnimationsManager.h" #include "td/telegram/AudiosManager.h" #include "td/telegram/AuthManager.h" @@ -23,6 +21,7 @@ #include "td/telegram/MessageEntity.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/Photo.h" +#include "td/telegram/secret_api.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" diff --git a/td/telegram/WebPagesManager.h b/td/telegram/WebPagesManager.h index bcfaea52f..0a1a8c902 100644 --- a/td/telegram/WebPagesManager.h +++ b/td/telegram/WebPagesManager.h @@ -6,14 +6,13 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/DialogId.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/SecretInputMedia.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/WebPageId.h" #include "td/actor/actor.h" diff --git a/td/telegram/files/FileDownloader.cpp b/td/telegram/files/FileDownloader.cpp index 41e8ee766..ea0622056 100644 --- a/td/telegram/files/FileDownloader.cpp +++ b/td/telegram/files/FileDownloader.cpp @@ -6,8 +6,6 @@ // #include "td/telegram/files/FileDownloader.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/FileReferenceManager.h" #include "td/telegram/files/FileLoaderUtils.h" #include "td/telegram/files/FileType.h" diff --git a/td/telegram/files/FileDownloader.h b/td/telegram/files/FileDownloader.h index cb3f215e3..a38706ba0 100644 --- a/td/telegram/files/FileDownloader.h +++ b/td/telegram/files/FileDownloader.h @@ -6,13 +6,12 @@ // #pragma once -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileEncryptionKey.h" #include "td/telegram/files/FileLoader.h" #include "td/telegram/files/FileLocation.h" #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQuery.h" +#include "td/telegram/telegram_api.h" #include "td/utils/common.h" #include "td/utils/port/FileFd.h" diff --git a/td/telegram/files/FileGenerateManager.cpp b/td/telegram/files/FileGenerateManager.cpp index 9845f0706..2d11c86a6 100644 --- a/td/telegram/files/FileGenerateManager.cpp +++ b/td/telegram/files/FileGenerateManager.cpp @@ -6,9 +6,6 @@ // #include "td/telegram/files/FileGenerateManager.h" -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileLoaderUtils.h" #include "td/telegram/files/FileManager.h" @@ -17,6 +14,8 @@ #include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/common.h" #include "td/utils/format.h" diff --git a/td/telegram/files/FileHashUploader.cpp b/td/telegram/files/FileHashUploader.cpp index 797f12160..86cdf3d98 100644 --- a/td/telegram/files/FileHashUploader.cpp +++ b/td/telegram/files/FileHashUploader.cpp @@ -6,12 +6,11 @@ // #include "td/telegram/files/FileHashUploader.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileType.h" #include "td/telegram/Global.h" #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/telegram_api.h" #include "td/utils/buffer.h" #include "td/utils/common.h" diff --git a/td/telegram/files/FileLocation.h b/td/telegram/files/FileLocation.h index b3fdd6737..9e4b9436f 100644 --- a/td/telegram/files/FileLocation.h +++ b/td/telegram/files/FileLocation.h @@ -6,12 +6,11 @@ // #pragma once -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileBitmask.h" #include "td/telegram/files/FileType.h" #include "td/telegram/net/DcId.h" #include "td/telegram/PhotoSizeSource.h" +#include "td/telegram/telegram_api.h" #include "td/utils/base64.h" #include "td/utils/buffer.h" diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index a2c461f99..bde54aa4d 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -6,8 +6,6 @@ // #include "td/telegram/files/FileManager.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/ConfigShared.h" #include "td/telegram/FileReferenceManager.h" #include "td/telegram/files/FileData.h" diff --git a/td/telegram/files/FileManager.h b/td/telegram/files/FileManager.h index 752ed7700..a7d4e925b 100644 --- a/td/telegram/files/FileManager.h +++ b/td/telegram/files/FileManager.h @@ -6,9 +6,6 @@ // #pragma once -#include "td/telegram/td_api.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/DialogId.h" #include "td/telegram/files/FileDbId.h" #include "td/telegram/files/FileEncryptionKey.h" @@ -20,6 +17,8 @@ #include "td/telegram/files/FileType.h" #include "td/telegram/Location.h" #include "td/telegram/PhotoSizeSource.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/actor/actor.h" #include "td/actor/PromiseFuture.h" diff --git a/td/telegram/files/FileStats.cpp b/td/telegram/files/FileStats.cpp index 52b9d4bf7..9bdc512bc 100644 --- a/td/telegram/files/FileStats.cpp +++ b/td/telegram/files/FileStats.cpp @@ -6,9 +6,8 @@ // #include "td/telegram/files/FileStats.h" -#include "td/telegram/td_api.h" - #include "td/telegram/files/FileLoaderUtils.h" +#include "td/telegram/td_api.h" #include "td/utils/algorithm.h" #include "td/utils/common.h" diff --git a/td/telegram/files/FileUploader.cpp b/td/telegram/files/FileUploader.cpp index e7429cb54..7899011f9 100644 --- a/td/telegram/files/FileUploader.cpp +++ b/td/telegram/files/FileUploader.cpp @@ -6,14 +6,12 @@ // #include "td/telegram/files/FileUploader.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/files/FileLoaderUtils.h" - #include "td/telegram/Global.h" #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/SecureStorage.h" +#include "td/telegram/telegram_api.h" #include "td/utils/buffer.h" #include "td/utils/common.h" diff --git a/td/telegram/net/ConnectionCreator.h b/td/telegram/net/ConnectionCreator.h index ba6934ebe..520c0708a 100644 --- a/td/telegram/net/ConnectionCreator.h +++ b/td/telegram/net/ConnectionCreator.h @@ -6,13 +6,12 @@ // #pragma once -#include "td/telegram/td_api.h" - #include "td/telegram/net/DcId.h" #include "td/telegram/net/DcOptions.h" #include "td/telegram/net/DcOptionsSet.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/net/Proxy.h" +#include "td/telegram/td_api.h" #include "td/mtproto/AuthData.h" #include "td/mtproto/ConnectionManager.h" diff --git a/td/telegram/net/PublicRsaKeyWatchdog.h b/td/telegram/net/PublicRsaKeyWatchdog.h index 73e4e9f14..b74022e76 100644 --- a/td/telegram/net/PublicRsaKeyWatchdog.h +++ b/td/telegram/net/PublicRsaKeyWatchdog.h @@ -6,12 +6,10 @@ // #pragma once -#include "td/telegram/net/PublicRsaKeyShared.h" - #include "td/telegram/net/NetActor.h" #include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/net/NetQueryDispatcher.h" - +#include "td/telegram/net/PublicRsaKeyShared.h" #include "td/telegram/telegram_api.h" #include "td/actor/actor.h" diff --git a/td/telegram/net/Session.cpp b/td/telegram/net/Session.cpp index c7289d869..979d39468 100644 --- a/td/telegram/net/Session.cpp +++ b/td/telegram/net/Session.cpp @@ -6,8 +6,6 @@ // #include "td/telegram/net/Session.h" -#include "td/telegram/telegram_api.h" - #include "td/telegram/ConfigShared.h" #include "td/telegram/DhCache.h" #include "td/telegram/Global.h" @@ -18,6 +16,7 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/net/NetType.h" #include "td/telegram/StateManager.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UniqueId.h" #include "td/mtproto/DhCallback.h" diff --git a/td/telegram/td_c_client.cpp b/td/telegram/td_c_client.cpp index a2670dc3f..05116778a 100644 --- a/td/telegram/td_c_client.cpp +++ b/td/telegram/td_c_client.cpp @@ -8,7 +8,6 @@ #include "td/telegram/Client.h" #include "td/telegram/Log.h" - #include "td/telegram/td_tdc_api_inner.h" #include From 81bfbecb186307383ebe3e443e4c9ee4623915a7 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 28 Oct 2021 21:46:34 +0300 Subject: [PATCH 47/82] Add internalLinkTypeUnsupportedProxy. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/LinkManager.cpp | 14 +++++++++++ td/telegram/LinkManager.h | 1 + td/telegram/cli.cpp | 3 ++- test/link.cpp | 46 ++++++++++++++++++++---------------- 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2d93c1e82..1a4cc674f 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3216,6 +3216,9 @@ internalLinkTypeThemeSettings = InternalLinkType; //@description The link is an unknown tg: link. Call getDeepLinkInfo to process the link @link Link to be passed to getDeepLinkInfo internalLinkTypeUnknownDeepLink link:string = InternalLinkType; +//@description The link is a link to an unsupported proxy. An alert can be shown to the user +internalLinkTypeUnsupportedProxy = InternalLinkType; + //@description The link is a link to a video chat. Call searchPublicChat with the given chat username, and then joinGoupCall with the given invite hash to process the link //@chat_username Username of the chat with the video chat @invite_hash If non-empty, invite hash to be used to join the video chat without being muted by administrators //@is_live_stream True, if the video chat is expected to be a live stream in a channel or a broadcast group diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 711d20a6e..f2dc217c5 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -354,6 +354,12 @@ class LinkManager::InternalLinkUnknownDeepLink final : public InternalLink { } }; +class LinkManager::InternalLinkUnsupportedProxy final : public InternalLink { + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(); + } +}; + class LinkManager::InternalLinkVoiceChat final : public InternalLink { string dialog_username_; string invite_hash_; @@ -863,6 +869,8 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que if (0 < port && port < 65536) { return td::make_unique( get_arg("server"), port, td_api::make_object(get_arg("user"), get_arg("pass"))); + } else { + return td::make_unique(); } } } else if (path.size() == 1 && path[0] == "proxy") { @@ -872,6 +880,8 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que if (0 < port && port < 65536 && mtproto::ProxySecret::from_link(get_arg("secret")).is_ok()) { return td::make_unique(get_arg("server"), port, td_api::make_object(get_arg("secret"))); + } else { + return td::make_unique(); } } } else if (path.size() == 1 && path[0] == "privatepost") { @@ -982,6 +992,8 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q if (0 < port && port < 65536) { return td::make_unique( get_arg("server"), port, td_api::make_object(get_arg("user"), get_arg("pass"))); + } else { + return td::make_unique(); } } } else if (path[0] == "proxy") { @@ -991,6 +1003,8 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q if (0 < port && port < 65536 && mtproto::ProxySecret::from_link(get_arg("secret")).is_ok()) { return td::make_unique(get_arg("server"), port, td_api::make_object(get_arg("secret"))); + } else { + return td::make_unique(); } } } else if (path[0] == "bg") { diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index 9790340c3..e55c7e57f 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -98,6 +98,7 @@ class LinkManager final : public Actor { class InternalLinkTheme; class InternalLinkThemeSettings; class InternalLinkUnknownDeepLink; + class InternalLinkUnsupportedProxy; class InternalLinkVoiceChat; struct LinkInfo { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 6e2db512c..b4fc390b3 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3364,7 +3364,8 @@ class CliClient final : public Actor { string bot_id; string query; get_args(args, bot_id, query); - send_request(td_api::make_object(as_user_id(bot_id), 0, nullptr, query, "")); + send_request(td_api::make_object(as_user_id(bot_id), as_chat_id(bot_id), nullptr, + query, "")); } else if (op == "giqro") { string bot_id; string offset; diff --git a/test/link.cpp b/test/link.cpp index 86c9afd1a..52d0f6533 100644 --- a/test/link.cpp +++ b/test/link.cpp @@ -171,6 +171,9 @@ TEST(Link, parse_internal_link) { auto unknown_deep_link = [](const td::string &link) { return td::td_api::make_object(link); }; + auto unsupported_proxy = [] { + return td::td_api::make_object(); + }; auto video_chat = [](const td::string &chat_username, const td::string &invite_hash, bool is_live_stream) { return td::td_api::make_object(chat_username, invite_hash, is_live_stream); }; @@ -468,17 +471,22 @@ TEST(Link, parse_internal_link) { proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); parse_internal_link("t.me/proxy?server=1.2.3.4&port=80adasdas&secret=1234567890abcdef1234567890ABCDEF", proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); - parse_internal_link("t.me/proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF", nullptr); - parse_internal_link("t.me/proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF", nullptr); - parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=", nullptr); - parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=12", nullptr); + parse_internal_link("t.me/proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); + parse_internal_link("t.me/proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); + parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=", unsupported_proxy()); + parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=12", unsupported_proxy()); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=1234567890abcdef1234567890ABCDEF", proxy_mtproto("google.com", 80, "1234567890abcdef1234567890ABCDEF")); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=dd1234567890abcdef1234567890ABCDEF", proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890ABCDEF")); - parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF", nullptr); - parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF", nullptr); - parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF0", nullptr); + parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); + parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); + parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF0", + unsupported_proxy()); parse_internal_link("t.me/proxy?server=google.com&port=8%30&secret=ee1234567890abcdef1234567890ABCDEF%30%30", proxy_mtproto("google.com", 80, "ee1234567890abcdef1234567890ABCDEF00")); parse_internal_link( @@ -491,24 +499,21 @@ TEST(Link, parse_internal_link) { proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); parse_internal_link("tg:proxy?server=1.2.3.4&port=80adasdas&secret=1234567890abcdef1234567890ABCDEF", proxy_mtproto("1.2.3.4", 80, "1234567890abcdef1234567890ABCDEF")); - parse_internal_link( - "tg:proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF", - unknown_deep_link("tg://proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF")); - parse_internal_link( - "tg:proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF", - unknown_deep_link("tg://proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF")); + parse_internal_link("tg:proxy?server=1.2.3.4&port=adasdas&secret=1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); + parse_internal_link("tg:proxy?server=1.2.3.4&port=65536&secret=1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=1234567890abcdef1234567890ABCDEF", proxy_mtproto("google.com", 80, "1234567890abcdef1234567890ABCDEF")); parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=dd1234567890abcdef1234567890ABCDEF", proxy_mtproto("google.com", 80, "dd1234567890abcdef1234567890ABCDEF")); - parse_internal_link( - "tg:proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF", - unknown_deep_link("tg://proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF")); + parse_internal_link("tg:proxy?server=google.com&port=8%30&secret=de1234567890abcdef1234567890ABCDEF", + unsupported_proxy()); parse_internal_link("t.me/socks?server=1.2.3.4&port=80", proxy_socks("1.2.3.4", 80, "", "")); parse_internal_link("t.me/socks?server=1.2.3.4&port=80adasdas", proxy_socks("1.2.3.4", 80, "", "")); - parse_internal_link("t.me/socks?server=1.2.3.4&port=adasdas", nullptr); - parse_internal_link("t.me/socks?server=1.2.3.4&port=65536", nullptr); + parse_internal_link("t.me/socks?server=1.2.3.4&port=adasdas", unsupported_proxy()); + parse_internal_link("t.me/socks?server=1.2.3.4&port=65536", unsupported_proxy()); parse_internal_link("t.me/socks?server=google.com&port=8%30", proxy_socks("google.com", 80, "", "")); parse_internal_link("t.me/socks?server=google.com&port=8%30&user=1&pass=", proxy_socks("google.com", 80, "1", "")); parse_internal_link("t.me/socks?server=google.com&port=8%30&user=&pass=2", proxy_socks("google.com", 80, "", "2")); @@ -516,9 +521,8 @@ TEST(Link, parse_internal_link) { parse_internal_link("tg:socks?server=1.2.3.4&port=80", proxy_socks("1.2.3.4", 80, "", "")); parse_internal_link("tg:socks?server=1.2.3.4&port=80adasdas", proxy_socks("1.2.3.4", 80, "", "")); - parse_internal_link("tg:socks?server=1.2.3.4&port=adasdas", - unknown_deep_link("tg://socks?server=1.2.3.4&port=adasdas")); - parse_internal_link("tg:socks?server=1.2.3.4&port=65536", unknown_deep_link("tg://socks?server=1.2.3.4&port=65536")); + parse_internal_link("tg:socks?server=1.2.3.4&port=adasdas", unsupported_proxy()); + parse_internal_link("tg:socks?server=1.2.3.4&port=65536", unsupported_proxy()); parse_internal_link("tg:socks?server=google.com&port=8%30", proxy_socks("google.com", 80, "", "")); parse_internal_link("tg:socks?server=google.com&port=8%30&user=1&pass=", proxy_socks("google.com", 80, "1", "")); parse_internal_link("tg:socks?server=google.com&port=8%30&user=&pass=2", proxy_socks("google.com", 80, "", "2")); From 39b5db357ea14841904665d47ca15708969def78 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 28 Oct 2021 22:49:56 +0300 Subject: [PATCH 48/82] Add updateNewChatJoinRequest. --- td/generate/scheme/td_api.tl | 4 ++++ td/telegram/ContactsManager.cpp | 22 +++++++++++++++++----- td/telegram/ContactsManager.h | 2 ++ td/telegram/UpdatesManager.cpp | 21 +++++++++++++++++---- td/telegram/UpdatesManager.h | 3 +-- 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 1a4cc674f..f344441af 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3935,6 +3935,10 @@ updatePollAnswer poll_id:int64 user_id:int53 option_ids:vector = Update; //@old_chat_member Previous chat member @new_chat_member New chat member updateChatMember chat_id:int53 actor_user_id:int53 date:int32 invite_link:chatInviteLink old_chat_member:chatMember new_chat_member:chatMember = Update; +//@description A user sent a join request to a chat; for bots only @chat_id Chat identifier @user_id Identifier of the user, which sent the join request +//@bio A short user bio @date Point in time (Unix timestamp) when the request was sent @invite_link The invite link, which was used to send join request; may be null +updateNewChatJoinRequest chat_id:int53 user_id:int53 bio:string date:int32 invite_link:chatInviteLink = Update; + //@description Contains a list of updates @updates List of updates updates updates:vector = Updates; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index ebab9cca2..d03a52c71 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -13625,14 +13625,10 @@ void ContactsManager::on_update_bot_stopped(UserId user_id, int32 date, bool is_ LOG(ERROR) << "Receive updateBotStopped by non-bot"; return; } - if (!user_id.is_valid() || date <= 0) { + if (date <= 0 || !have_user_force(user_id)) { LOG(ERROR) << "Receive invalid updateBotStopped by " << user_id << " at " << date; return; } - if (!have_user_force(user_id)) { - LOG(ERROR) << "Receive updateBotStopped by unknown " << user_id; - return; - } DialogParticipant old_dialog_participant(DialogId(get_my_id()), user_id, date, DialogParticipantStatus::Banned(0)); DialogParticipant new_dialog_participant(DialogId(get_my_id()), user_id, date, DialogParticipantStatus::Member()); @@ -13746,6 +13742,22 @@ void ContactsManager::on_update_channel_participant(ChannelId channel_id, UserId new_dialog_participant); } +void ContactsManager::on_update_chat_invite_requester(DialogId dialog_id, UserId user_id, string about, int32 date, + DialogInviteLink invite_link) { + if (!td_->auth_manager_->is_bot() || date <= 0 || !have_user_force(user_id) || + !td_->messages_manager_->have_dialog_info_force(dialog_id)) { + LOG(ERROR) << "Receive invalid updateBotChatInviteRequester by " << user_id << " in " << dialog_id << " at " + << date; + return; + } + td_->messages_manager_->force_create_dialog(dialog_id, "on_update_chat_invite_requester", true); + + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + dialog_id.get(), get_user_id_object(user_id, "on_update_chat_invite_requester"), about, date, + invite_link.get_chat_invite_link_object(this))); +} + void ContactsManager::update_contacts_hints(const User *u, UserId user_id, bool from_database) { bool is_contact = is_user_contact(u, user_id, false); if (td_->auth_manager_->is_bot()) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 52761b0c6..abff47b0e 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -202,6 +202,8 @@ class ContactsManager final : public Actor { void on_update_channel_participant(ChannelId channel_id, UserId user_id, int32 date, DialogInviteLink invite_link, tl_object_ptr old_participant, tl_object_ptr new_participant); + void on_update_chat_invite_requester(DialogId dialog_id, UserId user_id, string about, int32 date, + DialogInviteLink invite_link); int32 on_update_peer_located(vector> &&peers, bool from_update); diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index f403ee835..c50195871 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -2119,6 +2119,14 @@ void UpdatesManager::process_qts_update(tl_object_ptr &&up add_qts(qts).set_value(Unit()); break; } + case telegram_api::updateBotChatInviteRequester::ID: { + auto update = move_tl_object_as(update_ptr); + td_->contacts_manager_->on_update_chat_invite_requester(DialogId(update->peer_), UserId(update->user_id_), + std::move(update->about_), update->date_, + DialogInviteLink(std::move(update->invite_))); + add_qts(qts).set_value(Unit()); + break; + } default: UNREACHABLE(); break; @@ -2774,6 +2782,7 @@ bool UpdatesManager::is_qts_update(const telegram_api::Update *update) { case telegram_api::updateBotStopped::ID: case telegram_api::updateChatParticipant::ID: case telegram_api::updateChannelParticipant::ID: + case telegram_api::updateBotChatInviteRequester::ID: return true; default: return false; @@ -2792,6 +2801,8 @@ int32 UpdatesManager::get_update_qts(const telegram_api::Update *update) { return static_cast(update)->qts_; case telegram_api::updateChannelParticipant::ID: return static_cast(update)->qts_; + case telegram_api::updateBotChatInviteRequester::ID: + return static_cast(update)->qts_; default: return 0; } @@ -3207,6 +3218,12 @@ void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { td_->theme_manager_->on_update_theme(std::move(update->theme_), std::move(promise)); } @@ -3219,8 +3236,4 @@ void UpdatesManager::on_update(tl_object_ptr update, - Promise &&promise) { -} - } // namespace td diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 05527d8f6..cdbed6c6d 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -487,14 +487,13 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); // unsupported updates - - void on_update(tl_object_ptr update, Promise &&promise); }; } // namespace td From 13c76b349de2d532039d262257bb7be4741939e6 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 30 Oct 2021 03:34:49 +0300 Subject: [PATCH 49/82] Add td_api::getChatMessageCalendar. --- td/generate/scheme/td_api.tl | 12 ++ td/telegram/MessagesManager.cpp | 224 +++++++++++++++++++++++++++++++- td/telegram/MessagesManager.h | 12 ++ td/telegram/Td.cpp | 34 +++++ td/telegram/Td.h | 2 + td/telegram/cli.cpp | 7 + 6 files changed, 288 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index f344441af..d12667e42 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -819,6 +819,12 @@ messagePosition position:int32 message_id:int53 date:int32 = MessagePosition; //@description Contains a list of message positions @total_count Total count of messages found @positions List of message positions messagePositions total_count:int32 positions:vector = MessagePositions; +//@description Contains information about found messages sent in a specific day @total_count Total number of found messages sent in the day @message First message sent in the day +messageCalendarDay total_count:int32 message:message = MessageCalendarDay; + +//@description Contains information about found messages, splitted by days @total_count Total number of found messages @utc_time_offset UTC time offset in seconds, used to split messages by days @days Information about messages sent +messageCalendar total_count:int32 utc_time_offset:int32 days:vector = MessageCalendar; + //@description Describes a sponsored message @id Unique sponsored message identifier @sponsor_chat_id Chat identifier //@link An internal link to be opened when the sponsored message is clicked; may be null. If null, the sponsor chat needs to be opened instead @content Content of the message @@ -4299,6 +4305,12 @@ getChatMessageByDate chat_id:int53 date:int32 = Message; //@limit The expected number of message positions to be returned. A smaller number of positions can be returned, if there are not enough appropriate messages getChatSparseMessagePositions chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 limit:int32 = MessagePositions; +//@description Returns information about the next messages of the specified type in the chat splitted by days. Returns the results in reverse chronological order. Can return partial result for the last returned day +//@chat_id Identifier of the chat in which to return information about messages +//@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention, searchMessagesFilterUnreadMention and searchMessagesFilterFailedToSend are unsupported in this function +//@from_message_id The message identifier from which to return information about messages; use 0 to get results from the last message +getChatMessageCalendar chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 = MessageCalendar; + //@description Returns approximate number of messages of the specified type in the chat @chat_id Identifier of the chat in which to count messages @filter Filter for message content; searchMessagesFilterEmpty is unsupported in this function @return_local If true, returns count that is available locally without sending network requests, returning -1 if the number of messages is unknown getChatMessageCount chat_id:int53 filter:SearchMessagesFilter return_local:Bool = Count; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 409d3dbb9..4fa96eb22 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2167,6 +2167,70 @@ class ReadDiscussionQuery final : public Td::ResultHandler { } }; +class GetSearchResultCalendarQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + MessageId from_message_id_; + MessageSearchFilter filter_; + int64 random_id_; + + public: + explicit GetSearchResultCalendarQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, int64 random_id) { + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + CHECK(input_peer != nullptr); + + dialog_id_ = dialog_id; + from_message_id_ = from_message_id; + filter_ = filter; + random_id_ = random_id; + + send_query(G()->net_query_creator().create(telegram_api::messages_getSearchResultsCalendar( + std::move(input_peer), get_input_messages_filter(filter), from_message_id.get_server_message_id().get(), 0))); + } + + void on_result(uint64 id, BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetSearchResultCalendarQuery: " << to_string(result); + td->contacts_manager_->on_get_users(std::move(result->users_), "GetSearchResultCalendarQuery"); + td->contacts_manager_->on_get_chats(std::move(result->chats_), "GetSearchResultCalendarQuery"); + + MessagesManager::MessagesInfo info; + info.messages = std::move(result->messages_); + info.total_count = result->count_; + info.is_channel_messages = dialog_id_.get_type() == DialogType::Channel; + + td->messages_manager_->get_channel_difference_if_needed( + dialog_id_, std::move(info), + PromiseCreator::lambda([actor_id = td->messages_manager_actor_.get(), dialog_id = dialog_id_, + from_message_id = from_message_id_, filter = filter_, random_id = random_id_, + periods = std::move(result->periods_), + promise = std::move(promise_)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + auto info = result.move_as_ok(); + send_closure(actor_id, &MessagesManager::on_get_message_search_result_calendar, dialog_id, from_message_id, + filter, random_id, info.total_count, std::move(info.messages), std::move(periods), + std::move(promise)); + } + })); + } + + void on_error(uint64 id, Status status) final { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "SearchMessagesQuery"); + td->messages_manager_->on_failed_get_message_search_result_calendar(dialog_id_, random_id_); + promise_.set_error(std::move(status)); + } +}; + class SearchMessagesQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -9693,6 +9757,71 @@ void MessagesManager::on_failed_public_dialogs_search(const string &query, Statu } } +void MessagesManager::on_get_message_search_result_calendar( + DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, int64 random_id, int32 total_count, + vector> &&messages, + vector> &&periods, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto it = found_dialog_message_calendars_.find(random_id); + CHECK(it != found_dialog_message_calendars_.end()); + + int32 received_message_count = 0; + for (auto &message : messages) { + auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, + false, false, false, "on_get_message_search_result_calendar"); + if (new_full_message_id == FullMessageId()) { + total_count--; + continue; + } + + if (new_full_message_id.get_dialog_id() != dialog_id) { + LOG(ERROR) << "Receive " << new_full_message_id << " instead of a message in " << dialog_id; + total_count--; + continue; + } + + received_message_count++; + } + if (total_count < received_message_count) { + LOG(ERROR) << "Receive " << received_message_count << " valid messages out of " << total_count << " in " + << messages.size() << " messages"; + total_count = received_message_count; + } + + Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); + auto &old_message_count = d->message_count_by_index[message_search_filter_index(filter)]; + if (old_message_count != total_count) { + old_message_count = total_count; + on_dialog_updated(dialog_id, "on_get_message_search_result_calendar"); + } + + vector> days; + for (auto &period : periods) { + auto message_id = MessageId(ServerMessageId(period->min_msg_id_)); + const auto *m = get_message(d, message_id); + if (m == nullptr) { + LOG(ERROR) << "Failed to find " << message_id; + continue; + } + if (period->count_ <= 0) { + LOG(ERROR) << "Receive " << to_string(period); + continue; + } + days.push_back(td_api::make_object( + period->count_, get_message_object(dialog_id, m, "on_get_message_search_result_calendar"))); + } + it->second = td_api::make_object(total_count, Clocks::tz_offset(), std::move(days)); + promise.set_value(Unit()); +} + +void MessagesManager::on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id) { + auto it = found_dialog_message_calendars_.find(random_id); + CHECK(it != found_dialog_message_calendars_.end()); + found_dialog_message_calendars_.erase(it); +} + void MessagesManager::on_get_dialog_messages_search_result( DialogId dialog_id, const string &query, DialogId sender_dialog_id, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, int64 random_id, int32 total_count, @@ -21220,7 +21349,7 @@ std::pair> MessagesManager::get_message_thread_histo from_message_id = MessageId::max(); } if (!from_message_id.is_valid()) { - promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of the chat message or 0")); + promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); return {}; } @@ -21339,6 +21468,95 @@ std::pair> MessagesManager::get_message_thread_histo return {}; } +td_api::object_ptr MessagesManager::get_dialog_message_calendar(DialogId dialog_id, + MessageId from_message_id, + MessageSearchFilter filter, + int64 &random_id, bool use_db, + Promise &&promise) { + if (random_id != 0) { + // request has already been sent before + auto it = found_dialog_message_calendars_.find(random_id); + if (it != found_dialog_message_calendars_.end()) { + auto result = std::move(it->second); + found_dialog_message_calendars_.erase(it); + promise.set_value(Unit()); + return result; + } + random_id = 0; + } + LOG(INFO) << "Get message calendar in " << dialog_id << " filtered by " << filter << " from " << from_message_id; + + if (from_message_id.get() > MessageId::max().get()) { + from_message_id = MessageId::max(); + } + + if (!from_message_id.is_valid() && from_message_id != MessageId()) { + promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); + return {}; + } + from_message_id = from_message_id.get_next_server_message_id(); + + const Dialog *d = get_dialog_force(dialog_id, "get_dialog_message_calendar"); + if (d == nullptr) { + promise.set_error(Status::Error(400, "Chat not found")); + return {}; + } + if (!have_input_peer(dialog_id, AccessRights::Read)) { + promise.set_error(Status::Error(400, "Can't access the chat")); + return {}; + } + + do { + random_id = Random::secure_int64(); + } while (random_id == 0 || found_dialog_message_calendars_.find(random_id) != found_dialog_message_calendars_.end()); + found_dialog_message_calendars_[random_id]; // reserve place for result + + if (filter == MessageSearchFilter::Empty || filter == MessageSearchFilter::Call || + filter == MessageSearchFilter::MissedCall || filter == MessageSearchFilter::Mention || + filter == MessageSearchFilter::UnreadMention) { + promise.set_error(Status::Error(400, "The filter is not supported")); + return {}; + } + + // Trying to use database + if (use_db && G()->parameters().use_message_db) { + MessageId first_db_message_id = get_first_database_message_id_by_index(d, filter); + int32 message_count = d->message_count_by_index[message_search_filter_index(filter)]; + auto fixed_from_message_id = from_message_id; + if (fixed_from_message_id == MessageId()) { + fixed_from_message_id = MessageId::max(); + } + LOG(INFO) << "Get message calendar in " << dialog_id << " from " << fixed_from_message_id << ", have up to " + << first_db_message_id << ", message_count = " << message_count; + if (first_db_message_id < fixed_from_message_id && message_count != -1) { + // TODO + } + } + if (filter == MessageSearchFilter::FailedToSend) { + promise.set_value(Unit()); + return {}; + } + + LOG(DEBUG) << "Get message calendar from server in " << dialog_id << " from " << from_message_id; + + switch (dialog_id.get_type()) { + case DialogType::None: + case DialogType::User: + case DialogType::Chat: + case DialogType::Channel: + td_->create_handler(std::move(promise)) + ->send(dialog_id, from_message_id, filter, random_id); + break; + case DialogType::SecretChat: + promise.set_value(Unit()); + break; + default: + UNREACHABLE(); + promise.set_error(Status::Error(500, "Search messages is not supported")); + } + return {}; +} + std::pair> MessagesManager::search_dialog_messages( DialogId dialog_id, const string &query, const td_api::object_ptr &sender, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, @@ -21381,7 +21599,7 @@ std::pair> MessagesManager::search_dialog_messages( } if (!from_message_id.is_valid() && from_message_id != MessageId()) { - promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of the chat message or 0")); + promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); return result; } from_message_id = from_message_id.get_next_server_message_id(); @@ -21569,7 +21787,7 @@ std::pair> MessagesManager::search_call_messages(Me } if (!from_message_id.is_valid() && from_message_id != MessageId()) { - promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of the chat message or 0")); + promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); return result; } from_message_id = from_message_id.get_next_server_message_id(); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 3ce4089d7..1ff7a089a 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -205,6 +205,13 @@ class MessagesManager final : public Actor { vector> &&peers); void on_failed_public_dialogs_search(const string &query, Status &&error); + void on_get_message_search_result_calendar(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, + int64 random_id, int32 total_count, + vector> &&messages, + vector> &&periods, + Promise &&promise); + void on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id); + void on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, DialogId sender_dialog_id, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, @@ -695,6 +702,10 @@ class MessagesManager final : public Actor { int32 limit, int64 &random_id, Promise &&promise); + td_api::object_ptr get_dialog_message_calendar(DialogId dialog_id, MessageId from_message_id, + MessageSearchFilter filter, int64 &random_id, + bool use_db, Promise &&promise); + std::pair> search_dialog_messages(DialogId dialog_id, const string &query, const td_api::object_ptr &sender, MessageId from_message_id, int32 offset, int32 limit, @@ -3324,6 +3335,7 @@ class MessagesManager final : public Actor { std::unordered_map get_dialog_message_by_date_results_; + std::unordered_map> found_dialog_message_calendars_; std::unordered_map>> found_dialog_messages_; // random_id -> [total_count, [message_id]...] std::unordered_map found_dialog_messages_dialog_id_; // random_id -> dialog_id diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index ab5076352..5056cc716 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -1349,6 +1349,35 @@ class GetMessageThreadHistoryRequest final : public RequestActor<> { } }; +class GetChatMessageCalendarRequest final : public RequestActor<> { + DialogId dialog_id_; + MessageId from_message_id_; + MessageSearchFilter filter_; + int64 random_id_; + + td_api::object_ptr calendar_; + + void do_run(Promise &&promise) final { + calendar_ = td->messages_manager_->get_dialog_message_calendar(dialog_id_, from_message_id_, filter_, random_id_, + get_tries() == 3, std::move(promise)); + } + + void do_send_result() final { + send_result(std::move(calendar_)); + } + + public: + GetChatMessageCalendarRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 from_message_id, + tl_object_ptr filter) + : RequestActor(std::move(td), request_id) + , dialog_id_(dialog_id) + , from_message_id_(from_message_id) + , filter_(get_message_search_filter(filter)) + , random_id_(0) { + set_tries(3); + } +}; + class SearchChatMessagesRequest final : public RequestActor<> { DialogId dialog_id_; string query_; @@ -5321,6 +5350,11 @@ void Td::on_request(uint64 id, const td_api::getMessageThreadHistory &request) { request.offset_, request.limit_); } +void Td::on_request(uint64 id, td_api::getChatMessageCalendar &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetChatMessageCalendarRequest, request.chat_id_, request.from_message_id_, std::move(request.filter_)); +} + void Td::on_request(uint64 id, td_api::searchChatMessages &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.query_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 90eb04802..9d1be0fd3 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -612,6 +612,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getMessageThreadHistory &request); + void on_request(uint64 id, td_api::getChatMessageCalendar &request); + void on_request(uint64 id, td_api::searchChatMessages &request); void on_request(uint64 id, td_api::searchSecretMessages &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index b4fc390b3..bc69d2917 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2097,6 +2097,13 @@ class CliClient final : public Actor { string limit; get_args(args, chat_id, limit); send_request(td_api::make_object(as_chat_id(chat_id), as_limit(limit))); + } else if (op == "gcmca") { + string chat_id; + string filter; + string from_message_id; + get_args(args, chat_id, filter, from_message_id); + send_request(td_api::make_object( + as_chat_id(chat_id), as_search_messages_filter(filter), as_message_id(from_message_id))); } else if (op == "SearchAudio" || op == "SearchDocument" || op == "SearchPhoto" || op == "SearchChatPhoto") { string chat_id; string offset_message_id; From 463c4e96acd4a4cd42e9ef01c87742684d9b7e8c Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 12:52:51 +0300 Subject: [PATCH 50/82] Pass MessageSearchFilter instead of index_mask in message database queries. --- td/telegram/MessagesDb.cpp | 60 +++++++-------------------------- td/telegram/MessagesDb.h | 8 +++-- td/telegram/MessagesManager.cpp | 10 +++--- 3 files changed, 22 insertions(+), 56 deletions(-) diff --git a/td/telegram/MessagesDb.cpp b/td/telegram/MessagesDb.cpp index 3b11a1b8d..79069cfa7 100644 --- a/td/telegram/MessagesDb.cpp +++ b/td/telegram/MessagesDb.cpp @@ -7,7 +7,6 @@ #include "td/telegram/MessagesDb.h" #include "td/telegram/logevent/LogEvent.h" -#include "td/telegram/MessageSearchFilter.h" #include "td/telegram/Version.h" #include "td/db/SqliteConnectionSafe.h" @@ -335,7 +334,7 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { if (search_id != 0) { // add dialog_id to text text += PSTRING() << " \a" << dialog_id.get(); - if (index_mask) { + if (index_mask != 0) { for (int i = 0; i < MESSAGES_DB_INDEX_COUNT; i++) { if ((index_mask & (1 << i))) { text += PSTRING() << " \a\a" << i; @@ -613,9 +612,8 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { } Result> get_messages(MessagesDbMessagesQuery query) final { - if (query.index_mask != 0) { - return get_messages_from_index(query.dialog_id, query.from_message_id, query.index_mask, query.offset, - query.limit); + if (query.filter != MessageSearchFilter::Empty) { + return get_messages_from_index(query.dialog_id, query.from_message_id, query.filter, query.offset, query.limit); } return get_messages_impl(get_messages_stmt_, query.dialog_id, query.from_message_id, query.offset, query.limit); } @@ -699,7 +697,7 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { get_messages_fts_stmt_.reset(); }; - LOG(INFO) << tag("query", query.query) << query.dialog_id << tag("index_mask", query.index_mask) + LOG(INFO) << tag("query", query.query) << query.dialog_id << tag("filter", query.filter) << tag("from_search_id", query.from_search_id) << tag("limit", query.limit); string words = prepare_query(query.query); LOG(INFO) << tag("from", query.query) << tag("to", words); @@ -710,18 +708,8 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { } // index_mask kludge - if (query.index_mask != 0) { - int index_i = -1; - for (int i = 0; i < MESSAGES_DB_INDEX_COUNT; i++) { - if (query.index_mask == (1 << i)) { - index_i = i; - break; - } - } - if (index_i == -1) { - return Status::Error("Union of index types is not supported"); - } - words += PSTRING() << " \"\a\a" << index_i << "\""; + if (query.filter != MessageSearchFilter::Empty) { + words += PSTRING() << " \"\a\a" << message_search_filter_index(query.filter) << "\""; } auto &stmt = get_messages_fts_stmt_; @@ -750,44 +738,20 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { } Result> get_messages_from_index(DialogId dialog_id, MessageId from_message_id, - int32 index_mask, int32 offset, int32 limit) { - CHECK(index_mask != 0); - LOG_CHECK(index_mask < (1 << MESSAGES_DB_INDEX_COUNT)) << tag("index_mask", index_mask); - int index_i = -1; - for (int i = 0; i < MESSAGES_DB_INDEX_COUNT; i++) { - if (index_mask == (1 << i)) { - index_i = i; - break; - } - } - if (index_i == -1) { - return Status::Error("Union is not supported"); - } - - auto &stmt = get_messages_from_index_stmts_[index_i]; + MessageSearchFilter filter, int32 offset, + int32 limit) { + auto &stmt = get_messages_from_index_stmts_[message_search_filter_index(filter)]; return get_messages_impl(stmt, dialog_id, from_message_id, offset, limit); } Result get_calls(MessagesDbCallsQuery query) final { - CHECK(query.index_mask != 0); - LOG_CHECK(query.index_mask < (1 << MESSAGES_DB_INDEX_COUNT)) << tag("index_mask", query.index_mask); - int index_i = -1; - for (int i = 0; i < MESSAGES_DB_INDEX_COUNT; i++) { - if (query.index_mask == (1 << i)) { - index_i = i; - break; - } - } - if (index_i == -1) { - return Status::Error("Union is not supported"); - } int32 pos; - if (index_i + 1 == static_cast(MessageSearchFilter::Call)) { + if (query.filter == MessageSearchFilter::Call) { pos = 0; - } else if (index_i + 1 == static_cast(MessageSearchFilter::MissedCall)) { + } else if (query.filter == MessageSearchFilter::MissedCall) { pos = 1; } else { - return Status::Error(PSLICE() << "Index mask is not Call or MissedCall " << query.index_mask); + return Status::Error(PSLICE() << "Filter is not Call or MissedCall: " << query.filter); } auto &stmt = get_calls_stmts_[pos]; diff --git a/td/telegram/MessagesDb.h b/td/telegram/MessagesDb.h index 33abd123b..5e8216814 100644 --- a/td/telegram/MessagesDb.h +++ b/td/telegram/MessagesDb.h @@ -9,6 +9,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/FullMessageId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageSearchFilter.h" #include "td/telegram/NotificationId.h" #include "td/telegram/ServerMessageId.h" @@ -28,7 +29,7 @@ class SqliteDb; struct MessagesDbMessagesQuery { DialogId dialog_id; - int32 index_mask{0}; + MessageSearchFilter filter{MessageSearchFilter::Empty}; MessageId from_message_id; int32 offset{0}; int32 limit{100}; @@ -48,7 +49,7 @@ struct MessagesDbMessage { struct MessagesDbFtsQuery { string query; DialogId dialog_id; - int32 index_mask{0}; + MessageSearchFilter filter{MessageSearchFilter::Empty}; int64 from_search_id{0}; int32 limit{100}; }; @@ -58,10 +59,11 @@ struct MessagesDbFtsResult { }; struct MessagesDbCallsQuery { - int32 index_mask{0}; + MessageSearchFilter filter{MessageSearchFilter::Empty}; int32 from_unique_message_id{0}; int32 limit{100}; }; + struct MessagesDbCallsResult { vector messages; }; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 4fa96eb22..24a330dbe 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -21717,7 +21717,7 @@ std::pair> MessagesManager::search_dialog_messages( }); MessagesDbMessagesQuery db_query; db_query.dialog_id = dialog_id; - db_query.index_mask = message_search_filter_index_mask(filter); + db_query.filter = filter; db_query.from_message_id = fixed_from_message_id; db_query.offset = offset; db_query.limit = limit; @@ -21815,7 +21815,7 @@ std::pair> MessagesManager::search_call_messages(Me LOG(INFO) << "Search messages in database from " << fixed_from_message_id << " and with limit " << limit; MessagesDbCallsQuery db_query; - db_query.index_mask = message_search_filter_index_mask(filter); + db_query.filter = filter; db_query.from_unique_message_id = fixed_from_message_id.get_server_message_id().get(); db_query.limit = limit; G()->td_db()->get_messages_db_async()->get_calls( @@ -22351,7 +22351,7 @@ MessagesManager::FoundMessages MessagesManager::offline_search_messages(DialogId MessagesDbFtsQuery fts_query; fts_query.query = query; fts_query.dialog_id = dialog_id; - fts_query.index_mask = message_search_filter_index_mask(filter); + fts_query.filter = filter; if (!offset.empty()) { auto r_from_search_id = to_integer_safe(offset); if (r_from_search_id.is_error()) { @@ -28181,7 +28181,7 @@ Result> MessagesManager::do_get_message_notifica // ignore first_db_message_id, notifications can be nonconsecutive MessagesDbMessagesQuery db_query; db_query.dialog_id = d->dialog_id; - db_query.index_mask = message_search_filter_index_mask(MessageSearchFilter::UnreadMention); + db_query.filter = MessageSearchFilter::UnreadMention; db_query.from_message_id = from_message_id; db_query.offset = 0; db_query.limit = limit; @@ -28303,7 +28303,7 @@ void MessagesManager::do_get_message_notifications_from_database(Dialog *d, bool // ignore first_db_message_id, notifications can be nonconsecutive MessagesDbMessagesQuery db_query; db_query.dialog_id = dialog_id; - db_query.index_mask = message_search_filter_index_mask(MessageSearchFilter::UnreadMention); + db_query.filter = MessageSearchFilter::UnreadMention; db_query.from_message_id = from_message_id; db_query.offset = 0; db_query.limit = limit; From 5a82af3f7fc9bb16fa8db4799f3e84304f13a186 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 13:50:45 +0300 Subject: [PATCH 51/82] Add MessagesDbDialogCalendarQuery. --- td/generate/scheme/td_api.tl | 2 +- td/telegram/MessagesDb.cpp | 55 ++++++++++++++++++++--- td/telegram/MessagesDb.h | 17 ++++++++ td/telegram/MessagesManager.cpp | 77 +++++++++++++++++++++++++++++++-- td/telegram/MessagesManager.h | 8 +++- 5 files changed, 147 insertions(+), 12 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index d12667e42..23d7a3871 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4307,7 +4307,7 @@ getChatSparseMessagePositions chat_id:int53 filter:SearchMessagesFilter from_mes //@description Returns information about the next messages of the specified type in the chat splitted by days. Returns the results in reverse chronological order. Can return partial result for the last returned day //@chat_id Identifier of the chat in which to return information about messages -//@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention, searchMessagesFilterUnreadMention and searchMessagesFilterFailedToSend are unsupported in this function +//@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention and searchMessagesFilterUnreadMention are unsupported in this function //@from_message_id The message identifier from which to return information about messages; use 0 to get results from the last message getChatMessageCalendar chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 = MessageCalendar; diff --git a/td/telegram/MessagesDb.cpp b/td/telegram/MessagesDb.cpp index 79069cfa7..d42b31e22 100644 --- a/td/telegram/MessagesDb.cpp +++ b/td/telegram/MessagesDb.cpp @@ -611,6 +611,38 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { return std::make_pair(std::move(messages), next_expires_till); } + Result get_dialog_message_calendar(MessagesDbDialogCalendarQuery query) final { + auto &stmt = get_messages_from_index_stmts_[message_search_filter_index(query.filter)].desc_stmt_; + SCOPE_EXIT { + stmt.reset(); + }; + int32 limit = 1000; + stmt.bind_int64(1, query.dialog_id.get()).ensure(); + stmt.bind_int64(2, query.from_message_id.get()).ensure(); + stmt.bind_int32(3, limit).ensure(); + + vector messages; + vector total_counts; + stmt.step().ensure(); + int32 current_day = std::numeric_limits::max(); + while (stmt.has_row()) { + auto data_slice = stmt.view_blob(0); + MessageId message_id(stmt.view_int64(1)); + auto info = get_message_info(message_id, data_slice, false); + auto day = (query.tz_offset + info.second) / 86400; + if (day >= current_day) { + CHECK(!total_counts.empty()); + total_counts.back()++; + } else { + current_day = day; + messages.push_back(MessagesDbDialogMessage{message_id, BufferSlice(data_slice)}); + total_counts.push_back(1); + } + stmt.step().ensure(); + } + return MessagesDbCalendar{std::move(messages), std::move(total_counts)}; + } + Result> get_messages(MessagesDbMessagesQuery query) final { if (query.filter != MessageSearchFilter::Empty) { return get_messages_from_index(query.dialog_id, query.from_message_id, query.filter, query.offset, query.limit); @@ -892,7 +924,11 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { } static std::pair get_message_info(const MessagesDbDialogMessage &message, bool from_data = false) { - LogEventParser message_date_parser(message.data.as_slice()); + return get_message_info(message.message_id, message.data.as_slice(), from_data); + } + + static std::pair get_message_info(MessageId message_id, Slice data, bool from_data) { + LogEventParser message_date_parser(data); int32 flags; int32 flags2 = 0; int32 flags3 = 0; @@ -904,17 +940,17 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { } } bool has_sender = (flags & (1 << 10)) != 0; - MessageId message_id; - td::parse(message_id, message_date_parser); + MessageId data_message_id; + td::parse(data_message_id, message_date_parser); UserId sender_user_id; if (has_sender) { td::parse(sender_user_id, message_date_parser); } int32 date; td::parse(date, message_date_parser); - LOG(INFO) << "Loaded " << message.message_id << "(aka " << message_id << ") sent at " << date << " by " + LOG(INFO) << "Loaded " << message_id << "(aka " << data_message_id << ") sent at " << date << " by " << sender_user_id; - return {from_data ? message_id : message.message_id, date}; + return {from_data ? data_message_id : message_id, date}; } }; @@ -980,6 +1016,10 @@ class MessagesDbAsync final : public MessagesDbAsyncInterface { std::move(promise)); } + void get_dialog_message_calendar(MessagesDbDialogCalendarQuery query, Promise promise) final { + send_closure_later(impl_, &Impl::get_dialog_message_calendar, std::move(query), std::move(promise)); + } + void get_messages(MessagesDbMessagesQuery query, Promise> promise) final { send_closure_later(impl_, &Impl::get_messages, std::move(query), std::move(promise)); } @@ -1071,6 +1111,11 @@ class MessagesDbAsync final : public MessagesDbAsyncInterface { promise.set_result(sync_db_->get_dialog_message_by_date(dialog_id, first_message_id, last_message_id, date)); } + void get_dialog_message_calendar(MessagesDbDialogCalendarQuery query, Promise promise) { + add_read_query(); + promise.set_result(sync_db_->get_dialog_message_calendar(std::move(query))); + } + void get_messages(MessagesDbMessagesQuery query, Promise> promise) { add_read_query(); promise.set_result(sync_db_->get_messages(std::move(query))); diff --git a/td/telegram/MessagesDb.h b/td/telegram/MessagesDb.h index 5e8216814..30139a35a 100644 --- a/td/telegram/MessagesDb.h +++ b/td/telegram/MessagesDb.h @@ -46,6 +46,18 @@ struct MessagesDbMessage { BufferSlice data; }; +struct MessagesDbDialogCalendarQuery { + DialogId dialog_id; + MessageSearchFilter filter{MessageSearchFilter::Empty}; + MessageId from_message_id; + int32 tz_offset{0}; +}; + +struct MessagesDbCalendar { + vector messages; + vector total_counts; +}; + struct MessagesDbFtsQuery { string query; DialogId dialog_id; @@ -90,6 +102,8 @@ class MessagesDbSyncInterface { virtual Result get_dialog_message_by_date(DialogId dialog_id, MessageId first_message_id, MessageId last_message_id, int32 date) = 0; + virtual Result get_dialog_message_calendar(MessagesDbDialogCalendarQuery query) = 0; + virtual Result> get_messages(MessagesDbMessagesQuery query) = 0; virtual Result> get_scheduled_messages(DialogId dialog_id, int32 limit) = 0; virtual Result> get_messages_from_notification_id(DialogId dialog_id, @@ -141,6 +155,9 @@ class MessagesDbAsyncInterface { virtual void get_dialog_message_by_date(DialogId dialog_id, MessageId first_message_id, MessageId last_message_id, int32 date, Promise promise) = 0; + virtual void get_dialog_message_calendar(MessagesDbDialogCalendarQuery query, + Promise promise) = 0; + virtual void get_messages(MessagesDbMessagesQuery query, Promise> promise) = 0; virtual void get_scheduled_messages(DialogId dialog_id, int32 limit, Promise> promise) = 0; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 24a330dbe..78156f76b 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -67,6 +67,7 @@ #include "td/utils/format.h" #include "td/utils/misc.h" #include "td/utils/PathView.h" +#include "td/utils/port/Clocks.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" @@ -21529,7 +21530,21 @@ td_api::object_ptr MessagesManager::get_dialog_message_ LOG(INFO) << "Get message calendar in " << dialog_id << " from " << fixed_from_message_id << ", have up to " << first_db_message_id << ", message_count = " << message_count; if (first_db_message_id < fixed_from_message_id && message_count != -1) { - // TODO + LOG(INFO) << "Get message calendar from database in " << dialog_id << " from " << fixed_from_message_id; + auto new_promise = + PromiseCreator::lambda([random_id, dialog_id, fixed_from_message_id, first_db_message_id, filter, + promise = std::move(promise)](Result r_calendar) mutable { + send_closure(G()->messages_manager(), &MessagesManager::on_get_message_calendar_from_database, random_id, + dialog_id, fixed_from_message_id, first_db_message_id, filter, std::move(r_calendar), + std::move(promise)); + }); + MessagesDbDialogCalendarQuery db_query; + db_query.dialog_id = dialog_id; + db_query.filter = filter; + db_query.from_message_id = fixed_from_message_id; + db_query.tz_offset = Clocks::tz_offset(); + G()->td_db()->get_messages_db_async()->get_dialog_message_calendar(db_query, std::move(new_promise)); + return {}; } } if (filter == MessageSearchFilter::FailedToSend) { @@ -21557,6 +21572,60 @@ td_api::object_ptr MessagesManager::get_dialog_message_ return {}; } +void MessagesManager::on_get_message_calendar_from_database(int64 random_id, DialogId dialog_id, + MessageId from_message_id, MessageId first_db_message_id, + MessageSearchFilter filter, + Result r_calendar, + Promise promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + if (r_calendar.is_error()) { + LOG(ERROR) << "Failed to get message calendar from the database: " << r_calendar.error(); + if (first_db_message_id != MessageId::min() && dialog_id.get_type() != DialogType::SecretChat && + filter != MessageSearchFilter::FailedToSend) { + found_dialog_message_calendars_.erase(random_id); + } + return promise.set_value(Unit()); + } + CHECK(!from_message_id.is_scheduled()); + CHECK(!first_db_message_id.is_scheduled()); + + auto calendar = r_calendar.move_as_ok(); + + Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); + + auto it = found_dialog_message_calendars_.find(random_id); + CHECK(it != found_dialog_message_calendars_.end()); + CHECK(it->second == nullptr); + + vector> periods; + periods.reserve(calendar.messages.size()); + for (size_t i = 0; i < calendar.messages.size(); i++) { + auto m = on_get_message_from_database(d, calendar.messages[i], false, "on_get_message_calendar_from_database"); + if (m != nullptr && first_db_message_id <= m->message_id) { + CHECK(!m->message_id.is_scheduled()); + periods.emplace_back(m->message_id, calendar.total_counts[i]); + } + } + + if (periods.empty() && first_db_message_id != MessageId::min() && dialog_id.get_type() != DialogType::SecretChat) { + LOG(INFO) << "No messages found in database"; + found_dialog_message_calendars_.erase(it); + } else { + auto total_count = d->message_count_by_index[message_search_filter_index(filter)]; + vector> days; + for (auto &period : periods) { + const auto *m = get_message(d, period.first); + CHECK(m != nullptr); + days.push_back(td_api::make_object( + period.second, get_message_object(dialog_id, m, "on_get_message_calendar_from_database"))); + } + it->second = td_api::make_object(total_count, Clocks::tz_offset(), std::move(days)); + } + promise.set_value(Unit()); +} + std::pair> MessagesManager::search_dialog_messages( DialogId dialog_id, const string &query, const td_api::object_ptr &sender, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, @@ -22233,7 +22302,7 @@ void MessagesManager::on_search_dialog_messages_db_result(int64 random_id, Dialo MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, int32 offset, int32 limit, Result> r_messages, - Promise<> promise) { + Promise promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); if (r_messages.is_error()) { @@ -22287,7 +22356,7 @@ void MessagesManager::on_search_dialog_messages_db_result(int64 random_id, Dialo } it->second.first = message_count; if (res.empty() && first_db_message_id != MessageId::min() && dialog_id.get_type() != DialogType::SecretChat) { - LOG(INFO) << "No messages in database found"; + LOG(INFO) << "No messages found in database"; found_dialog_messages_.erase(it); } else { LOG(INFO) << "Found " << res.size() << " messages out of " << message_count << " in database"; @@ -22437,7 +22506,7 @@ void MessagesManager::on_messages_db_calls_result(Result it->second.first = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; if (res.empty() && first_db_message_id != MessageId::min()) { - LOG(INFO) << "No messages in database found"; + LOG(INFO) << "No messages found in database"; found_call_messages_.erase(it); } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 1ff7a089a..d720b2644 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -2817,13 +2817,17 @@ class MessagesManager final : public Actor { static MessageId get_first_database_message_id_by_index(const Dialog *d, MessageSearchFilter filter); + void on_get_message_calendar_from_database(int64 random_id, DialogId dialog_id, MessageId from_message_id, + MessageId first_db_message_id, MessageSearchFilter filter, + Result r_calendar, Promise promise); + void on_search_dialog_messages_db_result(int64 random_id, DialogId dialog_id, MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, int32 offset, int32 limit, Result> r_messages, - Promise<> promise); + Promise promise); void on_messages_db_fts_result(Result result, string offset, int32 limit, int64 random_id, - Promise<> &&promise); + Promise &&promise); void on_messages_db_calls_result(Result result, int64 random_id, MessageId first_db_message_id, MessageSearchFilter filter, Promise &&promise); From a3b71ca82c0dc5e162310eb78e9bf6245dab72ed Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 16:30:03 +0300 Subject: [PATCH 52/82] Support getChatSparseMessagePositions in secret chats when message database enabled. --- td/generate/scheme/td_api.tl | 9 +++--- td/telegram/MessagesDb.cpp | 55 +++++++++++++++++++++++++++++++-- td/telegram/MessagesDb.h | 24 ++++++++++++++ td/telegram/MessagesManager.cpp | 35 +++++++++++++++++++-- 4 files changed, 113 insertions(+), 10 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 23d7a3871..5fa99fc85 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -813,7 +813,7 @@ messages total_count:int32 messages:vector = Messages; //@description Contains a list of messages found by a search @total_count Approximate total count of messages found; -1 if unknown @messages List of messages @next_offset The offset for the next request. If empty, there are no more results foundMessages total_count:int32 messages:vector next_offset:string = FoundMessages; -//@description Contains information about a message in a specific position @position 1-based message position in the full list of suitable messages @message_id Message identifier @date Point in time (Unix timestamp) when the message was sent +//@description Contains information about a message in a specific position @position 0-based message position in the full list of suitable messages @message_id Message identifier @date Point in time (Unix timestamp) when the message was sent messagePosition position:int32 message_id:int53 date:int32 = MessagePosition; //@description Contains a list of message positions @total_count Total count of messages found @positions List of message positions @@ -4298,11 +4298,12 @@ getActiveLiveLocationMessages = Messages; //@description Returns the last message sent in a chat no later than the specified date @chat_id Chat identifier @date Point in time (Unix timestamp) relative to which to search for messages getChatMessageByDate chat_id:int53 date:int32 = Message; -//@description Returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. Returns the results in reverse chronological order (i.e., in order of decreasing message_id) +//@description Returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. Returns the results in reverse chronological order (i.e., in order of decreasing message_id). +//-Cannot be used in secret chats or with searchMessagesFilterFailedToSend filter without an enabled message database //@chat_id Identifier of the chat in which to return information about message positions -//@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention, searchMessagesFilterUnreadMention and searchMessagesFilterFailedToSend are unsupported in this function +//@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention and searchMessagesFilterUnreadMention are unsupported in this function //@from_message_id The message identifier from which to return information about message positions -//@limit The expected number of message positions to be returned. A smaller number of positions can be returned, if there are not enough appropriate messages +//@limit The expected number of message positions to be returned; 50-2000. A smaller number of positions can be returned, if there are not enough appropriate messages getChatSparseMessagePositions chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 limit:int32 = MessagePositions; //@description Returns information about the next messages of the specified type in the chat splitted by days. Returns the results in reverse chronological order. Can return partial result for the last returned day diff --git a/td/telegram/MessagesDb.cpp b/td/telegram/MessagesDb.cpp index d42b31e22..841cac167 100644 --- a/td/telegram/MessagesDb.cpp +++ b/td/telegram/MessagesDb.cpp @@ -230,6 +230,12 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { "ORDER BY rowid DESC LIMIT ?3) ORDER BY search_id DESC")); for (int32 i = 0; i < MESSAGES_DB_INDEX_COUNT; i++) { + TRY_RESULT_ASSIGN( + get_message_ids_stmts_[i], + db_.get_statement( + PSLICE() << "SELECT message_id FROM messages WHERE dialog_id = ?1 AND message_id < ?2 AND (index_mask & " + << (1 << i) << ") != 0 ORDER BY message_id DESC LIMIT 1000000")); + TRY_RESULT_ASSIGN( get_messages_from_index_stmts_[i].desc_stmt_, db_.get_statement( @@ -469,16 +475,16 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { return Status::Error("Not found"); } MessageId received_message_id(stmt.view_int64(0)); - MessagesDbDialogMessage result{received_message_id, BufferSlice(stmt.view_blob(1))}; + Slice data = stmt.view_blob(1); if (is_scheduled_server) { CHECK(received_message_id.is_scheduled()); CHECK(received_message_id.is_scheduled_server()); CHECK(received_message_id.get_scheduled_server_message_id() == message_id.get_scheduled_server_message_id()); } else { LOG_CHECK(received_message_id == message_id) - << received_message_id << ' ' << message_id << ' ' << get_message_info(result, true).first; + << received_message_id << ' ' << message_id << ' ' << get_message_info(received_message_id, data, true).first; } - return std::move(result); + return MessagesDbDialogMessage{received_message_id, BufferSlice(data)}; } Result get_message_by_unique_message_id(ServerMessageId unique_message_id) final { @@ -643,6 +649,37 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { return MessagesDbCalendar{std::move(messages), std::move(total_counts)}; } + Result get_dialog_sparse_message_positions( + MessagesDbGetDialogSparseMessagePositionsQuery query) final { + auto &stmt = get_message_ids_stmts_[message_search_filter_index(query.filter)]; + SCOPE_EXIT { + stmt.reset(); + }; + stmt.bind_int64(1, query.dialog_id.get()).ensure(); + stmt.bind_int64(2, query.from_message_id.get()).ensure(); + + vector message_ids; + stmt.step().ensure(); + while (stmt.has_row()) { + message_ids.push_back(MessageId(stmt.view_int64(0))); + stmt.step().ensure(); + } + + int32 limit = min(query.limit, static_cast(message_ids.size())); + double delta = static_cast(message_ids.size()) / limit; + vector positions; + positions.reserve(limit); + for (int32 i = 0; i < limit; i++) { + auto position = static_cast((i + 0.5) * delta); + auto message_id = message_ids[position]; + TRY_RESULT(message, get_message({query.dialog_id, message_id})); + auto date = get_message_info(message).second; + positions.push_back(MessagesDbMessagePosition{position, date, message_id}); + } + + return MessagesDbMessagePositions{static_cast(message_ids.size()), std::move(positions)}; + } + Result> get_messages(MessagesDbMessagesQuery query) final { if (query.filter != MessageSearchFilter::Empty) { return get_messages_from_index(query.dialog_id, query.from_message_id, query.filter, query.offset, query.limit); @@ -836,6 +873,7 @@ class MessagesDbImpl final : public MessagesDbSyncInterface { SqliteStatement get_scheduled_messages_stmt_; SqliteStatement get_messages_from_notification_id_stmt_; + std::array get_message_ids_stmts_; std::array get_messages_from_index_stmts_; std::array get_calls_stmts_; @@ -1020,6 +1058,11 @@ class MessagesDbAsync final : public MessagesDbAsyncInterface { send_closure_later(impl_, &Impl::get_dialog_message_calendar, std::move(query), std::move(promise)); } + void get_dialog_sparse_message_positions(MessagesDbGetDialogSparseMessagePositionsQuery query, + Promise promise) final { + send_closure_later(impl_, &Impl::get_dialog_sparse_message_positions, std::move(query), std::move(promise)); + } + void get_messages(MessagesDbMessagesQuery query, Promise> promise) final { send_closure_later(impl_, &Impl::get_messages, std::move(query), std::move(promise)); } @@ -1116,6 +1159,12 @@ class MessagesDbAsync final : public MessagesDbAsyncInterface { promise.set_result(sync_db_->get_dialog_message_calendar(std::move(query))); } + void get_dialog_sparse_message_positions(MessagesDbGetDialogSparseMessagePositionsQuery query, + Promise promise) { + add_read_query(); + promise.set_result(sync_db_->get_dialog_sparse_message_positions(std::move(query))); + } + void get_messages(MessagesDbMessagesQuery query, Promise> promise) { add_read_query(); promise.set_result(sync_db_->get_messages(std::move(query))); diff --git a/td/telegram/MessagesDb.h b/td/telegram/MessagesDb.h index 30139a35a..f2017db93 100644 --- a/td/telegram/MessagesDb.h +++ b/td/telegram/MessagesDb.h @@ -58,6 +58,24 @@ struct MessagesDbCalendar { vector total_counts; }; +struct MessagesDbGetDialogSparseMessagePositionsQuery { + DialogId dialog_id; + MessageSearchFilter filter{MessageSearchFilter::Empty}; + MessageId from_message_id; + int32 limit{0}; +}; + +struct MessagesDbMessagePosition { + int32 position{0}; + int32 date{0}; + MessageId message_id; +}; + +struct MessagesDbMessagePositions { + int32 total_count{0}; + vector positions; +}; + struct MessagesDbFtsQuery { string query; DialogId dialog_id; @@ -104,6 +122,9 @@ class MessagesDbSyncInterface { virtual Result get_dialog_message_calendar(MessagesDbDialogCalendarQuery query) = 0; + virtual Result get_dialog_sparse_message_positions( + MessagesDbGetDialogSparseMessagePositionsQuery query) = 0; + virtual Result> get_messages(MessagesDbMessagesQuery query) = 0; virtual Result> get_scheduled_messages(DialogId dialog_id, int32 limit) = 0; virtual Result> get_messages_from_notification_id(DialogId dialog_id, @@ -158,6 +179,9 @@ class MessagesDbAsyncInterface { virtual void get_dialog_message_calendar(MessagesDbDialogCalendarQuery query, Promise promise) = 0; + virtual void get_dialog_sparse_message_positions(MessagesDbGetDialogSparseMessagePositionsQuery query, + Promise promise) = 0; + virtual void get_messages(MessagesDbMessagesQuery query, Promise> promise) = 0; virtual void get_scheduled_messages(DialogId dialog_id, int32 limit, Promise> promise) = 0; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 78156f76b..db172bff5 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -22763,11 +22763,13 @@ void MessagesManager::get_dialog_sparse_message_positions( if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); } + if (limit < 50 || limit > 2000) { // server-side limits + return promise.set_error(Status::Error(400, "Invalid limit specified")); + } if (filter == MessageSearchFilter::Empty || filter == MessageSearchFilter::Call || filter == MessageSearchFilter::MissedCall || filter == MessageSearchFilter::Mention || - filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::FailedToSend || - filter == MessageSearchFilter::Pinned) { + filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::Pinned) { return promise.set_error(Status::Error(400, "The filter is not supported")); } @@ -22784,6 +22786,34 @@ void MessagesManager::get_dialog_sparse_message_positions( from_message_id = from_message_id.get_next_server_message_id(); } + if (filter == MessageSearchFilter::FailedToSend || dialog_id.get_type() == DialogType::SecretChat) { + if (!G()->parameters().use_message_db) { + return promise.set_error(Status::Error(400, "Unsupported without message database")); + } + + LOG(INFO) << "Get sparse message positions from database"; + auto new_promise = + PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + + auto positions = result.move_as_ok(); + promise.set_value(td_api::make_object( + positions.total_count, transform(positions.positions, [](const MessagesDbMessagePosition &position) { + return td_api::make_object(position.position, position.message_id.get(), + position.date); + }))); + }); + MessagesDbGetDialogSparseMessagePositionsQuery db_query; + db_query.dialog_id = dialog_id; + db_query.filter = filter; + db_query.from_message_id = from_message_id; + db_query.limit = limit; + G()->td_db()->get_messages_db_async()->get_dialog_sparse_message_positions(db_query, std::move(new_promise)); + return; + } + switch (dialog_id.get_type()) { case DialogType::User: case DialogType::Chat: @@ -22792,7 +22822,6 @@ void MessagesManager::get_dialog_sparse_message_positions( ->send(dialog_id, filter, from_message_id, limit); break; case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Secret chats aren't supported")); case DialogType::None: default: UNREACHABLE(); From fd0de189f8426edc2abb61b762213e15ead56b97 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 17:17:08 +0300 Subject: [PATCH 53/82] Add pushMessageContentChatJoinByRequest. --- td/generate/scheme/td_api.tl | 3 +++ td/telegram/NotificationManager.cpp | 3 +++ td/telegram/NotificationType.cpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5fa99fc85..cbb074d76 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2933,6 +2933,9 @@ pushMessageContentChatDeleteMember member_name:string is_current_user:Bool is_le //@description A new member joined the chat by invite link pushMessageContentChatJoinByLink = PushMessageContent; +//@description A new member was accepted to the chat by an administrator +pushMessageContentChatJoinByRequest = PushMessageContent; + //@description A forwarded messages @total_count Number of forwarded messages pushMessageContentMessageForwards total_count:int32 = PushMessageContent; diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 2c03f9ac5..7aa8fddb6 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -2911,6 +2911,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "CHAT_ADD_YOU") { return "MESSAGE_CHAT_ADD_MEMBERS_YOU"; } + if (loc_key == "CHAT_REQ_JOINED") { + return "MESSAGE_CHAT_JOIN_BY_REQUEST"; + } break; } return string(); diff --git a/td/telegram/NotificationType.cpp b/td/telegram/NotificationType.cpp index a50f11fdc..459fcfd7b 100644 --- a/td/telegram/NotificationType.cpp +++ b/td/telegram/NotificationType.cpp @@ -213,6 +213,9 @@ class NotificationTypePushMessage final : public NotificationType { if (key == "MESSAGE_CHAT_JOIN_BY_LINK") { return td_api::make_object(); } + if (key == "MESSAGE_CHAT_JOIN_BY_REQUEST") { + return td_api::make_object(); + } if (key == "MESSAGE_CONTACT") { return td_api::make_object(arg, is_pinned); } From a4592bd522fa2e691a7da9b07ad7f522536d7cca Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 17:22:42 +0300 Subject: [PATCH 54/82] Add messageChatJoinByRequest. --- td/generate/scheme/td_api.tl | 7 +++++-- td/telegram/MessageContent.cpp | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index cbb074d76..521a5410b 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1801,8 +1801,11 @@ messageChatDeletePhoto = MessageContent; //@description New chat members were added @member_user_ids User identifiers of the new members messageChatAddMembers member_user_ids:vector = MessageContent; -//@description A new member joined the chat by invite link @is_approved True, if the join request was approved by a chat administrator -messageChatJoinByLink is_approved:Bool = MessageContent; +//@description A new member joined the chat by invite link +messageChatJoinByLink = MessageContent; + +//@description A new member was accepted to the chat by an administrator +messageChatJoinByRequest = MessageContent; //@description A chat member was deleted @user_id User identifier of the deleted chat member messageChatDeleteMember user_id:int53 = MessageContent; diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 0d38a6bd1..2a8f6f427 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -4887,7 +4887,10 @@ tl_object_ptr get_message_content_object(const MessageCo } case MessageContentType::ChatJoinedByLink: { const MessageChatJoinedByLink *m = static_cast(content); - return make_tl_object(m->is_approved); + if (m->is_approved) { + return make_tl_object(); + } + return make_tl_object(); } case MessageContentType::ChatDeleteUser: { const auto *m = static_cast(content); From 5e43075d3b99c58b2566e1b9d5c189487e3bfc1f Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 18:59:35 +0300 Subject: [PATCH 55/82] Add TlStorerToString::store_object_field method. --- td/generate/tl_writer_cpp.cpp | 4 ++-- td/generate/tl_writer_jni_cpp.cpp | 4 ++-- tdutils/td/utils/tl_storers.h | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/td/generate/tl_writer_cpp.cpp b/td/generate/tl_writer_cpp.cpp index ea478ff1a..f635ec741 100644 --- a/td/generate/tl_writer_cpp.cpp +++ b/td/generate/tl_writer_cpp.cpp @@ -404,8 +404,8 @@ std::string TD_TL_writer_cpp::gen_type_store(const std::string &field_name, cons return gen_vector_store(field_name, child, vars, storer_type); } else { assert(tree_type->children.empty()); - return "if (" + field_name + " == nullptr) { s.store_field(\"" + get_pretty_field_name(field_name) + - "\", \"null\"); } else { " + field_name + "->store(s, \"" + get_pretty_field_name(field_name) + "\"); }"; + return "s.store_object_field(\"" + get_pretty_field_name(field_name) + "\", static_cast(" + + field_name + ".get()));"; } } diff --git a/td/generate/tl_writer_jni_cpp.cpp b/td/generate/tl_writer_jni_cpp.cpp index d28c582ac..330194e62 100644 --- a/td/generate/tl_writer_jni_cpp.cpp +++ b/td/generate/tl_writer_jni_cpp.cpp @@ -322,8 +322,8 @@ std::string TD_TL_writer_jni_cpp::gen_type_store(const std::string &field_name, res = gen_vector_store(field_name, child, vars, storer_type); } else { if (storer_type == 1) { - res = "if (" + field_name + " == nullptr) { s.store_field(\"" + get_pretty_field_name(field_name) + - "\", \"null\"); } else { " + field_name + "->store(s, \"" + get_pretty_field_name(field_name) + "\"); }"; + res = "s.store_object_field(\"" + get_pretty_field_name(field_name) + "\", static_cast(" + + field_name + ".get()));"; } else { res = "if (" + field_name + " != nullptr) { jobject next; " + field_name + "->store(env, next); if (next) { env->SetObjectField(s, " + field_name + diff --git a/tdutils/td/utils/tl_storers.h b/tdutils/td/utils/tl_storers.h index 0865088dd..72d049365 100644 --- a/tdutils/td/utils/tl_storers.h +++ b/tdutils/td/utils/tl_storers.h @@ -257,6 +257,15 @@ class TlStorerToString { store_field_end(); } + template + void store_object_field(const char *name, const ObjectT *value) { + if (value == nullptr) { + store_field(name, "null"); + } else { + value->store(*this, name); + } + } + void store_field(const char *name, const UInt128 &value) { store_field_begin(name); store_binary(as_slice(value)); From f743c782bf63cbca149193501b8bb44f88a1d118 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 19:21:24 +0300 Subject: [PATCH 56/82] Move TlStorerToString to TlStorerToString.h. --- td/generate/tl_writer_c.h | 1 - td/generate/tl_writer_cpp.cpp | 3 +- td/telegram/UpdatesManager.h | 1 + tdutils/td/utils/TlDowncastHelper.h | 2 +- tdutils/td/utils/TlStorerToString.h | 171 ++++++++++++++++++++++++++++ tdutils/td/utils/tl_storers.h | 158 +------------------------ 6 files changed, 176 insertions(+), 160 deletions(-) create mode 100644 tdutils/td/utils/TlStorerToString.h diff --git a/td/generate/tl_writer_c.h b/td/generate/tl_writer_c.h index 030afe620..e31bc969c 100644 --- a/td/generate/tl_writer_c.h +++ b/td/generate/tl_writer_c.h @@ -276,7 +276,6 @@ class TlWriterCCommon final : public tl::TL_writer { "#include \"td/utils/logging.h\"\n" "#include \"td/utils/misc.h\"\n" "#include \"td/utils/Slice.h\"\n" - "#include \"td/utils/tl_storers.h\"\n" "\n"; } std::string gen_output_end() const final { diff --git a/td/generate/tl_writer_cpp.cpp b/td/generate/tl_writer_cpp.cpp index f635ec741..daa860786 100644 --- a/td/generate/tl_writer_cpp.cpp +++ b/td/generate/tl_writer_cpp.cpp @@ -26,6 +26,7 @@ std::string TD_TL_writer_cpp::gen_output_begin() const { "#include \"td/utils/SliceBuilder.h\"\n" "#include \"td/utils/tl_parsers.h\"\n" "#include \"td/utils/tl_storers.h\"\n\n" + "#include \"td/utils/TlStorerToString.h\"\n\n" "namespace td {\n" "namespace " + tl_name + @@ -33,7 +34,7 @@ std::string TD_TL_writer_cpp::gen_output_begin() const { "std::string to_string(const BaseObject &value) {\n" " TlStorerToString storer;\n" " value.store(storer, \"\");\n" - " return storer.move_as_str();\n" + " return storer.move_as_string();\n" "}\n"; } diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index cdbed6c6d..96a619498 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -23,6 +23,7 @@ #include "td/utils/logging.h" #include "td/utils/Status.h" #include "td/utils/tl_storers.h" +#include "td/utils/TlStorerToString.h" #include #include diff --git a/tdutils/td/utils/TlDowncastHelper.h b/tdutils/td/utils/TlDowncastHelper.h index 4ca64db64..173b77431 100644 --- a/tdutils/td/utils/TlDowncastHelper.h +++ b/tdutils/td/utils/TlDowncastHelper.h @@ -7,7 +7,7 @@ #pragma once #include "td/utils/common.h" -#include "td/utils/tl_storers.h" +#include "td/utils/TlStorerToString.h" namespace td { diff --git a/tdutils/td/utils/TlStorerToString.h b/tdutils/td/utils/TlStorerToString.h new file mode 100644 index 000000000..68b74bea7 --- /dev/null +++ b/tdutils/td/utils/TlStorerToString.h @@ -0,0 +1,171 @@ +// +// 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/utils/common.h" +#include "td/utils/Slice.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/UInt.h" + +namespace td { + +class TlStorerToString { + string result; + size_t shift = 0; + + void store_field_begin(const char *name) { + result.append(shift, ' '); + if (name && name[0]) { + result += name; + result += " = "; + } + } + + void store_field_end() { + result += '\n'; + } + + void store_long(int64 value) { + result += (PSLICE() << value).c_str(); + } + + void store_binary(Slice data) { + static const char *hex = "0123456789ABCDEF"; + + result.append("{ ", 2); + for (auto c : data) { + unsigned char byte = c; + result += hex[byte >> 4]; + result += hex[byte & 15]; + result += ' '; + } + result += '}'; + } + + public: + TlStorerToString() = default; + TlStorerToString(const TlStorerToString &other) = delete; + TlStorerToString &operator=(const TlStorerToString &other) = delete; + + void store_field(const char *name, bool value) { + store_field_begin(name); + result += (value ? "true" : "false"); + store_field_end(); + } + + void store_field(const char *name, int32 value) { + store_field(name, static_cast(value)); + } + + void store_field(const char *name, int64 value) { + store_field_begin(name); + store_long(value); + store_field_end(); + } + + void store_field(const char *name, double value) { + store_field_begin(name); + result += (PSLICE() << value).c_str(); + store_field_end(); + } + + void store_field(const char *name, const char *value) { + store_field_begin(name); + result += value; + store_field_end(); + } + + void store_field(const char *name, const string &value) { + store_field_begin(name); + result += '"'; + result += value; + result += '"'; + store_field_end(); + } + + void store_field(const char *name, const SecureString &value) { + store_field_begin(name); + result.append(""); + store_field_end(); + } + + template + void store_field(const char *name, const T &value) { + store_field_begin(name); + result.append(value.data(), value.size()); + store_field_end(); + } + + void store_bytes_field(const char *name, const SecureString &value) { + store_field_begin(name); + result.append(""); + store_field_end(); + } + + template + void store_bytes_field(const char *name, const BytesT &value) { + static const char *hex = "0123456789ABCDEF"; + + store_field_begin(name); + result.append("bytes ["); + store_long(static_cast(value.size())); + result.append("] { "); + size_t len = min(static_cast(64), value.size()); + for (size_t i = 0; i < len; i++) { + int b = value[static_cast(i)] & 0xff; + result += hex[b >> 4]; + result += hex[b & 15]; + result += ' '; + } + if (len < value.size()) { + result.append("..."); + } + result += '}'; + store_field_end(); + } + + template + void store_object_field(const char *name, const ObjectT *value) { + if (value == nullptr) { + store_field(name, "null"); + } else { + value->store(*this, name); + } + } + + void store_field(const char *name, const UInt128 &value) { + store_field_begin(name); + store_binary(as_slice(value)); + store_field_end(); + } + + void store_field(const char *name, const UInt256 &value) { + store_field_begin(name); + store_binary(as_slice(value)); + store_field_end(); + } + + void store_class_begin(const char *field_name, const char *class_name) { + store_field_begin(field_name); + result += class_name; + result += " {\n"; + shift += 2; + } + + void store_class_end() { + CHECK(shift >= 2); + shift -= 2; + result.append(shift, ' '); + result += "}\n"; + } + + string move_as_string() { + return std::move(result); + } +}; + +} // namespace td diff --git a/tdutils/td/utils/tl_storers.h b/tdutils/td/utils/tl_storers.h index 72d049365..c8920547b 100644 --- a/tdutils/td/utils/tl_storers.h +++ b/tdutils/td/utils/tl_storers.h @@ -10,9 +10,7 @@ #include "td/utils/logging.h" #include "td/utils/SharedSlice.h" #include "td/utils/Slice.h" -#include "td/utils/SliceBuilder.h" #include "td/utils/StorerBase.h" -#include "td/utils/UInt.h" #include @@ -46,6 +44,7 @@ class TlStorerUnsafe { std::memcpy(buf_, slice.begin(), slice.size()); buf_ += slice.size(); } + void store_storer(const Storer &storer) { size_t size = storer.store(buf_); buf_ += size; @@ -142,161 +141,6 @@ class TlStorerCalcLength { } }; -class TlStorerToString { - std::string result; - size_t shift = 0; - - void store_field_begin(const char *name) { - result.append(shift, ' '); - if (name && name[0]) { - result += name; - result += " = "; - } - } - - void store_field_end() { - result += '\n'; - } - - void store_long(int64 value) { - result += (PSLICE() << value).c_str(); - } - - void store_binary(Slice data) { - static const char *hex = "0123456789ABCDEF"; - - result.append("{ ", 2); - for (auto c : data) { - unsigned char byte = c; - result += hex[byte >> 4]; - result += hex[byte & 15]; - result += ' '; - } - result += '}'; - } - - public: - TlStorerToString() = default; - TlStorerToString(const TlStorerToString &other) = delete; - TlStorerToString &operator=(const TlStorerToString &other) = delete; - - void store_field(const char *name, bool value) { - store_field_begin(name); - result += (value ? "true" : "false"); - store_field_end(); - } - - void store_field(const char *name, int32 value) { - store_field(name, static_cast(value)); - } - - void store_field(const char *name, int64 value) { - store_field_begin(name); - store_long(value); - store_field_end(); - } - - void store_field(const char *name, double value) { - store_field_begin(name); - result += (PSLICE() << value).c_str(); - store_field_end(); - } - - void store_field(const char *name, const char *value) { - store_field_begin(name); - result += value; - store_field_end(); - } - - void store_field(const char *name, const string &value) { - store_field_begin(name); - result += '"'; - result += value; - result += '"'; - store_field_end(); - } - - void store_field(const char *name, const SecureString &value) { - store_field_begin(name); - result.append(""); - store_field_end(); - } - - template - void store_field(const char *name, const T &value) { - store_field_begin(name); - result.append(value.data(), value.size()); - store_field_end(); - } - - void store_bytes_field(const char *name, const SecureString &value) { - store_field_begin(name); - result.append(""); - store_field_end(); - } - - template - void store_bytes_field(const char *name, const BytesT &value) { - static const char *hex = "0123456789ABCDEF"; - - store_field_begin(name); - result.append("bytes ["); - store_long(static_cast(value.size())); - result.append("] { "); - size_t len = min(static_cast(64), value.size()); - for (size_t i = 0; i < len; i++) { - int b = value[static_cast(i)] & 0xff; - result += hex[b >> 4]; - result += hex[b & 15]; - result += ' '; - } - if (len < value.size()) { - result.append("..."); - } - result += '}'; - store_field_end(); - } - - template - void store_object_field(const char *name, const ObjectT *value) { - if (value == nullptr) { - store_field(name, "null"); - } else { - value->store(*this, name); - } - } - - void store_field(const char *name, const UInt128 &value) { - store_field_begin(name); - store_binary(as_slice(value)); - store_field_end(); - } - - void store_field(const char *name, const UInt256 &value) { - store_field_begin(name); - store_binary(as_slice(value)); - store_field_end(); - } - - void store_class_begin(const char *field_name, const char *class_name) { - store_field_begin(field_name); - result += class_name; - result += " {\n"; - shift += 2; - } - - void store_class_end() { - CHECK(shift >= 2); - shift -= 2; - result.append(shift, ' '); - result += "}\n"; - } - - std::string move_as_str() { - return std::move(result); - } -}; - template size_t tl_calc_length(const T &data) { TlStorerCalcLength storer_calc_length; From 6e8a88be3552dfb11906d1efd9ae0cc6afe572bd Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 19:45:55 +0300 Subject: [PATCH 57/82] Add TlStorerTotString.store_vector_begin. --- td/generate/tl_writer_cpp.cpp | 16 +++++----------- tdutils/td/utils/TlStorerToString.h | 8 ++++++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/td/generate/tl_writer_cpp.cpp b/td/generate/tl_writer_cpp.cpp index daa860786..ed65208e9 100644 --- a/td/generate/tl_writer_cpp.cpp +++ b/td/generate/tl_writer_cpp.cpp @@ -284,7 +284,7 @@ std::string TD_TL_writer_cpp::gen_var_type_fetch(const tl::arg &a) const { } std::string TD_TL_writer_cpp::get_pretty_field_name(std::string field_name) const { - if (!field_name.empty() && field_name.back() == ']') { + if (!field_name.empty() && field_name[0] == '_') { return ""; } auto equals_pos = field_name.find('='); @@ -306,16 +306,10 @@ std::string TD_TL_writer_cpp::get_pretty_class_name(std::string class_name) cons std::string TD_TL_writer_cpp::gen_vector_store(const std::string &field_name, const tl::tl_tree_type *t, const std::vector &vars, int storer_type) const { - std::string num = field_name.back() == ']' ? "2" : ""; - return "{ const array<" + gen_type_name(t) + "> &v" + num + " = " + field_name + - "; const std::uint32_t multiplicity" + num + " = static_cast(v" + num + - ".size()); const auto vector_name" + num + " = \"" + get_pretty_class_name("vector") + - "[\" + td::to_string(multiplicity" + num + ")+ \"]\"; s.store_class_begin(\"" + - get_pretty_field_name(field_name) + "\", vector_name" + num + - ".c_str()); " - "for (std::uint32_t i" + - num + " = 0; i" + num + " < multiplicity" + num + "; i" + num + "++) { " + - gen_type_store("v" + num + "[i" + num + "]", t, vars, storer_type) + " } s.store_class_end(); }"; + std::string num = !field_name.empty() && field_name[0] == '_' ? "2" : ""; + return "{ s.store_vector_begin(\"" + get_pretty_field_name(field_name) + "\", " + field_name + + ".size()); for (const auto &_value" + num + " : " + field_name + ") { " + + gen_type_store("_value" + num, t, vars, storer_type) + " } s.store_class_end(); }"; } std::string TD_TL_writer_cpp::gen_store_class_name(const tl::tl_tree_type *tree_type) const { diff --git a/tdutils/td/utils/TlStorerToString.h b/tdutils/td/utils/TlStorerToString.h index 68b74bea7..512378c38 100644 --- a/tdutils/td/utils/TlStorerToString.h +++ b/tdutils/td/utils/TlStorerToString.h @@ -149,6 +149,14 @@ class TlStorerToString { store_field_end(); } + void store_vector_begin(const char *field_name, size_t vector_size) { + store_field_begin(field_name); + result += "vector["; + result += (PSLICE() << vector_size).c_str(); + result += "] {\n"; + shift += 2; + } + void store_class_begin(const char *field_name, const char *class_name) { store_field_begin(field_name); result += class_name; From 0522ba178a3b0bef456ffc2d1549b810a0086513 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 20:02:24 +0300 Subject: [PATCH 58/82] Remove TlStoreTrue. --- td/generate/tl_writer_cpp.cpp | 12 ++++++++++-- td/tl/tl_object_store.h | 8 -------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/td/generate/tl_writer_cpp.cpp b/td/generate/tl_writer_cpp.cpp index ed65208e9..9853d5130 100644 --- a/td/generate/tl_writer_cpp.cpp +++ b/td/generate/tl_writer_cpp.cpp @@ -25,7 +25,7 @@ std::string TD_TL_writer_cpp::gen_output_begin() const { "#include \"td/utils/logging.h\"\n" "#include \"td/utils/SliceBuilder.h\"\n" "#include \"td/utils/tl_parsers.h\"\n" - "#include \"td/utils/tl_storers.h\"\n\n" + "#include \"td/utils/tl_storers.h\"\n" "#include \"td/utils/TlStorerToString.h\"\n\n" "namespace td {\n" "namespace " + @@ -324,7 +324,8 @@ std::string TD_TL_writer_cpp::gen_store_class_name(const tl::tl_tree_type *tree_ return "TlStoreBool"; } if (name == "True") { - return "TlStoreTrue"; + assert(false); + return ""; } if (name == "String" || name == "Bytes") { return "TlStoreString"; @@ -438,6 +439,13 @@ std::string TD_TL_writer_cpp::gen_field_store(const tl::arg &a, std::vector= 0 && a.var_num < 0 && a.type->get_type() == tl::NODE_TYPE_TYPE) { + const tl::tl_tree_type *tree_type = static_cast(a.type); + if (tree_type->type->name == "True") { + return ""; + } + } + if (a.exist_var_num >= 0) { assert(a.exist_var_num < static_cast(vars.size())); assert(vars[a.exist_var_num].is_stored); diff --git a/td/tl/tl_object_store.h b/td/tl/tl_object_store.h index 191ec1418..196465ac8 100644 --- a/td/tl/tl_object_store.h +++ b/td/tl/tl_object_store.h @@ -47,14 +47,6 @@ class TlStoreBool { } }; -class TlStoreTrue { - public: - template - static void store(const bool &x, StorerT &storer) { - // currently nothing to do - } -}; - class TlStoreBinary { public: template From 4533f79338ef53dd120a78af12ee01ab994a774b Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 20:48:06 +0300 Subject: [PATCH 59/82] Don't generate MASK for parsed object/vector fields. --- td/generate/tl_writer_h.cpp | 25 +++++++++++++++++++++++-- td/generate/tl_writer_h.h | 4 +++- td/telegram/ContactsManager.cpp | 1 - td/telegram/MessageContent.cpp | 10 +++++----- td/telegram/MessagesManager.cpp | 2 +- td/telegram/NotificationManager.cpp | 3 --- tdtl/td/tl/tl_generate.cpp | 4 ++-- tdtl/td/tl/tl_writer.h | 2 +- 8 files changed, 35 insertions(+), 16 deletions(-) diff --git a/td/generate/tl_writer_h.cpp b/td/generate/tl_writer_h.cpp index a9285ac94..bf439a4f9 100644 --- a/td/generate/tl_writer_h.cpp +++ b/td/generate/tl_writer_h.cpp @@ -164,13 +164,34 @@ std::string TD_TL_writer_h::gen_function_vars(const tl::tl_combinator *t, return res; } -std::string TD_TL_writer_h::gen_flags_definitions(const tl::tl_combinator *t) const { +bool TD_TL_writer_h::need_arg_mask(const tl::arg &a, bool can_be_stored) const { + if (a.exist_var_num == -1) { + return false; + } + + if (can_be_stored) { + return true; + } + + if (a.type->get_type() != tl::NODE_TYPE_TYPE) { + return true; + } + const tl::tl_tree_type *tree_type = static_cast(a.type); + const std::string &name = tree_type->type->name; + + if (!is_built_in_simple_type(name)) { + return false; + } + return true; +} + +std::string TD_TL_writer_h::gen_flags_definitions(const tl::tl_combinator *t, bool can_be_stored) const { std::vector> flags; for (std::size_t i = 0; i < t->args.size(); i++) { const tl::arg &a = t->args[i]; - if (a.exist_var_num != -1) { + if (need_arg_mask(a, can_be_stored)) { auto name = a.name; for (auto &c : name) { c = to_upper(c); diff --git a/td/generate/tl_writer_h.h b/td/generate/tl_writer_h.h index c52125050..9e2538365 100644 --- a/td/generate/tl_writer_h.h +++ b/td/generate/tl_writer_h.h @@ -20,6 +20,8 @@ class TD_TL_writer_h : public TD_TL_writer { static std::string forward_declaration(std::string type); + bool need_arg_mask(const tl::arg &a, bool can_be_stored) const; + public: TD_TL_writer_h(const std::string &tl_name, const std::string &string_type, const std::string &bytes_type, const std::vector &ext_include) @@ -40,7 +42,7 @@ class TD_TL_writer_h : public TD_TL_writer { std::string gen_field_definition(const std::string &class_name, const std::string &type_name, const std::string &field_name) const override; - std::string gen_flags_definitions(const tl::tl_combinator *t) const override; + std::string gen_flags_definitions(const tl::tl_combinator *t, bool can_be_stored) const override; std::string gen_vars(const tl::tl_combinator *t, const tl::tl_tree_type *result_type, std::vector &vars) const override; std::string gen_function_vars(const tl::tl_combinator *t, std::vector &vars) const override; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index d03a52c71..331464044 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -8724,7 +8724,6 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) { telegram_api::object_ptr profile_photo; if (!G()->is_test_dc() && profile_photo_id != 0) { - flags |= telegram_api::user::PHOTO_MASK; profile_photo = telegram_api::make_object(0, false /*ignored*/, profile_photo_id, BufferSlice(), profile_photo_dc_id); } diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 2a8f6f427..5f670dac9 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -3848,9 +3848,9 @@ static auto secret_to_telegram_document(secret_api::decryptedMessageMediaExterna } vector> thumbnails; thumbnails.push_back(secret_to_telegram(*from.thumb_)); - return make_tl_object( - telegram_api::document::THUMBS_MASK, from.id_, from.access_hash_, BufferSlice(), from.date_, from.mime_type_, - from.size_, std::move(thumbnails), Auto(), from.dc_id_, secret_to_telegram(from.attributes_)); + return make_tl_object(0, from.id_, from.access_hash_, BufferSlice(), from.date_, + from.mime_type_, from.size_, std::move(thumbnails), Auto(), from.dc_id_, + secret_to_telegram(from.attributes_)); } template @@ -4116,7 +4116,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, return make_unique(std::move(message), WebPageId()); case telegram_api::messageMediaPhoto::ID: { auto message_photo = move_tl_object_as(media); - if ((message_photo->flags_ & telegram_api::messageMediaPhoto::PHOTO_MASK) == 0) { + if (message_photo->photo_ == nullptr) { if ((message_photo->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) == 0) { LOG(ERROR) << "Receive messageMediaPhoto without photo and TTL: " << oneline(to_string(message_photo)); break; @@ -4196,7 +4196,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, } case telegram_api::messageMediaDocument::ID: { auto message_document = move_tl_object_as(media); - if ((message_document->flags_ & telegram_api::messageMediaDocument::DOCUMENT_MASK) == 0) { + if (message_document->document_ == nullptr) { if ((message_document->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) == 0) { LOG(ERROR) << "Receive messageMediaDocument without document and TTL: " << oneline(to_string(message_document)); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index db172bff5..0d3b604fd 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -26621,7 +26621,7 @@ unique_ptr MessagesManager::get_message_for message_id = MessageId(); } } - if ((flags & telegram_api::messageFwdHeader::SAVED_FROM_PEER_MASK) != 0) { + if (forward_header->saved_from_peer_ != nullptr) { from_dialog_id = DialogId(forward_header->saved_from_peer_); from_message_id = MessageId(ServerMessageId(forward_header->saved_from_msg_id_)); if (!from_dialog_id.is_valid() || !from_message_id.is_valid()) { diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 7aa8fddb6..7208eb58a 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -3280,9 +3280,6 @@ Status NotificationManager::process_push_notification_payload(string payload, bo // set phone number flag to show that this is a full access hash flags |= telegram_api::user::ACCESS_HASH_MASK | telegram_api::user::PHONE_MASK; } - if (sender_photo != nullptr) { - flags |= telegram_api::user::PHOTO_MASK; - } auto user_name = sender_user_id.get() == 136817688 ? "Channel" : sender_name; auto user = telegram_api::make_object( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, diff --git a/tdtl/td/tl/tl_generate.cpp b/tdtl/td/tl/tl_generate.cpp index 1747bc5f0..6fe1cedae 100644 --- a/tdtl/td/tl/tl_generate.cpp +++ b/tdtl/td/tl/tl_generate.cpp @@ -248,7 +248,7 @@ static void write_function(tl_outputer &out, const tl_combinator *t, const std:: out.append(w.gen_class_begin(class_name, w.gen_base_function_class_name(), false)); int required_args = gen_field_definitions(out, t, class_name, w); - out.append(w.gen_flags_definitions(t)); + out.append(w.gen_flags_definitions(t, true)); std::vector vars(t->var_count); out.append(w.gen_function_vars(t, vars)); @@ -304,7 +304,6 @@ static void write_constructor(tl_outputer &out, const tl_combinator *t, const st out.append(w.gen_class_begin(class_name, base_class, is_proxy)); int required_args = gen_field_definitions(out, t, class_name, w); - out.append(w.gen_flags_definitions(t)); bool can_be_parsed = false; bool is_can_be_parsed_inited = false; @@ -334,6 +333,7 @@ static void write_constructor(tl_outputer &out, const tl_combinator *t, const st can_be_stored = true; } + out.append(w.gen_flags_definitions(t, can_be_stored)); if (w.is_default_constructor_generated(t, can_be_parsed, can_be_stored)) { write_class_constructor(out, t, class_name, true, w); } diff --git a/tdtl/td/tl/tl_writer.h b/tdtl/td/tl/tl_writer.h index 06dd9640f..f8724851f 100644 --- a/tdtl/td/tl/tl_writer.h +++ b/tdtl/td/tl/tl_writer.h @@ -96,7 +96,7 @@ class TL_writer { virtual std::string gen_field_definition(const std::string &class_name, const std::string &type_name, const std::string &field_name) const = 0; - virtual std::string gen_flags_definitions(const tl_combinator *t) const { + virtual std::string gen_flags_definitions(const tl_combinator *t, bool can_be_stored) const { return ""; } From 0c1e26870671fc24f5f7aebfcff60d0511f40749 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 21:53:23 +0300 Subject: [PATCH 60/82] Don't generate MASK for parsed True fields. --- td/generate/tl_writer_h.cpp | 6 ++--- td/telegram/AuthManager.cpp | 3 +-- td/telegram/BackgroundManager.cpp | 13 +++++------ td/telegram/CallActor.cpp | 10 ++++----- td/telegram/CallbackQueriesManager.cpp | 4 ++-- td/telegram/ConfigManager.cpp | 6 ++--- td/telegram/ContactsManager.cpp | 31 +++++++++++--------------- td/telegram/DialogParticipant.cpp | 10 ++++----- td/telegram/DraftMessage.cpp | 2 +- td/telegram/GroupCallParticipant.cpp | 2 +- td/telegram/LanguagePackManager.cpp | 6 ++--- td/telegram/LinkManager.cpp | 8 ++----- td/telegram/MessageContent.cpp | 6 ++--- td/telegram/MessagesManager.cpp | 24 +++++++++----------- td/telegram/NotificationManager.cpp | 6 ++--- td/telegram/NotificationManager.h | 4 ++++ td/telegram/PasswordManager.cpp | 5 ++--- td/telegram/Payments.cpp | 15 +++++-------- td/telegram/Photo.cpp | 14 +++++------- td/telegram/PollManager.cpp | 6 ++--- td/telegram/SecureValue.cpp | 7 +++--- td/telegram/StickersManager.cpp | 8 +++---- td/telegram/Td.cpp | 2 +- td/telegram/TermsOfService.cpp | 5 ++--- td/telegram/TopDialogCategory.cpp | 1 + td/telegram/UpdatesManager.cpp | 11 ++++----- td/telegram/WebPageBlock.cpp | 29 ++++++++++++------------ td/telegram/WebPagesManager.cpp | 6 ++--- 28 files changed, 111 insertions(+), 139 deletions(-) diff --git a/td/generate/tl_writer_h.cpp b/td/generate/tl_writer_h.cpp index bf439a4f9..3a4760ad9 100644 --- a/td/generate/tl_writer_h.cpp +++ b/td/generate/tl_writer_h.cpp @@ -179,7 +179,7 @@ bool TD_TL_writer_h::need_arg_mask(const tl::arg &a, bool can_be_stored) const { const tl::tl_tree_type *tree_type = static_cast(a.type); const std::string &name = tree_type->type->name; - if (!is_built_in_simple_type(name)) { + if (!is_built_in_simple_type(name) || name == "True") { return false; } return true; @@ -201,7 +201,7 @@ std::string TD_TL_writer_h::gen_flags_definitions(const tl::tl_combinator *t, bo } std::string res; if (!flags.empty()) { - res += " enum Flags : std::int32_t {"; + res += " enum Flags : std::int32_t { "; bool first = true; for (auto &p : flags) { if (first) { @@ -211,7 +211,7 @@ std::string TD_TL_writer_h::gen_flags_definitions(const tl::tl_combinator *t, bo } res += p.first + "_MASK = " + int_to_string(1 << p.second); } - res += "};\n"; + res += " };\n"; } return res; } diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index 77b1ca269..0a07619db 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -568,8 +568,7 @@ void AuthManager::on_get_password_result(NetQueryPtr &result) { wait_password_state_.srp_B_ = password->srp_B_.as_slice().str(); wait_password_state_.srp_id_ = password->srp_id_; wait_password_state_.hint_ = std::move(password->hint_); - wait_password_state_.has_recovery_ = - (password->flags_ & telegram_api::account_password::HAS_RECOVERY_MASK) != 0; + wait_password_state_.has_recovery_ = password->has_recovery_; break; } default: diff --git a/td/telegram/BackgroundManager.cpp b/td/telegram/BackgroundManager.cpp index b5e87c3a4..69556926c 100644 --- a/td/telegram/BackgroundManager.cpp +++ b/td/telegram/BackgroundManager.cpp @@ -1098,8 +1098,8 @@ std::pair BackgroundManager::on_get_background( Background background; background.id = background_id; background.is_creator = false; - background.is_default = (wallpaper->flags_ & telegram_api::wallPaperNoFile::DEFAULT_MASK) != 0; - background.is_dark = (wallpaper->flags_ & telegram_api::wallPaperNoFile::DARK_MASK) != 0; + background.is_default = wallpaper->default_; + background.is_dark = wallpaper->dark_; background.type = BackgroundType(true, false, std::move(wallpaper->settings_)); background.name = background.type.get_link(); add_background(background, replace_type); @@ -1124,8 +1124,7 @@ std::pair BackgroundManager::on_get_background( } CHECK(document_id == telegram_api::document::ID); - int32 flags = wallpaper->flags_; - bool is_pattern = (flags & telegram_api::wallPaper::PATTERN_MASK) != 0; + bool is_pattern = wallpaper->pattern_; Document document = td_->documents_manager_->on_get_document( telegram_api::move_object_as(wallpaper->document_), DialogId(), nullptr, @@ -1139,9 +1138,9 @@ std::pair BackgroundManager::on_get_background( Background background; background.id = background_id; background.access_hash = wallpaper->access_hash_; - background.is_creator = (flags & telegram_api::wallPaper::CREATOR_MASK) != 0; - background.is_default = (flags & telegram_api::wallPaper::DEFAULT_MASK) != 0; - background.is_dark = (flags & telegram_api::wallPaper::DARK_MASK) != 0; + background.is_creator = wallpaper->creator_; + background.is_default = wallpaper->default_; + background.is_dark = wallpaper->dark_; background.type = BackgroundType(false, is_pattern, std::move(wallpaper->settings_)); background.name = std::move(wallpaper->slug_); background.file_id = document.file_id; diff --git a/td/telegram/CallActor.cpp b/td/telegram/CallActor.cpp index d7e82d1a4..cefdcbcab 100644 --- a/td/telegram/CallActor.cpp +++ b/td/telegram/CallActor.cpp @@ -378,7 +378,7 @@ Status CallActor::do_update_call(telegram_api::phoneCallWaiting &call) { call_id_ = call.id_; call_access_hash_ = call.access_hash_; is_call_id_inited_ = true; - is_video_ |= (call.flags_ & telegram_api::phoneCallWaiting::VIDEO_MASK) != 0; + is_video_ |= call.video_; call_admin_user_id_ = UserId(call.admin_id_); // call_participant_user_id_ = UserId(call.participant_id_); if (call_id_promise_) { @@ -401,7 +401,7 @@ Status CallActor::do_update_call(telegram_api::phoneCallRequested &call) { call_id_ = call.id_; call_access_hash_ = call.access_hash_; is_call_id_inited_ = true; - is_video_ |= (call.flags_ & telegram_api::phoneCallRequested::VIDEO_MASK) != 0; + is_video_ |= call.video_; call_admin_user_id_ = UserId(call.admin_id_); // call_participant_user_id_ = UserId(call.participant_id_); if (call_id_promise_) { @@ -441,7 +441,7 @@ Status CallActor::do_update_call(telegram_api::phoneCallAccepted &call) { call_id_promise_.set_value(std::move(call.id_)); } } - is_video_ |= (call.flags_ & telegram_api::phoneCallAccepted::VIDEO_MASK) != 0; + is_video_ |= call.video_; dh_handshake_.set_g_a(call.g_b_.as_slice()); TRY_STATUS(dh_handshake_.run_checks(true, DhCache::instance())); std::tie(call_state_.key_fingerprint, call_state_.key) = dh_handshake_.gen_key(); @@ -465,7 +465,7 @@ Status CallActor::do_update_call(telegram_api::phoneCall &call) { } cancel_timeout(); - is_video_ |= (call.flags_ & telegram_api::phoneCall::VIDEO_MASK) != 0; + is_video_ |= call.video_; LOG(DEBUG) << "Do update call to Ready from state " << static_cast(state_); if (state_ == State::WaitAcceptResult) { @@ -484,7 +484,7 @@ Status CallActor::do_update_call(telegram_api::phoneCall &call) { call_state_.connections.emplace_back(*connection); } call_state_.protocol = CallProtocol(*call.protocol_); - call_state_.allow_p2p = (call.flags_ & telegram_api::phoneCall::P2P_ALLOWED_MASK) != 0; + call_state_.allow_p2p = call.p2p_allowed_; call_state_.type = CallState::Type::Ready; call_state_need_flush_ = true; diff --git a/td/telegram/CallbackQueriesManager.cpp b/td/telegram/CallbackQueriesManager.cpp index b640b9817..76b06f898 100644 --- a/td/telegram/CallbackQueriesManager.cpp +++ b/td/telegram/CallbackQueriesManager.cpp @@ -79,8 +79,8 @@ class GetBotCallbackAnswerQuery final : public Td::ResultHandler { } auto answer = result_ptr.move_as_ok(); - bool show_alert = (answer->flags_ & telegram_api::messages_botCallbackAnswer::ALERT_MASK) != 0; - promise_.set_value(td_api::make_object(answer->message_, show_alert, answer->url_)); + promise_.set_value( + td_api::make_object(answer->message_, answer->alert_, answer->url_)); } void on_error(uint64 id, Status status) final { diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 91b87d0db..df2fc0b40 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -1369,8 +1369,7 @@ void ConfigManager::process_config(tl_object_ptr config) { shared_config.set_option_integer("pinned_chat_count_max", config->pinned_dialogs_count_max_); shared_config.set_option_integer("pinned_archived_chat_count_max", config->pinned_infolder_count_max_); if (is_from_main_dc || !shared_config.have_option("expect_blocking")) { - shared_config.set_option_boolean("expect_blocking", - (config->flags_ & telegram_api::config::BLOCKED_MODE_MASK) != 0); + shared_config.set_option_boolean("expect_blocking", config->blocked_mode_); } if (is_from_main_dc || !shared_config.have_option("dc_txt_domain_name")) { shared_config.set_option_string("dc_txt_domain_name", config->dc_txt_domain_name_); @@ -1404,8 +1403,7 @@ void ConfigManager::process_config(tl_object_ptr config) { if (is_from_main_dc) { shared_config.set_option_integer("edit_time_limit", config->edit_time_limit_); - shared_config.set_option_boolean("revoke_pm_inbox", - (config->flags_ & telegram_api::config::REVOKE_PM_INBOX_MASK) != 0); + shared_config.set_option_boolean("revoke_pm_inbox", config->revoke_pm_inbox_); shared_config.set_option_integer("revoke_time_limit", config->revoke_time_limit_); shared_config.set_option_integer("revoke_pm_time_limit", config->revoke_pm_time_limit_); diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 331464044..16271b133 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -5307,15 +5307,11 @@ void ContactsManager::get_account_ttl(Promise &&promise) const { td_api::object_ptr ContactsManager::convert_authorization_object( tl_object_ptr &&authorization) { CHECK(authorization != nullptr); - bool is_current = (authorization->flags_ & telegram_api::authorization::CURRENT_MASK) != 0; - bool is_official_application = (authorization->flags_ & telegram_api::authorization::OFFICIAL_APP_MASK) != 0; - bool is_password_pending = (authorization->flags_ & telegram_api::authorization::PASSWORD_PENDING_MASK) != 0; - return td_api::make_object( - authorization->hash_, is_current, is_password_pending, authorization->api_id_, authorization->app_name_, - authorization->app_version_, is_official_application, authorization->device_model_, authorization->platform_, - authorization->system_version_, authorization->date_created_, authorization->date_active_, authorization->ip_, - authorization->country_, authorization->region_); + authorization->hash_, authorization->current_, authorization->password_pending_, authorization->api_id_, + authorization->app_name_, authorization->app_version_, authorization->official_app_, authorization->device_model_, + authorization->platform_, authorization->system_version_, authorization->date_created_, + authorization->date_active_, authorization->ip_, authorization->country_, authorization->region_); } void ContactsManager::confirm_qr_code_authentication(const string &link, @@ -8684,8 +8680,7 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) { if ((u == nullptr || !u->is_received) && (user_id == get_service_notifications_user_id() || user_id == get_replies_bot_user_id() || user_id == get_anonymous_bot_user_id())) { - int32 flags = telegram_api::user::ACCESS_HASH_MASK | telegram_api::user::FIRST_NAME_MASK | - telegram_api::user::APPLY_MIN_PHOTO_MASK; + int32 flags = USER_FLAG_HAS_ACCESS_HASH | USER_FLAG_HAS_FIRST_NAME | USER_FLAG_NEED_APPLY_MIN_PHOTO; int64 profile_photo_id = 0; int32 profile_photo_dc_id = 1; string first_name; @@ -8695,26 +8690,26 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) { int32 bot_info_version = 0; if (user_id == get_service_notifications_user_id()) { - flags |= telegram_api::user::PHONE_MASK | telegram_api::user::VERIFIED_MASK | telegram_api::user::SUPPORT_MASK; + flags |= USER_FLAG_HAS_PHONE_NUMBER | USER_FLAG_IS_VERIFIED | USER_FLAG_IS_SUPPORT; first_name = "Telegram"; if (G()->is_test_dc()) { - flags |= telegram_api::user::LAST_NAME_MASK; + flags |= USER_FLAG_HAS_LAST_NAME; last_name = "Notifications"; } phone_number = "42777"; profile_photo_id = 3337190045231023; } else if (user_id == get_replies_bot_user_id()) { - flags |= telegram_api::user::USERNAME_MASK | telegram_api::user::BOT_MASK; + flags |= USER_FLAG_HAS_USERNAME | USER_FLAG_IS_BOT; if (!G()->is_test_dc()) { - flags |= telegram_api::user::BOT_NOCHATS_MASK; + flags |= USER_FLAG_IS_PRIVATE_BOT; } first_name = "Replies"; username = "replies"; bot_info_version = G()->is_test_dc() ? 1 : 3; } else if (user_id == get_anonymous_bot_user_id()) { - flags |= telegram_api::user::USERNAME_MASK | telegram_api::user::BOT_MASK; + flags |= USER_FLAG_HAS_USERNAME | USER_FLAG_IS_BOT; if (!G()->is_test_dc()) { - flags |= telegram_api::user::BOT_NOCHATS_MASK; + flags |= USER_FLAG_IS_PRIVATE_BOT; } first_name = "Group"; username = G()->is_test_dc() ? "izgroupbot" : "GroupAnonymousBot"; @@ -10374,8 +10369,8 @@ void ContactsManager::on_get_user_full(tl_object_ptr &&u } on_update_user_full_common_chat_count(user_full, user_id, user->common_chats_count_); - on_update_user_full_need_phone_number_privacy_exception( - user_full, user_id, (user->settings_->flags_ & telegram_api::peerSettings::NEED_CONTACTS_EXCEPTION_MASK) != 0); + on_update_user_full_need_phone_number_privacy_exception(user_full, user_id, + user->settings_->need_contacts_exception_); bool can_pin_messages = user->can_pin_message_; if (user_full->can_pin_messages != can_pin_messages) { diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index 25b4a0a2d..5fb684899 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -711,16 +711,15 @@ DialogParticipant::DialogParticipant(tl_object_ptr(participant_ptr); - bool is_anonymous = (participant->admin_rights_->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0; *this = {DialogId(UserId(participant->user_id_)), UserId(), 0, - DialogParticipantStatus::Creator(true, is_anonymous, std::move(participant->rank_))}; + DialogParticipantStatus::Creator(true, participant->admin_rights_->anonymous_, + std::move(participant->rank_))}; break; } case telegram_api::channelParticipantAdmin::ID: { auto participant = move_tl_object_as(participant_ptr); - bool can_be_edited = (participant->flags_ & telegram_api::channelParticipantAdmin::CAN_EDIT_MASK) != 0; *this = {DialogId(UserId(participant->user_id_)), UserId(participant->promoted_by_), participant->date_, - get_dialog_participant_status(can_be_edited, std::move(participant->admin_rights_), + get_dialog_participant_status(participant->can_edit_, std::move(participant->admin_rights_), std::move(participant->rank_))}; break; } @@ -731,9 +730,8 @@ DialogParticipant::DialogParticipant(tl_object_ptr(participant_ptr); - auto is_member = (participant->flags_ & telegram_api::channelParticipantBanned::LEFT_MASK) == 0; *this = {DialogId(participant->peer_), UserId(participant->kicked_by_), participant->date_, - get_dialog_participant_status(is_member, std::move(participant->banned_rights_))}; + get_dialog_participant_status(!participant->left_, std::move(participant->banned_rights_))}; break; } default: diff --git a/td/telegram/DraftMessage.cpp b/td/telegram/DraftMessage.cpp index ed2587019..f6ca4265f 100644 --- a/td/telegram/DraftMessage.cpp +++ b/td/telegram/DraftMessage.cpp @@ -55,7 +55,7 @@ unique_ptr get_draft_message(ContactsManager *contacts_manager, entities = find_entities(draft->message_, false, true); } result->input_message_text.text = FormattedText{std::move(draft->message_), std::move(entities)}; - result->input_message_text.disable_web_page_preview = (flags & telegram_api::draftMessage::NO_WEBPAGE_MASK) != 0; + result->input_message_text.disable_web_page_preview = draft->no_webpage_; result->input_message_text.clear_draft = false; return result; diff --git a/td/telegram/GroupCallParticipant.cpp b/td/telegram/GroupCallParticipant.cpp index d9fee5ab5..d0b1ba795 100644 --- a/td/telegram/GroupCallParticipant.cpp +++ b/td/telegram/GroupCallParticipant.cpp @@ -32,7 +32,7 @@ GroupCallParticipant::GroupCallParticipant(const tl_object_ptrflags_ & telegram_api::groupCallParticipant::VOLUME_BY_ADMIN_MASK) == 0; + is_volume_level_local = !participant->volume_by_admin_; } if (!participant->left_) { joined_date = participant->date_; diff --git a/td/telegram/LanguagePackManager.cpp b/td/telegram/LanguagePackManager.cpp index 6c1ccdcad..2378c2c2f 100644 --- a/td/telegram/LanguagePackManager.cpp +++ b/td/telegram/LanguagePackManager.cpp @@ -1605,9 +1605,9 @@ Result LanguagePackManager::get_language_info info.native_name_ = std::move(language->native_name_); info.base_language_code_ = std::move(language->base_lang_code_); info.plural_code_ = std::move(language->plural_code_); - info.is_official_ = (language->flags_ & telegram_api::langPackLanguage::OFFICIAL_MASK) != 0; - info.is_rtl_ = (language->flags_ & telegram_api::langPackLanguage::RTL_MASK) != 0; - info.is_beta_ = (language->flags_ & telegram_api::langPackLanguage::BETA_MASK) != 0; + info.is_official_ = language->official_; + info.is_rtl_ = language->rtl_; + info.is_beta_ = language->beta_; info.is_from_database_ = false; info.total_string_count_ = language->strings_count_; info.translated_string_count_ = language->translated_count_; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index f2dc217c5..299f52c2d 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -401,8 +401,6 @@ class GetDeepLinkInfoQuery final : public Td::ResultHandler { return promise_.set_value(nullptr); case telegram_api::help_deepLinkInfo::ID: { auto info = telegram_api::move_object_as(result); - bool need_update = (info->flags_ & telegram_api::help_deepLinkInfo::UPDATE_APP_MASK) != 0; - auto entities = get_message_entities(nullptr, std::move(info->entities_), "GetDeepLinkInfoQuery"); auto status = fix_formatted_text(info->message_, entities, true, true, true, true, true); if (status.is_error()) { @@ -414,7 +412,7 @@ class GetDeepLinkInfoQuery final : public Td::ResultHandler { } FormattedText text{std::move(info->message_), std::move(entities)}; return promise_.set_value( - td_api::make_object(get_formatted_text_object(text, true, -1), need_update)); + td_api::make_object(get_formatted_text_object(text, true, -1), info->update_app_)); } default: UNREACHABLE(); @@ -469,11 +467,9 @@ class RequestUrlAuthQuery final : public Td::ResultHandler { return on_error(id, Status::Error(500, "Receive invalid bot_user_id")); } td->contacts_manager_->on_get_user(std::move(request->bot_), "RequestUrlAuthQuery"); - bool request_write_access = - (request->flags_ & telegram_api::urlAuthResultRequest::REQUEST_WRITE_ACCESS_MASK) != 0; promise_.set_value(td_api::make_object( url_, request->domain_, td->contacts_manager_->get_user_id_object(bot_user_id, "RequestUrlAuthQuery"), - request_write_access)); + request->request_write_access_)); break; } case telegram_api::urlAuthResultAccepted::ID: { diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index 5f670dac9..ab78210d0 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -1512,8 +1512,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, break; } - result.disable_web_page_preview = - (inline_message->flags_ & telegram_api::botInlineMessageText::NO_WEBPAGE_MASK) != 0; + result.disable_web_page_preview = inline_message->no_webpage_; WebPageId web_page_id; if (!result.disable_web_page_preview) { web_page_id = td->web_pages_manager_->get_web_page_by_url(get_first_url(inline_message->message_, entities)); @@ -4635,13 +4634,12 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(action); auto duration = (phone_call->flags_ & telegram_api::messageActionPhoneCall::DURATION_MASK) != 0 ? phone_call->duration_ : 0; - auto is_video = (phone_call->flags_ & telegram_api::messageActionPhoneCall::VIDEO_MASK) != 0; if (duration < 0) { LOG(ERROR) << "Receive invalid " << oneline(to_string(phone_call)); break; } return make_unique(phone_call->call_id_, duration, get_call_discard_reason(phone_call->reason_), - is_video); + phone_call->video_); } case telegram_api::messageActionPaymentSent::ID: { if (td->auth_manager_->is_bot()) { diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 0d3b604fd..620c20bdf 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -6667,7 +6667,7 @@ void MessagesManager::on_update_service_notification(tl_object_ptrget_type()); - if ((update->flags_ & telegram_api::updateServiceNotification::POPUP_MASK) != 0) { + if (update->popup_) { send_closure(G()->td(), &Td::send_update, td_api::make_object( update->type_, get_message_content_object(content.get(), td_, owner_dialog_id, date, @@ -8474,10 +8474,8 @@ void MessagesManager::on_get_peer_settings(DialogId dialog_id, bool ignore_privacy_exception) { CHECK(peer_settings != nullptr); if (dialog_id.get_type() == DialogType::User && !ignore_privacy_exception) { - auto need_phone_number_privacy_exception = - (peer_settings->flags_ & telegram_api::peerSettings::NEED_CONTACTS_EXCEPTION_MASK) != 0; td_->contacts_manager_->on_update_user_need_phone_number_privacy_exception(dialog_id.get_user_id(), - need_phone_number_privacy_exception); + peer_settings->need_contacts_exception_); } Dialog *d = get_dialog_force(dialog_id, "on_get_peer_settings"); @@ -8485,15 +8483,15 @@ void MessagesManager::on_get_peer_settings(DialogId dialog_id, return; } - auto can_report_spam = (peer_settings->flags_ & telegram_api::peerSettings::REPORT_SPAM_MASK) != 0; - auto can_add_contact = (peer_settings->flags_ & telegram_api::peerSettings::ADD_CONTACT_MASK) != 0; - auto can_block_user = (peer_settings->flags_ & telegram_api::peerSettings::BLOCK_CONTACT_MASK) != 0; - auto can_share_phone_number = (peer_settings->flags_ & telegram_api::peerSettings::SHARE_CONTACT_MASK) != 0; - auto can_report_location = (peer_settings->flags_ & telegram_api::peerSettings::REPORT_GEO_MASK) != 0; - auto can_unarchive = (peer_settings->flags_ & telegram_api::peerSettings::AUTOARCHIVED_MASK) != 0; + auto can_report_spam = peer_settings->report_spam_; + auto can_add_contact = peer_settings->add_contact_; + auto can_block_user = peer_settings->block_contact_; + auto can_share_phone_number = peer_settings->share_contact_; + auto can_report_location = peer_settings->report_geo_; + auto can_unarchive = peer_settings->autoarchived_; auto distance = (peer_settings->flags_ & telegram_api::peerSettings::GEO_DISTANCE_MASK) != 0 ? peer_settings->geo_distance_ : -1; - auto can_invite_members = (peer_settings->flags_ & telegram_api::peerSettings::INVITE_MEMBERS_MASK) != 0; + auto can_invite_members = peer_settings->invite_members_; if (d->can_report_spam == can_report_spam && d->can_add_contact == can_add_contact && d->can_block_user == can_block_user && d->can_share_phone_number == can_share_phone_number && d->can_report_location == can_report_location && d->can_unarchive == can_unarchive && d->distance == distance && @@ -14875,7 +14873,7 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectorpts_, "get channel"); } } - bool is_marked_as_unread = (dialog->flags_ & telegram_api::dialog::UNREAD_MARK_MASK) != 0; + bool is_marked_as_unread = dialog->unread_mark_; if (is_marked_as_unread != d->is_marked_as_unread) { set_dialog_is_marked_as_unread(d, is_marked_as_unread); } @@ -37202,7 +37200,7 @@ void MessagesManager::on_get_channel_difference( on_update_dialog_notify_settings(dialog_id, std::move(dialog->notify_settings_), "updates.channelDifferenceTooLong"); - bool is_marked_as_unread = (dialog->flags_ & telegram_api::dialog::UNREAD_MARK_MASK) != 0; + bool is_marked_as_unread = dialog->unread_mark_; if (is_marked_as_unread != d->is_marked_as_unread) { set_dialog_is_marked_as_unread(d, is_marked_as_unread); } diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 7208eb58a..e746bc70f 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -3275,10 +3275,10 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } } - int32 flags = telegram_api::user::FIRST_NAME_MASK | telegram_api::user::MIN_MASK; + int32 flags = USER_FLAG_IS_INACCESSIBLE; if (sender_access_hash != -1) { // set phone number flag to show that this is a full access hash - flags |= telegram_api::user::ACCESS_HASH_MASK | telegram_api::user::PHONE_MASK; + flags |= USER_FLAG_HAS_ACCESS_HASH | USER_FLAG_HAS_PHONE_NUMBER; } auto user_name = sender_user_id.get() == 136817688 ? "Channel" : sender_name; auto user = telegram_api::make_object( @@ -3616,7 +3616,7 @@ void NotificationManager::add_message_push_notification(DialogId dialog_id, Mess } if (sender_user_id.is_valid() && !td_->contacts_manager_->have_user_force(sender_user_id)) { - int32 flags = telegram_api::user::FIRST_NAME_MASK | telegram_api::user::MIN_MASK; + int32 flags = USER_FLAG_IS_INACCESSIBLE; auto user_name = sender_user_id.get() == 136817688 ? "Channel" : sender_name; auto user = telegram_api::make_object( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index 12688e427..fba5235d9 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -150,6 +150,10 @@ class NotificationManager final : public Actor { static constexpr int32 ANNOUNCEMENT_ID_CACHE_TIME = 7 * 86400; + static constexpr int32 USER_FLAG_HAS_ACCESS_HASH = 1 << 0; + static constexpr int32 USER_FLAG_HAS_PHONE_NUMBER = 1 << 4; + static constexpr int32 USER_FLAG_IS_INACCESSIBLE = 1 << 20; + class AddMessagePushNotificationLogEvent; class EditMessagePushNotificationLogEvent; diff --git a/td/telegram/PasswordManager.cpp b/td/telegram/PasswordManager.cpp index ee0dbbc47..1bcb1ceb0 100644 --- a/td/telegram/PasswordManager.cpp +++ b/td/telegram/PasswordManager.cpp @@ -778,9 +778,8 @@ void PasswordManager::do_get_state(Promise promise) { state.current_srp_B = password->srp_B_.as_slice().str(); state.current_srp_id = password->srp_id_; state.password_hint = std::move(password->hint_); - state.has_recovery_email_address = - (password->flags_ & telegram_api::account_password::HAS_RECOVERY_MASK) != 0; - state.has_secure_values = (password->flags_ & telegram_api::account_password::HAS_SECURE_VALUES_MASK) != 0; + state.has_recovery_email_address = password->has_recovery_; + state.has_secure_values = password->has_secure_values_; } else { state.has_password = false; send_closure(actor_id, &PasswordManager::drop_cached_secret); diff --git a/td/telegram/Payments.cpp b/td/telegram/Payments.cpp index 12b763529..ae61a3d1b 100644 --- a/td/telegram/Payments.cpp +++ b/td/telegram/Payments.cpp @@ -304,9 +304,8 @@ class GetPaymentFormQuery final : public Td::ResultHandler { LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; return on_error(id, Status::Error(500, "Receive invalid seller identifier")); } - bool can_save_credentials = - (payment_form->flags_ & telegram_api::payments_paymentForm::CAN_SAVE_CREDENTIALS_MASK) != 0; - bool need_password = (payment_form->flags_ & telegram_api::payments_paymentForm::PASSWORD_MISSING_MASK) != 0; + bool can_save_credentials = payment_form->can_save_credentials_; + bool need_password = payment_form->password_missing_; promise_.set_value(make_tl_object( payment_form->form_id_, convert_invoice(std::move(payment_form->invoice_)), std::move(payment_form->url_), td->contacts_manager_->get_user_id_object(seller_bot_user_id, "paymentForm seller"), @@ -649,9 +648,8 @@ InputInvoice get_input_invoice(tl_object_ptr result.photo = get_web_document_photo(td->file_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id); result.start_parameter = std::move(message_invoice->start_param_); result.invoice.currency = std::move(message_invoice->currency_); - result.invoice.is_test = (message_invoice->flags_ & telegram_api::messageMediaInvoice::TEST_MASK) != 0; - result.invoice.need_shipping_address = - (message_invoice->flags_ & telegram_api::messageMediaInvoice::SHIPPING_ADDRESS_REQUESTED_MASK) != 0; + result.invoice.is_test = message_invoice->test_; + result.invoice.need_shipping_address = message_invoice->shipping_address_requested_; // result.payload = string(); // result.provider_token = string(); // result.provider_data = string(); @@ -674,9 +672,8 @@ InputInvoice get_input_invoice(tl_object_ptrfile_manager_.get(), std::move(message_invoice->photo_), owner_dialog_id); // result.start_parameter = string(); result.invoice.currency = std::move(message_invoice->currency_); - result.invoice.is_test = (message_invoice->flags_ & telegram_api::messageMediaInvoice::TEST_MASK) != 0; - result.invoice.need_shipping_address = - (message_invoice->flags_ & telegram_api::messageMediaInvoice::SHIPPING_ADDRESS_REQUESTED_MASK) != 0; + result.invoice.is_test = message_invoice->test_; + result.invoice.need_shipping_address = message_invoice->shipping_address_requested_; // result.payload = string(); // result.provider_token = string(); // result.provider_data = string(); diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index fc44bf0f7..0ea431483 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -159,7 +159,7 @@ ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64 auto profile_photo = move_tl_object_as(profile_photo_ptr); auto dc_id = DcId::create(profile_photo->dc_id_); - result.has_animation = (profile_photo->flags_ & telegram_api::userProfilePhoto::HAS_VIDEO_MASK) != 0; + result.has_animation = profile_photo->has_video_; result.id = profile_photo->photo_id_; result.minithumbnail = profile_photo->stripped_thumb_.as_slice().str(); result.small_file_id = register_photo( @@ -221,7 +221,7 @@ DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int6 auto chat_photo = move_tl_object_as(chat_photo_ptr); auto dc_id = DcId::create(chat_photo->dc_id_); - result.has_animation = (chat_photo->flags_ & telegram_api::chatPhoto::HAS_VIDEO_MASK) != 0; + result.has_animation = chat_photo->has_video_; result.minithumbnail = chat_photo->stripped_thumb_.as_slice().str(); result.small_file_id = register_photo(file_manager, PhotoSizeSource::dialog_photo(dialog_id, dialog_access_hash, false), @@ -702,7 +702,7 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && res.id = photo->id_; res.date = photo->date_; - res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0; + res.has_stickers = photo->has_stickers_; if (res.is_empty()) { LOG(ERROR) << "Receive photo with identifier " << res.id.get(); @@ -977,12 +977,8 @@ tl_object_ptr convert_photo_to_profile_photo( if (!have_photo_small || !have_photo_big) { return nullptr; } - int32 flags = 0; - if (!photo->video_sizes_.empty()) { - flags |= telegram_api::userProfilePhoto::HAS_VIDEO_MASK; - } - return make_tl_object(flags, false /*ignored*/, photo->id_, BufferSlice(), - photo->dc_id_); + bool has_video = !photo->video_sizes_.empty(); + return make_tl_object(0, has_video, photo->id_, BufferSlice(), photo->dc_id_); } } // namespace td diff --git a/td/telegram/PollManager.cpp b/td/telegram/PollManager.cpp index 32688fe2c..41669a3ac 100644 --- a/td/telegram/PollManager.cpp +++ b/td/telegram/PollManager.cpp @@ -1490,7 +1490,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptrflags_ & telegram_api::pollResults::MIN_MASK) != 0; + bool is_min = poll_results->min_; bool has_total_voters = (poll_results->flags_ & telegram_api::pollResults::TOTAL_VOTERS_MASK) != 0; if (has_total_voters && poll_results->total_voters_ != poll->total_voter_count) { poll->total_voter_count = poll_results->total_voters_; @@ -1509,14 +1509,14 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptrflags_ & telegram_api::pollAnswerVoters::CHOSEN_MASK) != 0; + bool is_chosen = poll_result->chosen_; if (is_chosen != option.is_chosen) { option.is_chosen = is_chosen; is_changed = true; } } if (!is_min || poll_server_is_closed) { - bool is_correct = (poll_result->flags_ & telegram_api::pollAnswerVoters::CORRECT_MASK) != 0; + bool is_correct = poll_result->correct_; if (is_correct) { if (correct_option_id != -1) { LOG(ERROR) << "Receive more than 1 correct answers " << correct_option_id << " and " << option_index; diff --git a/td/telegram/SecureValue.cpp b/td/telegram/SecureValue.cpp index 9cc8cc0b3..afba2e777 100644 --- a/td/telegram/SecureValue.cpp +++ b/td/telegram/SecureValue.cpp @@ -242,10 +242,9 @@ SuitableSecureValue get_suitable_secure_value( const tl_object_ptr &secure_required_type) { SuitableSecureValue result; result.type = get_secure_value_type(secure_required_type->type_); - auto flags = secure_required_type->flags_; - result.is_selfie_required = (flags & telegram_api::secureRequiredType::SELFIE_REQUIRED_MASK) != 0; - result.is_translation_required = (flags & telegram_api::secureRequiredType::TRANSLATION_REQUIRED_MASK) != 0; - result.is_native_name_required = (flags & telegram_api::secureRequiredType::NATIVE_NAMES_MASK) != 0; + result.is_selfie_required = secure_required_type->selfie_required_; + result.is_translation_required = secure_required_type->translation_required_; + result.is_native_name_required = secure_required_type->native_names_; return result; } diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index cbf549213..4136b759f 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -2690,10 +2690,10 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptraccess_hash_); bool is_installed = (set->flags_ & telegram_api::stickerSet::INSTALLED_DATE_MASK) != 0; - bool is_archived = (set->flags_ & telegram_api::stickerSet::ARCHIVED_MASK) != 0; - bool is_official = (set->flags_ & telegram_api::stickerSet::OFFICIAL_MASK) != 0; - bool is_animated = (set->flags_ & telegram_api::stickerSet::ANIMATED_MASK) != 0; - bool is_masks = (set->flags_ & telegram_api::stickerSet::MASKS_MASK) != 0; + bool is_archived = set->archived_; + bool is_official = set->official_; + bool is_animated = set->animated_; + bool is_masks = set->masks_; PhotoSize thumbnail; string minithumbnail; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 5056cc716..b8163243b 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -2902,7 +2902,7 @@ void Td::on_get_promo_data(Result(promo_data_ptr); expires_at = promo->expires_; - bool is_proxy = (promo->flags_ & telegram_api::help_promoData::PROXY_MASK) != 0; + bool is_proxy = promo->proxy_; messages_manager_->on_get_sponsored_dialog( std::move(promo->peer_), is_proxy ? DialogSource::mtproto_proxy() diff --git a/td/telegram/TermsOfService.cpp b/td/telegram/TermsOfService.cpp index 75c4dd61a..27f6274cc 100644 --- a/td/telegram/TermsOfService.cpp +++ b/td/telegram/TermsOfService.cpp @@ -106,9 +106,8 @@ TermsOfService::TermsOfService(telegram_api::object_ptrtext_), std::move(entities)}; - min_user_age_ = - ((terms->flags_ & telegram_api::help_termsOfService::MIN_AGE_CONFIRM_MASK) != 0 ? terms->min_age_confirm_ : 0); - show_popup_ = (terms->flags_ & telegram_api::help_termsOfService::POPUP_MASK) != 0; + min_user_age_ = terms->min_age_confirm_; + show_popup_ = terms->popup_; } void get_terms_of_service(Td *td, Promise> promise) { diff --git a/td/telegram/TopDialogCategory.cpp b/td/telegram/TopDialogCategory.cpp index 10a4238f9..b79f62843 100644 --- a/td/telegram/TopDialogCategory.cpp +++ b/td/telegram/TopDialogCategory.cpp @@ -56,6 +56,7 @@ TopDialogCategory get_top_dialog_category(const td_api::object_ptr &category) { CHECK(category != nullptr); switch (category->get_id()) { diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index c50195871..edaf2400b 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -2928,9 +2928,8 @@ void UpdatesManager::on_update(tl_object_ptr u } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - FolderId folder_id(update->flags_ & telegram_api::updateDialogPinned::FOLDER_ID_MASK ? update->folder_id_ : 0); - td_->messages_manager_->on_update_dialog_is_pinned( - folder_id, DialogId(update->peer_), (update->flags_ & telegram_api::updateDialogPinned::PINNED_MASK) != 0); + td_->messages_manager_->on_update_dialog_is_pinned(FolderId(update->folder_id_), DialogId(update->peer_), + update->pinned_); promise.set_value(Unit()); } @@ -2941,8 +2940,7 @@ void UpdatesManager::on_update(tl_object_ptr } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_update_dialog_is_marked_as_unread( - DialogId(update->peer_), (update->flags_ & telegram_api::updateDialogUnreadMark::UNREAD_MASK) != 0); + td_->messages_manager_->on_update_dialog_is_marked_as_unread(DialogId(update->peer_), update->unread_); promise.set_value(Unit()); } @@ -3047,8 +3045,7 @@ void UpdatesManager::on_update(tl_object_ptr up } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - bool is_masks = (update->flags_ & telegram_api::updateStickerSetsOrder::MASKS_MASK) != 0; - td_->stickers_manager_->on_update_sticker_sets_order(is_masks, + td_->stickers_manager_->on_update_sticker_sets_order(update->masks_, StickersManager::convert_sticker_set_ids(update->order_)); promise.set_value(Unit()); } diff --git a/td/telegram/WebPageBlock.cpp b/td/telegram/WebPageBlock.cpp index 36b483bdf..37c6ea58c 100644 --- a/td/telegram/WebPageBlock.cpp +++ b/td/telegram/WebPageBlock.cpp @@ -2039,8 +2039,8 @@ unique_ptr get_web_page_block(Td *td, tl_object_ptr(page_block_ptr); - bool need_autoplay = (page_block->flags_ & telegram_api::pageBlockVideo::AUTOPLAY_MASK) != 0; - bool is_looped = (page_block->flags_ & telegram_api::pageBlockVideo::LOOP_MASK) != 0; + bool need_autoplay = page_block->autoplay_; + bool is_looped = page_block->loop_; auto animations_it = animations.find(page_block->video_id_); if (animations_it != animations.end()) { LOG_IF(ERROR, !is_looped) << "Receive non-looped animation"; @@ -2067,8 +2067,8 @@ unique_ptr get_web_page_block(Td *td, tl_object_ptr(page_block_ptr); - bool is_full_width = (page_block->flags_ & telegram_api::pageBlockEmbed::FULL_WIDTH_MASK) != 0; - bool allow_scrolling = (page_block->flags_ & telegram_api::pageBlockEmbed::ALLOW_SCROLLING_MASK) != 0; + bool is_full_width = page_block->full_width_; + bool allow_scrolling = page_block->allow_scrolling_; bool has_dimensions = (page_block->flags_ & telegram_api::pageBlockEmbed::W_MASK) != 0; auto it = (page_block->flags_ & telegram_api::pageBlockEmbed::POSTER_PHOTO_ID_MASK) != 0 ? photos.find(page_block->poster_photo_id_) @@ -2158,23 +2158,22 @@ unique_ptr get_web_page_block(Td *td, tl_object_ptr(page_block_ptr); - auto is_bordered = (page_block->flags_ & telegram_api::pageBlockTable::BORDERED_MASK) != 0; - auto is_striped = (page_block->flags_ & telegram_api::pageBlockTable::STRIPED_MASK) != 0; + auto is_bordered = page_block->bordered_; + auto is_striped = page_block->striped_; auto cells = transform(std::move(page_block->rows_), [&](tl_object_ptr &&row) { return transform(std::move(row->cells_), [&](tl_object_ptr &&table_cell) { WebPageBlockTableCell cell; - auto flags = table_cell->flags_; - cell.is_header = (flags & telegram_api::pageTableCell::HEADER_MASK) != 0; - cell.align_center = (flags & telegram_api::pageTableCell::ALIGN_CENTER_MASK) != 0; + cell.is_header = table_cell->header_; + cell.align_center = table_cell->align_center_; if (!cell.align_center) { - cell.align_right = (flags & telegram_api::pageTableCell::ALIGN_RIGHT_MASK) != 0; + cell.align_right = table_cell->align_right_; if (!cell.align_right) { cell.align_left = true; } } - cell.valign_middle = (flags & telegram_api::pageTableCell::VALIGN_MIDDLE_MASK) != 0; + cell.valign_middle = table_cell->valign_middle_; if (!cell.valign_middle) { - cell.valign_bottom = (flags & telegram_api::pageTableCell::VALIGN_BOTTOM_MASK) != 0; + cell.valign_bottom = table_cell->valign_bottom_; if (!cell.valign_bottom) { cell.valign_top = true; } @@ -2182,10 +2181,10 @@ unique_ptr get_web_page_block(Td *td, tl_object_ptrtext_ != nullptr) { cell.text = get_rich_text(std::move(table_cell->text_), documents); } - if ((flags & telegram_api::pageTableCell::COLSPAN_MASK) != 0) { + if ((table_cell->flags_ & telegram_api::pageTableCell::COLSPAN_MASK) != 0) { cell.colspan = table_cell->colspan_; } - if ((flags & telegram_api::pageTableCell::ROWSPAN_MASK) != 0) { + if ((table_cell->flags_ & telegram_api::pageTableCell::ROWSPAN_MASK) != 0) { cell.rowspan = table_cell->rowspan_; } return cell; @@ -2196,7 +2195,7 @@ unique_ptr get_web_page_block(Td *td, tl_object_ptr(page_block_ptr); - auto is_open = (page_block->flags_ & telegram_api::pageBlockDetails::OPEN_MASK) != 0; + auto is_open = page_block->open_; return td::make_unique(get_rich_text(std::move(page_block->title_), documents), get_web_page_blocks(td, std::move(page_block->blocks_), animations, audios, documents, photos, videos, voice_notes), diff --git a/td/telegram/WebPagesManager.cpp b/td/telegram/WebPagesManager.cpp index 74ff295f4..c881e07e3 100644 --- a/td/telegram/WebPagesManager.cpp +++ b/td/telegram/WebPagesManager.cpp @@ -1456,12 +1456,12 @@ void WebPagesManager::on_get_web_page_instant_view(WebPage *web_page, tl_object_ web_page->instant_view.page_blocks = get_web_page_blocks(td_, std::move(page->blocks_), animations, audios, documents, photos, videos, voice_notes); web_page->instant_view.view_count = (page->flags_ & telegram_api::page::VIEWS_MASK) != 0 ? page->views_ : 0; - web_page->instant_view.is_v2 = (page->flags_ & telegram_api::page::V2_MASK) != 0; - web_page->instant_view.is_rtl = (page->flags_ & telegram_api::page::RTL_MASK) != 0; + web_page->instant_view.is_v2 = page->v2_; + web_page->instant_view.is_rtl = page->rtl_; web_page->instant_view.hash = hash; web_page->instant_view.url = std::move(page->url_); web_page->instant_view.is_empty = false; - web_page->instant_view.is_full = (page->flags_ & telegram_api::page::PART_MASK) == 0; + web_page->instant_view.is_full = !page->part_; web_page->instant_view.is_loaded = true; LOG(DEBUG) << "Receive web page instant view: " From 88d7b284b4280c03eafae968b21e8077070a099d Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 22:32:49 +0300 Subject: [PATCH 61/82] Add utc_time_offset option. --- td/generate/scheme/td_api.tl | 4 ++-- td/telegram/MessagesManager.cpp | 7 +++---- td/telegram/Td.cpp | 9 ++++++--- td/telegram/net/MtprotoHeader.cpp | 5 ++--- td/telegram/net/MtprotoHeader.h | 1 + 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 521a5410b..47f1485e2 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -822,8 +822,8 @@ messagePositions total_count:int32 positions:vector = MessagePo //@description Contains information about found messages sent in a specific day @total_count Total number of found messages sent in the day @message First message sent in the day messageCalendarDay total_count:int32 message:message = MessageCalendarDay; -//@description Contains information about found messages, splitted by days @total_count Total number of found messages @utc_time_offset UTC time offset in seconds, used to split messages by days @days Information about messages sent -messageCalendar total_count:int32 utc_time_offset:int32 days:vector = MessageCalendar; +//@description Contains information about found messages, splitted by days according to GetOption("utc_time_offset") @total_count Total number of found messages @days Information about messages sent +messageCalendar total_count:int32 days:vector = MessageCalendar; //@description Describes a sponsored message @id Unique sponsored message identifier @sponsor_chat_id Chat identifier diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 620c20bdf..83b91a4ce 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -67,7 +67,6 @@ #include "td/utils/format.h" #include "td/utils/misc.h" #include "td/utils/PathView.h" -#include "td/utils/port/Clocks.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" @@ -9811,7 +9810,7 @@ void MessagesManager::on_get_message_search_result_calendar( days.push_back(td_api::make_object( period->count_, get_message_object(dialog_id, m, "on_get_message_search_result_calendar"))); } - it->second = td_api::make_object(total_count, Clocks::tz_offset(), std::move(days)); + it->second = td_api::make_object(total_count, std::move(days)); promise.set_value(Unit()); } @@ -21540,7 +21539,7 @@ td_api::object_ptr MessagesManager::get_dialog_message_ db_query.dialog_id = dialog_id; db_query.filter = filter; db_query.from_message_id = fixed_from_message_id; - db_query.tz_offset = Clocks::tz_offset(); + db_query.tz_offset = static_cast(G()->shared_config().get_option_integer("utc_time_offset")); G()->td_db()->get_messages_db_async()->get_dialog_message_calendar(db_query, std::move(new_promise)); return {}; } @@ -21619,7 +21618,7 @@ void MessagesManager::on_get_message_calendar_from_database(int64 random_id, Dia days.push_back(td_api::make_object( period.second, get_message_object(dialog_id, m, "on_get_message_calendar_from_database"))); } - it->second = td_api::make_object(total_count, Clocks::tz_offset(), std::move(days)); + it->second = td_api::make_object(total_count, std::move(days)); } promise.set_value(Unit()); } diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index b8163243b..f354b8cf2 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -130,6 +130,7 @@ #include "td/utils/MimeType.h" #include "td/utils/misc.h" #include "td/utils/PathView.h" +#include "td/utils/port/Clocks.h" #include "td/utils/port/IPAddress.h" #include "td/utils/port/path.h" #include "td/utils/port/SocketFd.h" @@ -3867,6 +3868,7 @@ Status Td::init(DbKey key) { options_.language_pack = G()->shared_config().get_option_string("localization_target"); options_.language_code = G()->shared_config().get_option_string("language_pack_id"); options_.parameters = G()->shared_config().get_option_string("connection_parameters"); + options_.tz_offset = static_cast(G()->shared_config().get_option_integer("utc_time_offset")); options_.is_emulator = G()->shared_config().get_option_boolean("is_emulator"); // options_.proxy = Proxy(); G()->set_mtproto_header(make_unique(options_)); @@ -4023,6 +4025,7 @@ void Td::init_options_and_network() { if (!G()->shared_config().have_option("suggested_video_note_audio_bitrate")) { G()->shared_config().set_option_integer("suggested_video_note_audio_bitrate", 64); } + G()->shared_config().set_option_integer("utc_time_offset", Clocks::tz_offset()); init_connection_creator(); @@ -4463,9 +4466,9 @@ Status Td::set_parameters(td_api::object_ptr parameters options_.application_version += ", TDLib "; options_.application_version += TDLIB_VERSION; } - options_.language_pack = ""; - options_.language_code = ""; - options_.parameters = ""; + options_.language_pack = string(); + options_.language_code = string(); + options_.parameters = string(); options_.is_emulator = false; options_.proxy = Proxy(); diff --git a/td/telegram/net/MtprotoHeader.cpp b/td/telegram/net/MtprotoHeader.cpp index 831b4468c..9c388a73e 100644 --- a/td/telegram/net/MtprotoHeader.cpp +++ b/td/telegram/net/MtprotoHeader.cpp @@ -13,7 +13,6 @@ #include "td/tl/tl_object_store.h" -#include "td/utils/port/Clocks.h" #include "td/utils/tl_helpers.h" namespace td { @@ -89,12 +88,12 @@ class HeaderStorer { for (auto &value : values) { if (value->key_ == "tz_offset") { has_tz_offset = true; - break; + value->value_ = make_tl_object(options.tz_offset); } } if (!has_tz_offset) { values.push_back(make_tl_object( - "tz_offset", make_tl_object(Clocks::tz_offset()))); + "tz_offset", make_tl_object(options.tz_offset))); } } TlStoreBoxedUnknown::store(json_value, storer); diff --git a/td/telegram/net/MtprotoHeader.h b/td/telegram/net/MtprotoHeader.h index b5b0754c3..77699697b 100644 --- a/td/telegram/net/MtprotoHeader.h +++ b/td/telegram/net/MtprotoHeader.h @@ -24,6 +24,7 @@ class MtprotoHeader { string language_pack; string language_code; string parameters; + int32 tz_offset = 0; bool is_emulator = false; Proxy proxy; }; From 3d827b408f4f8aec5726dcf552dcd755850adcfc Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 22:42:33 +0300 Subject: [PATCH 62/82] Allow to set "utc_time_offset" option. --- td/telegram/Td.cpp | 29 ++++++++++++++++++----------- td/telegram/net/MtprotoHeader.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index f354b8cf2..61d1e958d 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3395,6 +3395,10 @@ void Td::on_config_option_updated(const string &name) { return send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, false, -1); } else if (name == "base_language_pack_version") { return send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, true, -1); + } else if (name == "utc_time_offset") { + if (G()->mtproto_header().set_tz_offset(static_cast(G()->shared_config().get_option_integer(name)))) { + G()->net_query_dispatcher().update_mtproto_header(); + } } else if (name == "notification_group_count_max") { send_closure(notification_manager_actor_, &NotificationManager::on_notification_group_count_max_changed, true); } else if (name == "notification_group_size_max") { @@ -7589,6 +7593,20 @@ void Td::on_request(uint64 id, td_api::setOption &request) { return; } break; + case 'u': + if (set_boolean_option("use_pfs")) { + return; + } + if (set_boolean_option("use_quick_ack")) { + return; + } + if (set_boolean_option("use_storage_optimizer")) { + return; + } + if (set_integer_option("utc_time_offset", -12 * 60 * 60, 14 * 60 * 60)) { + return; + } + break; case 'X': case 'x': { if (request.name_.size() > 255) { @@ -7615,17 +7633,6 @@ void Td::on_request(uint64 id, td_api::setOption &request) { } return send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); } - case 'u': - if (set_boolean_option("use_pfs")) { - return; - } - if (set_boolean_option("use_quick_ack")) { - return; - } - if (set_boolean_option("use_storage_optimizer")) { - return; - } - break; } return send_error_raw(id, 400, "Option can't be set"); diff --git a/td/telegram/net/MtprotoHeader.h b/td/telegram/net/MtprotoHeader.h index 77699697b..f6d1f83ee 100644 --- a/td/telegram/net/MtprotoHeader.h +++ b/td/telegram/net/MtprotoHeader.h @@ -78,6 +78,16 @@ class MtprotoHeader { return true; } + bool set_tz_offset(int32 tz_offset) { + if (options_.tz_offset == tz_offset) { + return false; + } + + options_.tz_offset = tz_offset; + default_header_ = gen_header(options_, false); + return true; + } + Slice get_default_header() const { return default_header_; } From 6ab91f2712beabf1e00ac618dc2795b810b20bcd Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 23:03:41 +0300 Subject: [PATCH 63/82] Update chat join request after GetChatJoinRequestsQuery. --- td/telegram/ContactsManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 16271b133..6cdb7c1c6 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -2008,6 +2008,7 @@ class GetChatJoinRequestsQuery final : public Td::ResultHandler { total_count = static_cast(result->importers_.size()); } vector> join_requests; + vector recent_requesters; for (auto &request : result->importers_) { UserId user_id(request->user_id_); UserId approver_user_id(request->approved_by_); @@ -2016,9 +2017,14 @@ class GetChatJoinRequestsQuery final : public Td::ResultHandler { total_count--; continue; } + if (recent_requesters.size() < 3) { + recent_requesters.push_back(user_id.get()); + } join_requests.push_back(td_api::make_object( td->contacts_manager_->get_user_id_object(user_id, "chatJoinRequest"), request->date_, request->about_)); } + td->messages_manager_->on_update_dialog_pending_join_requests(dialog_id_, total_count, + std::move(recent_requesters)); promise_.set_value(td_api::make_object(total_count, std::move(join_requests))); } From 2ac0bea1930f52581d2d5e092751a6a728b1901d Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 1 Nov 2021 23:19:22 +0300 Subject: [PATCH 64/82] Disable animated emoji clicks if animated emoji are disabled. --- td/telegram/StickersManager.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 4136b759f..ee1e44856 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -4314,6 +4314,10 @@ void StickersManager::get_animated_emoji(string emoji, bool is_recursive, void StickersManager::get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, Promise> &&promise) { + if (disable_animated_emojis_) { + return promise.set_value(nullptr); + } + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::animated_emoji_click()); if (!special_sticker_set.id_.is_valid()) { // don't wait for the first load of the sticker set from the server @@ -4375,6 +4379,10 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic return promise.set_error(Status::Error(400, "Message is not an animated emoji message")); } + if (disable_animated_emojis_) { + return promise.set_value(nullptr); + } + auto now = Time::now(); if (last_clicked_animated_emoji_ == message_text && last_clicked_animated_emoji_full_message_id_ == full_message_id && next_click_animated_emoji_message_time_ >= now + 2 * MIN_ANIMATED_EMOJI_CLICK_DELAY) { @@ -4531,7 +4539,7 @@ bool StickersManager::is_sent_animated_emoji_click(DialogId dialog_id, Slice emo } Status StickersManager::on_animated_emoji_message_clicked(Slice emoji, FullMessageId full_message_id, string data) { - if (td_->auth_manager_->is_bot()) { + if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { return Status::OK(); } @@ -4649,7 +4657,7 @@ void StickersManager::schedule_update_animated_emoji_clicked(const StickerSet *s } void StickersManager::send_update_animated_emoji_clicked(FullMessageId full_message_id, FileId sticker_id) { - if (G()->close_flag()) { + if (G()->close_flag() || disable_animated_emojis_) { return; } if (td_->messages_manager_->is_message_edited_recently(full_message_id, 2)) { From 32a2e51235b4d7f9ccb26c518d31d5cbdd950465 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 15:25:55 +0300 Subject: [PATCH 65/82] Improve documentation. --- td/generate/scheme/td_api.tl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 47f1485e2..751105c28 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -822,7 +822,7 @@ messagePositions total_count:int32 positions:vector = MessagePo //@description Contains information about found messages sent in a specific day @total_count Total number of found messages sent in the day @message First message sent in the day messageCalendarDay total_count:int32 message:message = MessageCalendarDay; -//@description Contains information about found messages, splitted by days according to GetOption("utc_time_offset") @total_count Total number of found messages @days Information about messages sent +//@description Contains information about found messages, splitted by days according to the option "utc_time_offset" @total_count Total number of found messages @days Information about messages sent messageCalendar total_count:int32 days:vector = MessageCalendar; @@ -4312,7 +4312,7 @@ getChatMessageByDate chat_id:int53 date:int32 = Message; //@limit The expected number of message positions to be returned; 50-2000. A smaller number of positions can be returned, if there are not enough appropriate messages getChatSparseMessagePositions chat_id:int53 filter:SearchMessagesFilter from_message_id:int53 limit:int32 = MessagePositions; -//@description Returns information about the next messages of the specified type in the chat splitted by days. Returns the results in reverse chronological order. Can return partial result for the last returned day +//@description Returns information about the next messages of the specified type in the chat splitted by days. Returns the results in reverse chronological order. Can return partial result for the last returned day. Behavior of this method depends on the value of the option "utc_time_offset" //@chat_id Identifier of the chat in which to return information about messages //@filter Filter for message content. Filters searchMessagesFilterEmpty, searchMessagesFilterCall, searchMessagesFilterMissedCall, searchMessagesFilterMention and searchMessagesFilterUnreadMention are unsupported in this function //@from_message_id The message identifier from which to return information about messages; use 0 to get results from the last message From 5a596fcc485bd69ad64511edc87356222bd40403 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 17:09:54 +0300 Subject: [PATCH 66/82] Reuse chatJoinRequest class. --- td/generate/scheme/td_api.tl | 5 ++--- td/telegram/ContactsManager.cpp | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 751105c28..5f3b2b23e 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3947,9 +3947,8 @@ updatePollAnswer poll_id:int64 user_id:int53 option_ids:vector = Update; //@old_chat_member Previous chat member @new_chat_member New chat member updateChatMember chat_id:int53 actor_user_id:int53 date:int32 invite_link:chatInviteLink old_chat_member:chatMember new_chat_member:chatMember = Update; -//@description A user sent a join request to a chat; for bots only @chat_id Chat identifier @user_id Identifier of the user, which sent the join request -//@bio A short user bio @date Point in time (Unix timestamp) when the request was sent @invite_link The invite link, which was used to send join request; may be null -updateNewChatJoinRequest chat_id:int53 user_id:int53 bio:string date:int32 invite_link:chatInviteLink = Update; +//@description A user sent a join request to a chat; for bots only @chat_id Chat identifier @request Join request @invite_link The invite link, which was used to send join request; may be null +updateNewChatJoinRequest chat_id:int53 request:chatJoinRequest invite_link:chatInviteLink = Update; //@description Contains a list of updates @updates List of updates diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 6cdb7c1c6..19c9afe36 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -13754,7 +13754,9 @@ void ContactsManager::on_update_chat_invite_requester(DialogId dialog_id, UserId send_closure(G()->td(), &Td::send_update, td_api::make_object( - dialog_id.get(), get_user_id_object(user_id, "on_update_chat_invite_requester"), about, date, + dialog_id.get(), + td_api::make_object( + get_user_id_object(user_id, "on_update_chat_invite_requester"), date, about), invite_link.get_chat_invite_link_object(this))); } From d732789cacda23d5ff936c885f451e42e0f82a5b Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 17:21:36 +0300 Subject: [PATCH 67/82] Disallow member_limit for links requiring administrator approval. --- td/generate/scheme/td_api.tl | 8 ++++---- td/telegram/ContactsManager.cpp | 8 ++++++++ td/telegram/DialogInviteLink.cpp | 4 ++++ td/telegram/DialogInviteLink.h | 3 +++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5f3b2b23e..5462d5984 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -569,10 +569,10 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@date Point in time (Unix timestamp) when the link was created //@edit_date Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown //@expire_date Point in time (Unix timestamp) when the link will expire; 0 if never -//@member_limit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited +//@member_limit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited. Always 0 if the link requires approval //@member_count Number of chat members, which joined the chat using the link //@pending_join_request_count Number of pending join requests, created using this link -//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators +//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators. If true, total number of joining members will be unlimited //@is_primary True, if the link is primary. Primary invite link can't have title, expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time //@is_revoked True, if the link was revoked chatInviteLink invite_link:string title:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 pending_join_request_count:int32 requires_approval:Bool is_primary:Bool is_revoked:Bool = ChatInviteLink; @@ -4933,7 +4933,7 @@ replacePrimaryChatInviteLink chat_id:int53 = ChatInviteLink; //@title Invite link title; 0-32 characters //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited -//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators +//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators. If true, member_limit must not be specified createChatInviteLink chat_id:int53 title:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; //@description Edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links @@ -4942,7 +4942,7 @@ createChatInviteLink chat_id:int53 title:string expire_date:int32 member_limit:i //@title Invite link title; 0-32 characters //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited -//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators +//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators. If true, member_limit must not be specified editChatInviteLink chat_id:int53 invite_link:string title:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; //@description Returns information about an invite link. Requires administrator privileges and can_invite_users right in the chat to get own links and owner privileges to get other links diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 19c9afe36..a7433639f 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -7459,6 +7459,10 @@ void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, string Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); + if (requires_approval && usage_limit > 0) { + return promise.set_error( + Status::Error(400, "Member limit can't be specified for links requiring administrator approval")); + } auto new_title = clean_name(std::move(title), MAX_INVITE_LINK_TITLE_LENGTH); td_->create_handler(std::move(promise)) @@ -7469,6 +7473,10 @@ void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string & int32 expire_date, int32 usage_limit, bool requires_approval, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); + if (requires_approval && usage_limit > 0) { + return promise.set_error( + Status::Error(400, "Member limit can't be specified for links requiring administrator approval")); + } if (invite_link.empty()) { return promise.set_error(Status::Error(400, "Invite link must be non-empty")); diff --git a/td/telegram/DialogInviteLink.cpp b/td/telegram/DialogInviteLink.cpp index 3cc8e2324..6ab4ba74c 100644 --- a/td/telegram/DialogInviteLink.cpp +++ b/td/telegram/DialogInviteLink.cpp @@ -71,6 +71,10 @@ DialogInviteLink::DialogInviteLink(tl_object_ptr 0) { + LOG(ERROR) << "Receive wrong permanent " << *this; + usage_limit_ = 0; + } } bool DialogInviteLink::is_valid_invite_link(Slice invite_link) { diff --git a/td/telegram/DialogInviteLink.h b/td/telegram/DialogInviteLink.h index accfdd396..5d020f421 100644 --- a/td/telegram/DialogInviteLink.h +++ b/td/telegram/DialogInviteLink.h @@ -146,6 +146,9 @@ class DialogInviteLink { if (has_title) { parse(title_, parser); } + if (requires_approval_) { + usage_limit_ = 0; + } } }; From 239f46b0750e052f85eb8d5263eab4e53458839c Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 17:51:52 +0300 Subject: [PATCH 68/82] Don't store pending join requests for bots. --- td/telegram/MessagesManager.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 83b91a4ce..ef926ffa3 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -30510,6 +30510,9 @@ void MessagesManager::set_dialog_theme_name(Dialog *d, string theme_name) { void MessagesManager::drop_dialog_pending_join_requests(DialogId dialog_id) { CHECK(dialog_id.is_valid()); + if (td_->auth_manager_->is_bot()) { + return; + } auto d = get_dialog(dialog_id); // called from update_chat/channel, must not create the dialog if (d != nullptr && d->is_update_new_chat_sent) { set_dialog_pending_join_requests(d, 0, {}); @@ -30522,6 +30525,9 @@ void MessagesManager::on_update_dialog_pending_join_requests(DialogId dialog_id, LOG(ERROR) << "Receive pending join request count in invalid " << dialog_id; return; } + if (td_->auth_manager_->is_bot()) { + return; + } auto d = get_dialog_force(dialog_id, "on_update_dialog_pending_join_request_count"); if (d == nullptr) { @@ -30578,6 +30584,10 @@ void MessagesManager::fix_pending_join_requests(DialogId dialog_id, int32 &pendi void MessagesManager::set_dialog_pending_join_requests(Dialog *d, int32 pending_join_request_count, vector pending_join_request_user_ids) { + if (td_->auth_manager_->is_bot()) { + return; + } + CHECK(d != nullptr); fix_pending_join_requests(d->dialog_id, pending_join_request_count, pending_join_request_user_ids); if (d->pending_join_request_count == pending_join_request_count && From 41668e3aca9dc13ce9ebc25ee9c94500c8df20bd Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 18:01:09 +0300 Subject: [PATCH 69/82] Don't store dialog theme names for bots. --- td/telegram/MessagesManager.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ef926ffa3..f9ff93b67 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -17532,15 +17532,15 @@ Status MessagesManager::can_get_message_viewers(FullMessageId full_message_id) { } Status MessagesManager::can_get_message_viewers(DialogId dialog_id, const Message *m) const { + if (td_->auth_manager_->is_bot()) { + return Status::Error(400, "User is bot"); + } if (!m->is_outgoing) { return Status::Error(400, "Can't get viewers of incoming messages"); } if (G()->unix_time() - m->date > G()->shared_config().get_option_integer("chat_read_mark_expire_period", 7 * 86400)) { return Status::Error(400, "Message is too old"); } - if (td_->auth_manager_->is_bot()) { - return Status::Error(400, "User is bot"); - } int32 participant_count = 0; switch (dialog_id.get_type()) { @@ -30481,6 +30481,9 @@ void MessagesManager::on_update_dialog_theme_name(DialogId dialog_id, string the LOG(ERROR) << "Receive theme in invalid " << dialog_id; return; } + if (td_->auth_manager_->is_bot()) { + return; + } auto d = get_dialog_force(dialog_id, "on_update_dialog_theme_name"); if (d == nullptr) { @@ -30493,6 +30496,10 @@ void MessagesManager::on_update_dialog_theme_name(DialogId dialog_id, string the void MessagesManager::set_dialog_theme_name(Dialog *d, string theme_name) { CHECK(d != nullptr); + if (td_->auth_manager_->is_bot()) { + return; + } + bool is_changed = d->theme_name != theme_name; if (!is_changed && d->is_theme_name_inited) { return; From 9d467d1ea561ce9048585d5de447ab4a34fa814a Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 18:05:50 +0300 Subject: [PATCH 70/82] Add chatEventMemberJoinedByRequest. --- td/generate/scheme/td_api.tl | 7 +++++-- td/telegram/MessagesManager.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5462d5984..5874a45ea 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2539,8 +2539,11 @@ chatEventMessageUnpinned message:message = ChatEventAction; //@description A new member joined the chat chatEventMemberJoined = ChatEventAction; -//@description A new member joined the chat by an invite link @invite_link Invite link used to join the chat @approver_user_id User identifier of the chat administrator, approved user join request; 0 if the approval wasn't needed -chatEventMemberJoinedByInviteLink invite_link:chatInviteLink approver_user_id:int53 = ChatEventAction; +//@description A new member joined the chat by an invite link @invite_link Invite link used to join the chat +chatEventMemberJoinedByInviteLink invite_link:chatInviteLink = ChatEventAction; + +//@description A new member was accepted to the chat by an administrator @approver_user_id User identifier of the chat administrator, approved user join request @invite_link Invite link used to join the chat; may be null +chatEventMemberJoinedByRequest approver_user_id:int53 invite_link:chatInviteLink = ChatEventAction; //@description A member left the chat chatEventMemberLeft = ChatEventAction; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index f9ff93b67..76a6ae3b6 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -32436,7 +32436,7 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob return nullptr; } return make_tl_object( - invite_link.get_chat_invite_link_object(td_->contacts_manager_.get()), 0); + invite_link.get_chat_invite_link_object(td_->contacts_manager_.get())); } case telegram_api::channelAdminLogEventActionParticipantJoinByRequest::ID: { auto action = move_tl_object_as(action_ptr); @@ -32449,9 +32449,9 @@ tl_object_ptr MessagesManager::get_chat_event_action_ob if (!approver_user_id.is_valid()) { return nullptr; } - return make_tl_object( - invite_link.get_chat_invite_link_object(td_->contacts_manager_.get()), - td_->contacts_manager_->get_user_id_object(approver_user_id, "chatEventMemberJoinedByInviteLink")); + return make_tl_object( + td_->contacts_manager_->get_user_id_object(approver_user_id, "chatEventMemberJoinedByRequest"), + invite_link.get_chat_invite_link_object(td_->contacts_manager_.get())); } case telegram_api::channelAdminLogEventActionParticipantLeave::ID: return make_tl_object(); From babb66d3e06c5df025dcac04da6b0783759721c4 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 18:30:11 +0300 Subject: [PATCH 71/82] Fix processing of empty messages. --- td/telegram/MessagesManager.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 76a6ae3b6..c67d3e100 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -464,14 +464,16 @@ class GetMessagesQuery final : public Td::ResultHandler { class GetChannelMessagesQuery final : public Td::ResultHandler { Promise promise_; ChannelId channel_id_; + MessageId last_new_message_id_; public: explicit GetChannelMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { } void send(ChannelId channel_id, tl_object_ptr &&input_channel, - vector> &&message_ids) { + vector> &&message_ids, MessageId last_new_message_id) { channel_id_ = channel_id; + last_new_message_id_ = last_new_message_id; CHECK(input_channel != nullptr); send_query(G()->net_query_creator().create( telegram_api::channels_getMessages(std::move(input_channel), std::move(message_ids)))); @@ -485,12 +487,14 @@ class GetChannelMessagesQuery final : public Td::ResultHandler { auto info = td->messages_manager_->get_messages_info(result_ptr.move_as_ok(), "GetChannelMessagesQuery"); LOG_IF(ERROR, !info.is_channel_messages) << "Receive ordinary messages in GetChannelMessagesQuery"; - if (!td->auth_manager_->is_bot()) { // bots can receive messageEmpty because of their privacy mode + // messages with invalid big identifiers can be received as messageEmpty + // bots can receive messageEmpty because of their privacy mode + if (last_new_message_id_.is_valid() && !td->auth_manager_->is_bot()) { vector empty_message_ids; for (auto &message : info.messages) { if (message->get_id() == telegram_api::messageEmpty::ID) { auto message_id = MessagesManager::get_message_id(message, false); - if (message_id.is_valid()) { + if (message_id.is_valid() && message_id <= last_new_message_id_) { empty_message_ids.push_back(message_id); } } @@ -17856,8 +17860,10 @@ void MessagesManager::get_messages_from_server(vector &&message_i mpas.get_promise().set_error(Status::Error(400, "Can't access the chat")); continue; } + const auto *d = get_dialog_force(DialogId(it.first)); td_->create_handler(mpas.get_promise()) - ->send(it.first, std::move(input_channel), std::move(it.second)); + ->send(it.first, std::move(input_channel), std::move(it.second), + d == nullptr ? MessageId() : d->last_new_message_id); } lock.set_value(Unit()); } From ca6fb2bdb2cc975266f84ce5778be6babd24cd50 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 19:04:02 +0300 Subject: [PATCH 72/82] Fix getCountries. --- td/telegram/CountryInfoManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/td/telegram/CountryInfoManager.cpp b/td/telegram/CountryInfoManager.cpp index e9efe9dea..92c1d8ee9 100644 --- a/td/telegram/CountryInfoManager.cpp +++ b/td/telegram/CountryInfoManager.cpp @@ -380,6 +380,7 @@ void CountryInfoManager::on_get_country_list(const string &language_code, void CountryInfoManager::on_get_country_list_impl(const string &language_code, tl_object_ptr country_list) { CHECK(country_list != nullptr); + LOG(DEBUG) << "Receive " << to_string(country_list); auto &countries = countries_[language_code]; switch (country_list->get_id()) { case telegram_api::help_countriesListNotModified::ID: @@ -395,6 +396,8 @@ void CountryInfoManager::on_get_country_list_impl(const string &language_code, auto list = move_tl_object_as(country_list); if (countries == nullptr) { countries = make_unique(); + } else { + countries->countries.clear(); } for (auto &c : list->countries_) { CountryInfo info; From d63471fcde01fc5594e48ababf7691e2aba82981 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 Nov 2021 19:20:18 +0300 Subject: [PATCH 73/82] Update country list. --- td/telegram/CountryInfoManager.cpp | 126 +++++++++++++++-------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/td/telegram/CountryInfoManager.cpp b/td/telegram/CountryInfoManager.cpp index 92c1d8ee9..719d740af 100644 --- a/td/telegram/CountryInfoManager.cpp +++ b/td/telegram/CountryInfoManager.cpp @@ -444,68 +444,70 @@ const CountryInfoManager::CountryList *CountryInfoManager::get_country_list(Coun if (language_code == "en") { static const BufferSlice en = gzdecode( base64url_decode( - "eJyNW81uI0lyzhb13-qeaXs8uwdjQMDAehfwLMj6ryP_RZFFsVmk_m5JMofMUbFKU6ySVnqBve0jGAb2sNiDb_YTtH034LfYi1_" - "BUaTEKlYFsxrobqmpjMzIyIgvvohM_Wv4P3_8h__6z3_8GyHkn_70xy_whexV6uSo4k4936fRz97BZ__" - "334XqHnwtyLr29tnxzU1x9WdLtkG-G7k8YNNixafjYmPBfRqwJfwsM5epl98-e7-aaPX3Jp6rSd5XfprNqcuXAXXT8numTBLymwli-" - "Rb5VHEDPgtp8TfFKvXH4ZRm9dgvS5qR0O_" - "4TZGtfbXJccWdhdxxKLKXaA4ld44u2NUZw3YQu6qq2BYWyPoLhsrqyttnp7FsYt1Lcgi6e6B5RlZSFLENB-" - "Sk4s8YmNFN2W71c1VJrGOTj5UF8_mEukWbLrzsevtlzci30xD2Gi4DP7vXPSU-" - "89O15M32XkegbyRLHY6c9Z5WTvjMSj5l52tyUPHDMSJbkExdrPcdOa28MH9M-c_URfzdVIRnXK2Q76reEo4Y3PWc-" - "S9s5j2uzJ6dSzZ04ZlXq-Q48ng69bDYA39VtLxzqNbJaZW6M4dO2XKe1cEwSmIdGuSoypwZDxeZc5ClzXxnN29AksKSapOcVUP_" - "HkxQbNKlh9lBkrRtm67_xHO0wA6hM6M-T9uRrOPOjMeeg7507lOewRrAKvnts5Ob2FixbBtkQz90pzyro5o6q-" - "K2z1YvyEEVIttF92eKbWxFNvYXgGzZM1aUcu4Z98inKqjNeLFO_XC5pA5dIHpo8f7xeS5BD8_hjwg-qWZ5O2bT-_9Mfqh6LuU--" - "5eizd2g2IAIpgEPlxAINh3T7LmpZuLcBuSw6tMX7mTjXVU3n314XTh7dvbq3OmCLrE4kXJtOIT152GAxryuis_" - "vGvzTC5ZPFI9zScuJ89tVjEVHh-QFcU6p3oHezOEvDLFvqbwZV6uQwxroN90-hwJ8fVde6_" - "zbSEYpyQXV0Au6USoYklqQZA18v1TQSgr4j1TQdaMgwfeKXIb5tYJeMgtmCT43pCiOIReZBckwC7IiF2RNLShlDcbqBbVsFlTFKGhlua" - "ApMH9JLRglHWSjMQaMgb-wjlpWCqoOY41ywQAZQ4d5YB1Nhu9jO54l8tzWOdbq5FPNg0RZ_G2dLX5fHLCH3_" - "8OOxNFFtq11iTf1SBjQg4qVn5ap8NoLvR8ZTF-1Vrk7FWnV3UwfSSxPufkvf3EA0hNDnWn2ZyazImYfJt8rH35j4AVp__" - "cfvQgTDGcUrfjrJiNs1on2ot3X2wvIz3SeWnld5ohxeO75KA25w5D8riqifN4zSLHNQpkxPNc3O4bf0DxvNZbrZ3mPKu1DS2JKYnVk_" - "KXsL7neItxJu-s9dfT-Q_xxwE5rXmAhMUB-FB2DxBD4j2MyH5tRWWQ9dM8KoXJtStYmz6w4hXzp9h5y4YQE2uAa7XQp1_-QtN5-" - "90rfr999s5Myt0C1jw_AJwhnEfNObM78NMXNplH0RaOHT7JzqFIpYSvZ_luHThLC_IpdZ-zcWKu5tt_PbMN_YzmKmub_74v6_" - "H3slYqF5WyaSTXuCDH9Z_52AsDjvqmKgsxod4hR3XmLqh_" - "n9UxzneojeoQF3Vvwd3IozBeqGs6ycl39Uvy8W2OV2SLxhe25jFK5o55EmOkrxij7BoT63MX1VUzhtQLBaksp-" - "IsyzMbNXLUmIRAlX2Eu4ixvgH-0lgGHl6XScKzaLTIQWP2_BAg8SmVkviQhJiE_ADW9nngM2TfMec6iWlDQtYmB_YDxTjnnqyI6-" - "rGkBw3gjn3HlBsA_8V1_VN4MpN7qZzEVnHuBGPuyD7Tf4zGiOabgp9otkh3zapcx8tIso3aqkUy1jk1OIT33PZkiOcUzNjTtS8JB-" - "a1PdYPDlyBhuMPErbsAmctelTd5LF1j1ZTuSX4pbTbuRbFXLQomMPrRmUbb79KhzLVsnH1x5Nh7uzqbfI6qBs-" - "8AboMVz1AEnfRaRQqTu0OW8mG2tcNbzZ0jcmKYq9L9WE2wPawPQt0JOsb4ExK0Sjz8HW80z417zmDi-" - "W21y0uJjoHIB9bE6XC0JY7zVBXmfsZW3oz5i7vSRlkUOW3TFIBC-VRLbtweyIXcZKivu-bT65LQFcMgcL3xAcr9qbtbeiamtz-" - "RT45eQBh6gslN8VQXzVXE-bkGcRPZD42QLI3EO1RqC_UENtqAOtr5akrZiJc2DWsChQH6BYNB-WdNz6-" - "vWNfmw3vyPVQ7VdYjaQBXPcRud5XPkwIifx3z5vENOzqFWKHbgH2QdQxXv9bxHjkF-CrQN7deqJUXo6-eQj2q-" - "B4U7kgsNcR18PiQH55RHhAhZ1xSvOyJH56E7o36Ws8kaEfpXu05O2u70FfKRfmHcpzqNYTBeuw041vYZVlcBNoixpd0lh-" - "2lT1m2b1EwdXFN14b6BPRGdTbL29j9qnUse0nO6pxBTdmi_mRHDlc0oU-2P5P9tk9_wWRNTcmNy_ZgJY_VZnumkR_XbRvsPtlld0WsO_" - "haO6DOM8Z9TLG_XFjk6IIuKFDfLB4Yem5P9eKSHF54_hTtFWmJM0dq2os-" - "ObigDxTjbEY5aTOcL3Ya5KDD3GcUh1VxTui0yGnn2Z89vyzxPpepCeOkc76qx8feFPc3QxXjQ6dNjjvc52OK10yaIa6FO3BuNW_h-" - "V62TyZpYi7Z6ZG_t2nUl-zwIIh6kj32yJFeoaHl1iqdPnnf8_xgDiCd4u1kbYeYj3YG5L0NRSIydn3mUtJXN2cey1-Tw074BKiK-" - "Zoqttct1NL0GergDcHN7leGajNvv3fgN_SF3s8zfrPqH-pr-Wi-d1r8_zX33TjCNvftVsh-l6L3GmA_" - "LSFfTLhSQr5KjrpsTF0P6fNrZaEfdmtwJitf6IaTbJ6D-lnNvUvstsmHLmeTecDcZcDQvr8iifvtXcj1ts-" - "LXereozlASfvGNpZ0IVd3-RivmWVx_da1I_stvWDuIbGkie0HfKzLg3kY3YJifFrf4tNrHEnue0ROu-" - "EfGCBJ6M8wPp7Mm1kc616Rwy4NHjFOLetl8dq35ABshuNn2RDazKqQIwvQZzJBbFYW53qrRg4tz6UTD9NZ3BOz6tG6ztR7xPoTsvCsrA" - "bUw54LXspm_vbaK6ySE71aC_KDBcXgjC4nUCghfrGx7VkyLpM-bZ2Tby3qL-fUcYQ94gTntTrkmzWeWnTCpngfxhDfoVldsm9RB-_" - "FSeJ7PwvyigXUfEH9tJ57ppoYB9zaivr4Dp7_TD0VNylubl2SA9ghWj8Yao6OffLrlY2Y74KZ_Khk3mHft7qmlIdh1ufovP2Au_" - "yXELs_MrV47CAaG_o8WAU9YmNxn8yy1364ZL5Ps7kM9M1_e2ENI_tBEY_W8OI7GGtETtb68xDt88jiHoB1BWdPnSl_" - "3PEORhPX8hbkcZCnTxyLK_Edn3UDsuwPfJKN3z1VSqxxu9KRPi_x-wrtK_" - "qR1l10Ti9RxyLtE68cU4yRPcDIHl3wMZaTNPHbiV6NfOixp2KNOmsUQO-" - "W9Hg8cOEenzGspyNJutAfek3yEeLpJ895u8pC1tJjjOq1YF98R39aVnLt2muTkx4UHD6dhZj_qiUxl-t1gXOyKPxXIZ-" - "tecobDpbuN34w9VinrTmhjgEbPNFnpHcY323h-kAd02MP1EFxUM-3xwDkIR5D7Iz1uO_" - "XG5H9HgdPRH1BjsfdRfZ5Kt4xit6Paop4P5cW2b9coLUsxLYhlO1XyGEf8HiB3u-Jc3u_Qfb7LDIDcr-33QPI8KB-k3z72kPte87za_" - "sDs1P8zqLfIt_26UNIi5G13lp62Bmoscw5ed-fc4c_PMDwrO9pchJX8Fq_3yHHfXq_egSI7dXMvCVC5uiCnb1MrK791cixlUV-" - "teb8fQ4piEEBaEUI52zXD2R9ZvH9RR_qt37I_MCLLnC9txhL1ArGrru2eIwp59aUfZuc9AH3lpCNkbtyiKl0j3UbO_tDsC_" - "wg3AWhSSWH8ti-1yTA1g_zU1e_SeuZ_u30TmuUOwZW0fN6ft_rpCDzxTvw5s5byAHDXI8-PLX0OU73gNo4rphcEmOBt4Ce7u5p5TE_" - "jOwyaHNfLSPLxviWmswIn83CJcQnW6xyaYMCFC0g_Q8ybp5ZwwMgEcMniAEMA6mpn1kew92hZzZNJzy1bPeHRxW04R7savkGzt6E-" - "FtmgoIdsQ52q6RU5s9T-bMAefGepRGfOZx0orl6-" - "TADqdYvyx6ayTWtQFn9gQGz9p6T9nqKSOyLajNuTujD56PvV3Rcu7o7fPI1hHenDOHbd6F7SXtJCl64g5pc3aHab-32-" - "TYdrxH5uJnJhviet3urOUBflF5RRJjg92FvUSoSYtd5rnpXPzKgSSxDhb4AV2XLi5aAxu5vm_3yJEdFbLUQfieOAZtiH0bYt_B-Juao_" - "sA7AelA2R4dO9qzpti237rAa48Gekd5Og-JN_bX_7sFYfe4stfIXP1_S__7k44dq8nyck-6BvlS-" - "hyRd43nKJNnUf8rURJXIfaN5EvgFtbFCpHhuEw5ESpTHLynX0Lcf3so_0jU5PF_nhHjhvLJxoVrqgv5vC1YY18Pwz9-6gLXKOQ1ZeC_" - "qiW_3ZlWCf7tTmd4nGRqu1SdciwRfaH3mzHu2hD6JfDc3I8nFO-vpZGMCrnfd3wgpwO6c_" - "8lZVlz8EU97SGHXI09O4ZsIZsDjBjzjCE2mXIF57_Yxf4DUPyRWKsRc6is4l-S2IHVwS9kj669vGt8wWcGAJLWKJvicRYObwkB0MPcB_" - "lxHE_ZDggh5GeDKmdzK-40x4OyachQAqf0im44dAb08gJsv5n5P9ey_Aq0uWROiHG3WIuOwTuMKT8CTtrw9CEMTeEmBtS94XuyEFSzu-" - "-jCrkaHQfPctnGVk5_h2Es41sqq84apHD0WwX7xFzlpFNCiO7kuFb5a_gW6Nb0NsPI7qL4P42d0n3-" - "0Z35HT0Mma748vI3fdVjfyw5hFX3J0w-PqbYjBnxfW7nagcw_A3__" - "dzrhrk5Apy6QuUQAgG76lfcX971SLfV6OO2nIO2vkzLrpnkr5Cpzb5NLLTU6F3VqXcuQADrjgLIGenY2LPSPy-" - "09UIxlE3pAGCYXocO9dN8s01dRweJY1mGIRu9t5PM-K3ZdfR27zVr09hMbmqraPP9m5a5IeWA9HvFC1vzB0GqTkArswD-" - "O4Z0HKRlTcS69x0yGHHW3qPGKcyduby9dpX5Pu2GzDfXRUkoEKPBU8eJMYsVzUMKfF93He5bZCDW7ZgGD83NX0XpqzWv4V6_vbHTD2_-" - "pkixXeKyro22qx5F9UxKz61fpmP4NGepBMhJtxZ5PBu17usuJeLy16T4zu-GNPxE86FNfTNyJ__99_-9v8o_old") + "eJyNW0tz48iRrhb1lrpn2h6PfXBMMGIjvN6IHQeJN458iyJBsQlSr1uRrCFrBAIaEJAs_QHf9ifsxQeHD77t_oK27_" + "4Pvvmyl73sbROkSIBEstAR3S01VVmVlZX55ZdZpf8M__6HX_z1v3_9T0LIv_zHHz7DF7JXqpKjkjv2fJ9GP3sHn_" + "3P33LlPfiak3Vt9dnx7W1-8WdDtka-Gbg8YON8yafDfG3GfRqwOfwsNZepF1efnS0mWvy9jeeqk7PSD5Mpdfk8oO62_" + "J4pk4T8eoJYvkE-ltyAT0Ka_02-TP1hOKZpPfaLkmYk9DteKbKxryY5LrmTkDsORfYSzaFkztEGuzpD2A5iV1UV28ICWX_" + "GUFldWX12Gssm1r0ih6C7B5qnZCVFEduwR05K_oSBGd0t2y1-riqJdWzyoTRjPh9RN2_TmZdeb7-oGdl26sNew3ngp_" + "e6p8RnfrqS3djrAPSNZKnDkbPe04oJn1lIb9n5hhyU_HCIyOYkUxfrfU9OS6_MH1L-I3URfzcV4RmXS-SbsjeHIwZ3vWD-K5t4Twuzp-" + "eSDV145uUyOY48no49LPbAXxUt6xzKVXJapu7EoWM2n6Z1MIyCWIcaOSozZ8LDWeocZGk93_ntCki2sKRcJ-fl0H8AE-" + "TrdO5hdpAkbdOmyz_xHA2wQ-hMqM-37UiWcWfGYy9AXzr1KU9hDWCVvPrs5DY2VizbBNnQD90xT-" + "uobp1VftNny5fkoAyR7aL7M8U2tiIb-zNAtvQZK0ox84w75GMZ1GY8X6V-OJ9Th84QPbR4__g8V6CH5_" + "AnBJ9UsxjvYe32CdlP5Luy51Lus3_P29wN8jWIYBrwcA6BYNMhTZ-baibOrUcOyz595U463lV1_dn7FVykzs5enDud0TkWJ1KmDfuw_" + "jQM0JjXVfH53YB_esH8meJxLmkZcX63iLHo6JC8IM4p5XvQmzn8lSH2LRTX4yolclgB_cab55CDr--KS51_" + "G8koBTmnGnpONwo5Q1JzkqyB7xdyWkEB_" + "5Fyum7kJPhekYswv5bTC2bOLMDnhhTFMeQiMycZZk5W5JysqTmlqMFYPacWzZyqGDmtKOc0BeYvqDmjoINsNMaAMfAX1lGLSk7VYaxRz" + "BkgY-gwD6yjyfB9bMfzRJ7bOMdKlXyseJAo87-tstnv8j32-Lt_w85EkYV2rdTJNxXImJCD8qUflukwmgs9X1mMX5UGOX_" + "T6U0dTB9JrM8FObOfeQCpyaHuOJ1TkzkRk2-SD5XP_xWw_Phfm08ehCmGU-pmnOXTcVZpRXvxHvLNeaTHdl5a-" + "J1mSPH4NjmoTLnDkDyuauI8XrHIcYUCGfE8F7f72h9QPK90Fmtvc57F2oaWxJTE6kn5K1jfc7zZMJV3lvrr2_" + "kP8cceOa14gIT5HvhQeg8QQ-I9DMh-ZUFlkPWTPArB5Mo1rE0fWf6a-" + "WPsvGVDiIkVwLVK6NPPf6LbefvdG36vPntnJuXuAGteHgHOEM6jZpzZPfjpKxtNo2gLhw4fpedQpELC19N8twqcpQH5lLov6TgxF_" + "Ptv53ZinxG-z4rauv_nhX1-HtZKxTzStE0kmtckuPqj3zohQFHfVOVhZhQbZGjKnNn1H9I6xjnO9RGVYiLqjfjbuRRGC_" + "UNZ1k5LvqFfmwmuMN2aLxuY15jIK5Y57EGOkLxii7xsT63Ed11YQh9UJOKspbcZbmmbUKOaqNQqDKPsJdxFhfA3-" + "pzQMPr8sk4VnUGuSgNnl5DJD4lApJfEhCTEK-B2v7PPAZsu-Yc53EtCEha5MD-5FinHNPVsR1da1PjmvBlHuPKLaB_4rr-" + "jpw5Tp3t3MRWca4EY-7JPt1_iMaI5puCn2i3iJf16nzEC0iyjdqoRDLWOTU4iPfc9mcI5xTM2NOVL8i7-" + "vU91g8OXIGa4w82rZhHThr3afuKI2te7KcyC_" + "5DaddyzdK5KBBhx5aMyibfPtNOJYtkw9vPZoWdydjb5bWQdn0gRWgxXNUASd9FpFCpO7Q5ayYbSxw1vMnSNyYpir0v0YdbA9rA9A3Qk6" + "xvgTErRKPvwBbTVPj3vKYOL4bTXLS4EOgcgH1sTpcLQhjvNEGeZ-xhbejPmLu9JGGRQ4bdMEgEL5VENu3A7IhdxkqK-" + "75NLrktAFwyBwvfERyv2qu196JqY1P5GPtp5AGHqCyk39TBfNVcT5uQJxE9kPjZAMjcQ7V6IP9QQ02ow62vlqQNmJlmwc1gEOB_" + "AzBoP2ipmfW140b8n65-e_LHKrrELWBKp7jLjrLl8iBET-P-fJFi5xcQK2Qb8E_yDqGKt7rRYccg_" + "wYaBvar1ULitDXLyAfVXwPCnckFxriOviiTw4uKI8IEbKuKV53QI4uQndC_" + "TRnkzUi9K9mlZw03fEb5CP9wrhPhfYbm4BjTZ9hdRVggxhbmm1y2Jz7lKX7FjlTF9d0TahPQG9UZ7O4id1vWseyV-" + "S8yhnUlA3qj3bkcEUT-mTzE9lv-vQnTNbUlMy4bPYW8lhttmca2XHdtMHuo112V8S6g681A-q8YNzHFPvLpUWOLumMAvVN44GhZ_" + "ZUL6_I4aXnj9FekZY4c6SmveySg0v6SDHOZhSTNsP5YqtGDlrMfUFxWBXnhFaDnLZe_MnL6xzvc5maME5aF4t6fOiNcX8zVDE-" + "tJrkuMV9PqR4zaQZ4lq4BedW8Wae76X7ZJIm5pKtDvm5TaO-" + "ZIsHQdST7LAnjvQKDS2zVml1yVnH84MpgPQWbydLO8R8tNUjZzYUicjY5ZlLSV9dn3ksf0MOW-" + "EzoCrma6rYXndQS9MXqIPXBDe9Xxmqzaz93oPf0Ff6ME35zaJ_qC_lo_neafH_l9x37Qib3LddIvttit5rgP20hHw-4UoJ-" + "TI5arMhdT2kz68VhX7YrsCZLHyhHY7SeQ7qZzXzLrHdJO_bnI2mAXPnAUP7_ook7re3IdfbPs-" + "3qfuA5gBl2zc2saQNubrNh3jNLIvrt7Yd2W_uBVMPiSVNbD_gY20eTMPoFhTj0_oGn17iSHLfA3LaDn_PAElCf4Lx8WTeTONY-" + "5octmnwhHFqWS-K174jB2AzHD-LhtBmVokcWYA-oxFis6I411sVcmh5Lh15mM7inphVjdZ1xt4T1p-" + "QhWdl1aAe9lzwUjbxN9deYJWc6NVakB8sKAYndD6CQgnxi7Vtz5NxmfRp64J8bVF_PqWOI-" + "wRJziv1SJfLfHUoiM2xvswhvgOzWqTfYs6eC9OEt_7WZBXLKDmM-pv67lnqolxwK2tqI_v4PnP1LfiZoubW1fkAHaI1g-GmqFjl_" + "xqYSPmu2AmPyqZd9h3VdcUsjDM-hSdtx9wl_8UYvdHphaP7UVjQ58Hi6BHbCzuk1n20g_nzPdpOpeBvtlvL6x-" + "ZD8o4tEaXnwHYw3IyVJ_HqJ9HlncA7Cu4eypM-ZPO97BaOJa3oI8DvL0mWNxJb7js25Blv2ej9Lxu6dKiTXuFjrSlzl-X6F9QT_Suo_" + "O6TXqWGz7xBvHFGNkBzCyQ2d8iOUkTfx2olMh7zvsOV-hzhIF0LslPR4PXLjDJwzr6UiSLvSHTp18gHj6wXNWV1nIWnqMUZ0G7Ivv6E_" + "LSqZdO01y0oGCw6eTEPNftSDmcp02cE4Whf8i5NM1T3HNwbb7je9NPdZpY06oY8AGz_" + "QF6R3Gd1u4PlDHdNgjdVAc1LPt0QN5iMcQO2M97vt1BmS_w8ETUV-Q43H3kX2e8_" + "eMovejmiLez5VF9q9maC0LsW0IZbslctgFPJ6h93vi3N6tkf0ui8yA3O9t9gBSPKhbJ1-_9VC7nvPy1v7A7BS_s-g2yNdd-" + "hjSfGStVUsPOwM1lrkgZ90pd_jjIwxP-54mJ3EFr_W7LXLcpQ-" + "LR4DYXs3UWyJkjjbY2UvF6tJfjQxbWeSXS87f5ZCCGBSAVoRwzmb9QJZnFt9fdKF-" + "64bMD7zoAtdbxViiVjB23bXFY0w5s6bs2uSkC7g3h2yM3JVDTG33WDexs9sH-wI_CCdRSGL5sSi2zw05gPW3ucmb_" + "8T1bPcuOscFir1g66gZff9PJXLwieJ9eDPjDWSvRo57n_8cunzHewBNXDf0rshRz5thbzf3lILYf3o2ObSZj_bxZUNcb_" + "YG5Ge9cA7R6ebrbMyAAEU72J4nWTfvjIEe8IjeM4QAxsHUbR_Z3INdIuc2Dcd88ax3B4fVtnjUlp_" + "ZZfKVHb2J8NZNBQQ74hxtV8ipzV5GU-" + "aAc2M9SiO2XZy0YvkqObDDMdYvi94aiXWtwZk9g8HTtt5TNnrKiGwDanPuTuij52NvV7SMO3r7IrJ1hDcXzGHrd2F7STtJip64Q1qf3e" + "G2_9hNcmw73hNz8TOTDXG9breW8gC_qLwiibHBbsNeItSk-Tbz3O1c_MaBJLEOFvgBXZYuLloDG5m-b3fIkR0VstRB-J6432FD7NsQ-" + "w7G39QM3XtgPygdIMOje1cz3hTb9qoHuPBkpHeQoXuffGt__qOX73uzz3-GzNX1P__FHXHsXk-Sk33QFeVL6HJNzmpO3qbOE_" + "5WoiCuQ-3byBfArS0KlSPDcBhyolQkGfnOvoO4fvHR_pGpyWJ_vCfHtfkzjQpX1Bcz-Fq_Qr7th_5D1AWuUMjqc0F_VMt-" + "u9Kvkv3KlI7xuNiq7bbqkH6D7Pe9yY530YbQL_sX5Lg_pXx5LY1gVMb7uv4lOe3TH_kbK0ufgynuafVb5KjvPTBgDekcYMacoQ-1S5_" + "PPP_7NvAbhuSLxFiLnEdnE_2WxA6uCHolfXTp4xvnCzjRB5YwR98SibGyf0UO-h7gPsqJ435Iv0cOIz0ZUjuZX3Cn3e-" + "Tj32AFD6mY3DDvjekkROk_c_I_r2W_nWkyxN1Qoy7xVy2D9yhT_" + "kzdtaGoQljrg8x16fuK92Rg6SM330ZlMjR4CF6ls9SsnL8Owjna9mtvuKgQQ4Hk128R8xZBjbJDexSim8Vv4BvDe5Abz-M6C6C-" + "5vcZbvfN7gnp4PXIdsdX0bmvq8r5Lslj7jm7ojB19_kgynLL9_tROUYhr_Zv59zXSMn15BLX6EEQjB4T_2C-" + "9vrBvm2HHXU5lPQzp9w0T2T9AU6NcnHgb09FXpnVcicCzDgmrMAcvZ2TOwZid93uh7AOOqGNEAwTI9j56ZOvrqhjsOjpFEPg9BN3_" + "tpRvy27CZ6m7f49SksJhe1dfTZ3m2DfNdwIPqdvOUNucMgNQfAlXkA370AWs7S8kZindsWOWx5c-8J41TGzly-XPuafNt0A-" + "a7i4IEVOiw4NmDxJjmqoYhJb6P-y53NXJwx2YM4-empu_ClMX6d1DP332fqucXP1Ok-E5RWdZG6zXvozpmwaeWL_" + "MRPNqTdCLEhHuLHN7vepcV93Jx2RtyfM9nQzp8xrmwhr4Z-cf__p_7_0VkiUI") .ok()); TlBufferParser parser(&en); auto result = telegram_api::help_getCountriesList::fetch_result(parser); From 46486bd82e70fc88daa1a156f5d1485794b7821c Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 4 Nov 2021 00:21:27 +0300 Subject: [PATCH 74/82] Init disable_web_page_preview for incoming messages. --- td/telegram/MessageContent.cpp | 14 ++++++++++++- td/telegram/MessageContent.h | 2 +- td/telegram/MessagesManager.cpp | 28 +++++++++++++++---------- td/telegram/MessagesManager.h | 1 + td/telegram/SponsoredMessageManager.cpp | 5 ++++- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index ab78210d0..d7a35bcf9 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -4100,11 +4100,14 @@ unique_ptr get_secret_message_content( unique_ptr get_message_content(Td *td, FormattedText message, tl_object_ptr &&media, DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id, - int32 *ttl) { + int32 *ttl, bool *disable_web_page_preview) { if (!td->auth_manager_->was_authorized() && !G()->close_flag() && media != nullptr) { LOG(ERROR) << "Receive without authorization " << to_string(media); media = nullptr; } + if (disable_web_page_preview != nullptr) { + *disable_web_page_preview = false; + } int32 constructor_id = media == nullptr ? telegram_api::messageMediaEmpty::ID : media->get_id(); switch (constructor_id) { @@ -4112,6 +4115,9 @@ unique_ptr get_message_content(Td *td, FormattedText message, if (message.text.empty()) { LOG(ERROR) << "Receive empty message text and media for message from " << owner_dialog_id; } + if (disable_web_page_preview != nullptr) { + *disable_web_page_preview = true; + } return make_unique(std::move(message), WebPageId()); case telegram_api::messageMediaPhoto::ID: { auto message_photo = move_tl_object_as(media); @@ -4233,6 +4239,9 @@ unique_ptr get_message_content(Td *td, FormattedText message, get_input_invoice(move_tl_object_as(media), td, owner_dialog_id)); case telegram_api::messageMediaWebPage::ID: { auto media_web_page = move_tl_object_as(media); + if (disable_web_page_preview != nullptr) { + *disable_web_page_preview = (media_web_page->webpage_ == nullptr); + } auto web_page_id = td->web_pages_manager_->on_get_web_page(std::move(media_web_page->webpage_), owner_dialog_id); return make_unique(std::move(message), web_page_id); } @@ -4252,6 +4261,9 @@ unique_ptr get_message_content(Td *td, FormattedText message, } // explicit empty media message + if (disable_web_page_preview != nullptr) { + *disable_web_page_preview = true; + } return make_unique(std::move(message), WebPageId()); } diff --git a/td/telegram/MessageContent.h b/td/telegram/MessageContent.h index f75eb02fd..8e5c3bffe 100644 --- a/td/telegram/MessageContent.h +++ b/td/telegram/MessageContent.h @@ -189,7 +189,7 @@ unique_ptr get_secret_message_content( unique_ptr get_message_content(Td *td, FormattedText message_text, tl_object_ptr &&media, DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id, - int32 *ttl); + int32 *ttl, bool *disable_web_page_preview); enum class MessageContentDupType : int32 { Send, SendViaBot, Forward, Copy }; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index c67d3e100..f02c492bb 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -6643,7 +6643,6 @@ void MessagesManager::save_auth_notification_ids() { void MessagesManager::on_update_service_notification(tl_object_ptr &&update, bool skip_new_entities, Promise &&promise) { - int32 ttl = 0; bool has_date = (update->flags_ & telegram_api::updateServiceNotification::INBOX_DATE_MASK) != 0; auto date = has_date ? update->inbox_date_ : G()->unix_time(); if (date <= 0) { @@ -6666,8 +6665,10 @@ void MessagesManager::on_update_service_notification(tl_object_ptrmessage_), std::move(update->entities_), skip_new_entities, !is_user, date, false, "on_update_service_notification"); DialogId owner_dialog_id = is_user ? get_service_notifications_dialog()->dialog_id : DialogId(); + int32 ttl = 0; + bool disable_web_page_preview = false; auto content = get_message_content(td_, std::move(message_text), std::move(update->media_), owner_dialog_id, false, - UserId(), &ttl); + UserId(), &ttl, &disable_web_page_preview); bool is_content_secret = is_secret_message_content(ttl, content->get_type()); if (update->popup_) { @@ -6687,6 +6688,7 @@ void MessagesManager::on_update_service_notification(tl_object_ptrsender_user_id = dialog_id.get_user_id(); new_message->date = date; new_message->ttl = ttl; + new_message->disable_web_page_preview = disable_web_page_preview; new_message->is_content_secret = is_content_secret; new_message->content = std::move(content); new_message->have_previous = true; @@ -13593,7 +13595,7 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( message_info.forward_header ? message_info.forward_header->date_ : message_info.date, message_info.media_album_id != 0, new_source.c_str()), std::move(message->media_), message_info.dialog_id, is_content_read, message_info.via_bot_user_id, - &message_info.ttl); + &message_info.ttl, &message_info.disable_web_page_preview); message_info.reply_markup = message->flags_ & MESSAGE_FLAG_HAS_REPLY_MARKUP ? std::move(message->reply_markup_) : nullptr; message_info.restriction_reasons = get_restriction_reasons(std::move(message->restriction_reason_)); @@ -13836,6 +13838,7 @@ std::pair> MessagesManager::creat message->date = date; message->ttl_period = ttl_period; message->ttl = ttl; + message->disable_web_page_preview = message_info.disable_web_page_preview; message->edit_date = edit_date; message->random_id = message_info.random_id; message->forward_info = get_message_forward_info(std::move(message_info.forward_header)); @@ -14596,8 +14599,9 @@ void MessagesManager::on_update_sent_text_message(int64 random_id, FormattedText new_message_text = get_message_text( td_->contacts_manager_.get(), old_message_text->text, std::move(entities), true, td_->auth_manager_->is_bot(), m->forward_info ? m->forward_info->date : m->date, m->media_album_id != 0, "on_update_sent_text_message"); - auto new_content = get_message_content(td_, std::move(new_message_text), std::move(message_media), dialog_id, - true /*likely ignored*/, UserId() /*likely ignored*/, nullptr /*ignored*/); + auto new_content = + get_message_content(td_, std::move(new_message_text), std::move(message_media), dialog_id, + true /*likely ignored*/, UserId() /*likely ignored*/, nullptr /*ignored*/, nullptr); if (new_content->get_type() != MessageContentType::Text) { LOG(ERROR) << "Text message content has changed to " << new_content->get_type(); return; @@ -24755,7 +24759,7 @@ void MessagesManager::on_upload_message_media_success(DialogId dialog_id, Messag auto caption = get_message_content_caption(m->content.get()); auto content = get_message_content(td_, caption == nullptr ? FormattedText() : *caption, std::move(media), dialog_id, - false, UserId(), nullptr); + false, UserId(), nullptr, nullptr); if (update_message_content(dialog_id, m, std::move(content), true, true, true) && m->message_id == d->last_message_id) { @@ -26469,14 +26473,13 @@ void MessagesManager::unregister_message_reply(const Dialog *d, const Message *m } bool MessagesManager::get_message_disable_web_page_preview(const Message *m) { - // m->disable_web_page_preview is known only for sent from this client messages - if (m->disable_web_page_preview) { - return true; - } if (m->content->get_type() != MessageContentType::Text) { return false; } - return !has_message_content_web_page(m->content.get()); + if (has_message_content_web_page(m->content.get())) { + return false; + } + return m->disable_web_page_preview; } int32 MessagesManager::get_message_flags(const Message *m) { @@ -34626,6 +34629,9 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr // old_message->disable_notification = new_message->disable_notification; // need_send_update = true; } + if (old_message->disable_web_page_preview != new_message->disable_web_page_preview) { + old_message->disable_web_page_preview = new_message->disable_web_page_preview; + } if (!is_scheduled && update_message_contains_unread_mention(d, old_message, new_message->contains_unread_mention, "update_message")) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index d720b2644..b2c6f8572 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -969,6 +969,7 @@ class MessagesManager final : public Actor { int32 date = 0; int32 ttl_period = 0; int32 ttl = 0; + bool disable_web_page_preview = false; int64 random_id = 0; tl_object_ptr forward_header; MessageId reply_to_message_id; diff --git a/td/telegram/SponsoredMessageManager.cpp b/td/telegram/SponsoredMessageManager.cpp index 46f218fdf..519829481 100644 --- a/td/telegram/SponsoredMessageManager.cpp +++ b/td/telegram/SponsoredMessageManager.cpp @@ -261,11 +261,14 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( std::move(sponsored_message->entities_), true, true, 0, false, "on_get_dialog_sponsored_messages"); int32 ttl = 0; - auto content = get_message_content(td_, std::move(message_text), nullptr, sponsor_dialog_id, true, UserId(), &ttl); + bool disable_web_page_preview = false; + auto content = get_message_content(td_, std::move(message_text), nullptr, sponsor_dialog_id, true, UserId(), &ttl, + &disable_web_page_preview); if (ttl != 0) { LOG(ERROR) << "Receive sponsored message with TTL " << ttl; continue; } + CHECK(disable_web_page_preview); CHECK(current_sponsored_message_id_ < std::numeric_limits::max()); auto local_id = ++current_sponsored_message_id_; From 47f3363ca82f9bfbe12d59e0ef22f74997d84684 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 4 Nov 2021 09:52:27 +0300 Subject: [PATCH 75/82] Improve field names. --- td/generate/scheme/td_api.tl | 24 +++++++++++----------- td/telegram/ContactsManager.cpp | 34 ++++++++++++++++---------------- td/telegram/ContactsManager.h | 8 ++++---- td/telegram/DialogInviteLink.cpp | 14 ++++++------- td/telegram/DialogInviteLink.h | 8 ++++---- td/telegram/Td.cpp | 16 +++++++-------- td/telegram/cli.cpp | 20 +++++++++---------- 7 files changed, 62 insertions(+), 62 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 5874a45ea..e5412b01c 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -564,7 +564,7 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@description Contains a chat invite link //@invite_link Chat invite link -//@title Title of the chat invite link +//@name Name of the chat invite link //@creator_user_id User identifier of an administrator created the link //@date Point in time (Unix timestamp) when the link was created //@edit_date Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown @@ -572,10 +572,10 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@member_limit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited. Always 0 if the link requires approval //@member_count Number of chat members, which joined the chat using the link //@pending_join_request_count Number of pending join requests, created using this link -//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators. If true, total number of joining members will be unlimited -//@is_primary True, if the link is primary. Primary invite link can't have title, expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time +//@creates_join_request True, if the link only creates join request. If true, total number of joining members will be unlimited +//@is_primary True, if the link is primary. Primary invite link can't have name, expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time //@is_revoked True, if the link was revoked -chatInviteLink invite_link:string title:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 pending_join_request_count:int32 requires_approval:Bool is_primary:Bool is_revoked:Bool = ChatInviteLink; +chatInviteLink invite_link:string name:string creator_user_id:int53 date:int32 edit_date:int32 expire_date:int32 member_limit:int32 member_count:int32 pending_join_request_count:int32 creates_join_request:Bool is_primary:Bool is_revoked:Bool = ChatInviteLink; //@description Contains a list of chat invite links @total_count Approximate total count of chat invite links found @invite_links List of invite links chatInviteLinks total_count:int32 invite_links:vector = ChatInviteLinks; @@ -604,9 +604,9 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@param_description Chat description //@member_count Number of members in the chat //@member_user_ids User identifiers of some chat members that may be known to the current user -//@requires_approval True, if the user will need to be approved by chat administrators +//@creates_join_request True, if the link only creates join request //@is_public True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup -chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector requires_approval:Bool is_public:Bool = ChatInviteLinkInfo; +chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector creates_join_request:Bool is_public:Bool = ChatInviteLinkInfo; //@description Describes a user waiting administrator approval to join a chat @user_id User identifier @request_date Point in time (Unix timestamp) when the user sent the chat join request @bio A short bio of the user chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; @@ -4933,20 +4933,20 @@ replacePrimaryChatInviteLink chat_id:int53 = ChatInviteLink; //@description Creates a new invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat //@chat_id Chat identifier -//@title Invite link title; 0-32 characters +//@name Invite link name; 0-32 characters //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited -//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators. If true, member_limit must not be specified -createChatInviteLink chat_id:int53 title:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; +//@creates_join_request True, if the link only creates join request. If true, member_limit must not be specified +createChatInviteLink chat_id:int53 name:string expire_date:int32 member_limit:int32 creates_join_request:Bool = ChatInviteLink; //@description Edits a non-primary invite link for a chat. Available for basic groups, supergroups, and channels. Requires administrator privileges and can_invite_users right in the chat for own links and owner privileges for other links //@chat_id Chat identifier //@invite_link Invite link to be edited -//@title Invite link title; 0-32 characters +//@name Invite link name; 0-32 characters //@expire_date Point in time (Unix timestamp) when the link will expire; pass 0 if never //@member_limit The maximum number of chat members that can join the chat by the link simultaneously; 0-99999; pass 0 if not limited -//@requires_approval True, if users joining the chat by the link need to be approved by chat administrators. If true, member_limit must not be specified -editChatInviteLink chat_id:int53 invite_link:string title:string expire_date:int32 member_limit:int32 requires_approval:Bool = ChatInviteLink; +//@creates_join_request True, if the link only creates join request. If true, member_limit must not be specified +editChatInviteLink chat_id:int53 invite_link:string name:string expire_date:int32 member_limit:int32 creates_join_request:Bool = ChatInviteLink; //@description Returns information about an invite link. Requires administrator privileges and can_invite_users right in the chat to get own links and owner privileges to get other links //@chat_id Chat identifier diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index a7433639f..db1b00eb8 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1610,7 +1610,7 @@ class ExportChatInviteQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, const string &title, int32 expire_date, int32 usage_limit, bool requires_approval, + void send(DialogId dialog_id, const string &title, int32 expire_date, int32 usage_limit, bool creates_join_request, bool is_permanent) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); @@ -1625,7 +1625,7 @@ class ExportChatInviteQuery final : public Td::ResultHandler { if (usage_limit > 0) { flags |= telegram_api::messages_exportChatInvite::USAGE_LIMIT_MASK; } - if (requires_approval) { + if (creates_join_request) { flags |= telegram_api::messages_exportChatInvite::REQUEST_NEEDED_MASK; } if (is_permanent) { @@ -1677,7 +1677,7 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { } void send(DialogId dialog_id, const string &invite_link, const string &title, int32 expire_date, int32 usage_limit, - bool requires_approval) { + bool creates_join_request) { dialog_id_ = dialog_id; auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { @@ -1690,7 +1690,7 @@ class EditChatInviteLinkQuery final : public Td::ResultHandler { telegram_api::messages_editExportedChatInvite::TITLE_MASK; send_query(G()->net_query_creator().create( telegram_api::messages_editExportedChatInvite(flags, false /*ignored*/, std::move(input_peer), invite_link, - expire_date, usage_limit, requires_approval, title))); + expire_date, usage_limit, creates_join_request, title))); } void on_result(uint64 id, BufferSlice packet) final { @@ -7440,40 +7440,40 @@ Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool } void ContactsManager::export_dialog_invite_link(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit, - bool requires_approval, bool is_permanent, + bool creates_join_request, bool is_permanent, Promise> &&promise) { get_me(PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, title = std::move(title), expire_date, - usage_limit, requires_approval, is_permanent, + usage_limit, creates_join_request, is_permanent, promise = std::move(promise)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { send_closure(actor_id, &ContactsManager::export_dialog_invite_link_impl, dialog_id, std::move(title), expire_date, - usage_limit, requires_approval, is_permanent, std::move(promise)); + usage_limit, creates_join_request, is_permanent, std::move(promise)); } })); } void ContactsManager::export_dialog_invite_link_impl(DialogId dialog_id, string title, int32 expire_date, - int32 usage_limit, bool requires_approval, bool is_permanent, + int32 usage_limit, bool creates_join_request, bool is_permanent, Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); - if (requires_approval && usage_limit > 0) { + if (creates_join_request && usage_limit > 0) { return promise.set_error( Status::Error(400, "Member limit can't be specified for links requiring administrator approval")); } auto new_title = clean_name(std::move(title), MAX_INVITE_LINK_TITLE_LENGTH); td_->create_handler(std::move(promise)) - ->send(dialog_id, new_title, expire_date, usage_limit, requires_approval, is_permanent); + ->send(dialog_id, new_title, expire_date, usage_limit, creates_join_request, is_permanent); } void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string &invite_link, string title, - int32 expire_date, int32 usage_limit, bool requires_approval, + int32 expire_date, int32 usage_limit, bool creates_join_request, Promise> &&promise) { TRY_STATUS_PROMISE(promise, can_manage_dialog_invite_links(dialog_id)); - if (requires_approval && usage_limit > 0) { + if (creates_join_request && usage_limit > 0) { return promise.set_error( Status::Error(400, "Member limit can't be specified for links requiring administrator approval")); } @@ -7484,7 +7484,7 @@ void ContactsManager::edit_dialog_invite_link(DialogId dialog_id, const string & auto new_title = clean_name(std::move(title), MAX_INVITE_LINK_TITLE_LENGTH); td_->create_handler(std::move(promise)) - ->send(dialog_id, invite_link, new_title, expire_date, requires_approval, usage_limit); + ->send(dialog_id, invite_link, new_title, expire_date, creates_join_request, usage_limit); } void ContactsManager::get_dialog_invite_link(DialogId dialog_id, const string &invite_link, @@ -12774,7 +12774,7 @@ void ContactsManager::on_get_dialog_invite_link_info(const string &invite_link, invite_link_info->description = std::move(chat_invite->about_); invite_link_info->participant_count = chat_invite->participants_count_; invite_link_info->participant_user_ids = std::move(participant_user_ids); - invite_link_info->requires_approval = std::move(chat_invite->request_needed_); + invite_link_info->creates_join_request = std::move(chat_invite->request_needed_); invite_link_info->is_chat = (chat_invite->flags_ & CHAT_INVITE_FLAG_IS_CHANNEL) == 0; invite_link_info->is_channel = (chat_invite->flags_ & CHAT_INVITE_FLAG_IS_CHANNEL) != 0; @@ -16215,7 +16215,7 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ string description; int32 participant_count = 0; vector member_user_ids; - bool requires_approval = false; + bool creates_join_request = false; bool is_public = false; bool is_member = false; td_api::object_ptr chat_type; @@ -16268,7 +16268,7 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ description = invite_link_info->description; participant_count = invite_link_info->participant_count; member_user_ids = get_user_ids_object(invite_link_info->participant_user_ids, "get_chat_invite_link_info_object"); - requires_approval = invite_link_info->requires_approval; + creates_join_request = invite_link_info->creates_join_request; is_public = invite_link_info->is_public; if (invite_link_info->is_chat) { @@ -16292,7 +16292,7 @@ tl_object_ptr ContactsManager::get_chat_invite_link_ return make_tl_object(dialog_id.get(), accessible_for, std::move(chat_type), title, get_chat_photo_info_object(td_->file_manager_.get(), photo), description, participant_count, std::move(member_user_ids), - requires_approval, is_public); + creates_join_request, is_public); } UserId ContactsManager::get_support_user(Promise &&promise) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index abff47b0e..574f905dd 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -387,11 +387,11 @@ class ContactsManager final : public Actor { void transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, Promise &&promise); void export_dialog_invite_link(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit, - bool requires_approval, bool is_permanent, + bool creates_join_request, bool is_permanent, Promise> &&promise); void edit_dialog_invite_link(DialogId dialog_id, const string &link, string title, int32 expire_date, - int32 usage_limit, bool requires_approval, + int32 usage_limit, bool creates_join_request, Promise> &&promise); void get_dialog_invite_link(DialogId dialog_id, const string &invite_link, @@ -943,7 +943,7 @@ class ContactsManager final : public Actor { string description; int32 participant_count = 0; vector participant_user_ids; - bool requires_approval = false; + bool creates_join_request = false; bool is_chat = false; bool is_channel = false; bool is_public = false; @@ -1406,7 +1406,7 @@ class ContactsManager final : public Actor { static bool is_channel_public(const Channel *c); void export_dialog_invite_link_impl(DialogId dialog_id, string title, int32 expire_date, int32 usage_limit, - bool requires_approval, bool is_permanent, + bool creates_join_request, bool is_permanent, Promise> &&promise); void remove_dialog_access_by_invite_link(DialogId dialog_id); diff --git a/td/telegram/DialogInviteLink.cpp b/td/telegram/DialogInviteLink.cpp index 6ab4ba74c..ef72dfea9 100644 --- a/td/telegram/DialogInviteLink.cpp +++ b/td/telegram/DialogInviteLink.cpp @@ -27,7 +27,7 @@ DialogInviteLink::DialogInviteLink(tl_object_ptrusage_; edit_date_ = exported_invite->start_date_; request_count_ = exported_invite->requested_; - requires_approval_ = exported_invite->request_needed_; + creates_join_request_ = exported_invite->request_needed_; is_revoked_ = exported_invite->revoked_; is_permanent_ = exported_invite->permanent_; @@ -62,16 +62,16 @@ DialogInviteLink::DialogInviteLink(tl_object_ptr 0 || usage_limit_ > 0 || edit_date_ > 0 || - request_count_ > 0 || requires_approval_)) { + request_count_ > 0 || creates_join_request_)) { LOG(ERROR) << "Receive wrong permanent " << *this; title_.clear(); expire_date_ = 0; usage_limit_ = 0; edit_date_ = 0; request_count_ = 0; - requires_approval_ = false; + creates_join_request_ = false; } - if (requires_approval_ && usage_limit_ > 0) { + if (creates_join_request_ && usage_limit_ > 0) { LOG(ERROR) << "Receive wrong permanent " << *this; usage_limit_ = 0; } @@ -90,7 +90,7 @@ td_api::object_ptr DialogInviteLink::get_chat_invite_lin return td_api::make_object( invite_link_, title_, contacts_manager->get_user_id_object(creator_user_id_, "get_chat_invite_link_object"), - date_, edit_date_, expire_date_, usage_limit_, usage_count_, request_count_, requires_approval_, is_permanent_, + date_, edit_date_, expire_date_, usage_limit_, usage_count_, request_count_, creates_join_request_, is_permanent_, is_revoked_); } @@ -99,7 +99,7 @@ bool operator==(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { lhs.creator_user_id_ == rhs.creator_user_id_ && lhs.date_ == rhs.date_ && lhs.edit_date_ == rhs.edit_date_ && lhs.expire_date_ == rhs.expire_date_ && lhs.usage_limit_ == rhs.usage_limit_ && lhs.usage_count_ == rhs.usage_count_ && lhs.request_count_ == rhs.request_count_ && - lhs.requires_approval_ == rhs.requires_approval_ && lhs.is_permanent_ == rhs.is_permanent_ && + lhs.creates_join_request_ == rhs.creates_join_request_ && lhs.is_permanent_ == rhs.is_permanent_ && lhs.is_revoked_ == rhs.is_revoked_; } @@ -109,7 +109,7 @@ bool operator!=(const DialogInviteLink &lhs, const DialogInviteLink &rhs) { StringBuilder &operator<<(StringBuilder &string_builder, const DialogInviteLink &invite_link) { return string_builder << "ChatInviteLink[" << invite_link.invite_link_ << '(' << invite_link.title_ << ')' - << (invite_link.requires_approval_ ? " requiring approval" : "") << " by " + << (invite_link.creates_join_request_ ? " creating join request" : "") << " by " << invite_link.creator_user_id_ << " created at " << invite_link.date_ << " edited at " << invite_link.edit_date_ << " expiring at " << invite_link.expire_date_ << " used by " << invite_link.usage_count_ << " with usage limit " << invite_link.usage_limit_ << " and " diff --git a/td/telegram/DialogInviteLink.h b/td/telegram/DialogInviteLink.h index 5d020f421..86f12ca04 100644 --- a/td/telegram/DialogInviteLink.h +++ b/td/telegram/DialogInviteLink.h @@ -29,7 +29,7 @@ class DialogInviteLink { int32 usage_limit_ = 0; int32 usage_count_ = 0; int32 request_count_ = 0; - bool requires_approval_ = false; + bool creates_join_request_ = false; bool is_revoked_ = false; bool is_permanent_ = false; @@ -79,7 +79,7 @@ class DialogInviteLink { STORE_FLAG(has_usage_count); STORE_FLAG(has_edit_date); STORE_FLAG(has_request_count); - STORE_FLAG(requires_approval_); + STORE_FLAG(creates_join_request_); STORE_FLAG(has_title); END_STORE_FLAGS(); store(invite_link_, storer); @@ -122,7 +122,7 @@ class DialogInviteLink { PARSE_FLAG(has_usage_count); PARSE_FLAG(has_edit_date); PARSE_FLAG(has_request_count); - PARSE_FLAG(requires_approval_); + PARSE_FLAG(creates_join_request_); PARSE_FLAG(has_title); END_PARSE_FLAGS(); parse(invite_link_, parser); @@ -146,7 +146,7 @@ class DialogInviteLink { if (has_title) { parse(title_, parser); } - if (requires_approval_) { + if (creates_join_request_) { usage_limit_ = 0; } } diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 61d1e958d..2509d2e6d 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6350,20 +6350,20 @@ void Td::on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &reque } void Td::on_request(uint64 id, td_api::createChatInviteLink &request) { - CLEAN_INPUT_STRING(request.title_); + CLEAN_INPUT_STRING(request.name_); CREATE_REQUEST_PROMISE(); - contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), std::move(request.title_), - request.expire_date_, request.member_limit_, request.requires_approval_, - false, std::move(promise)); + contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), std::move(request.name_), + request.expire_date_, request.member_limit_, + request.creates_join_request_, false, std::move(promise)); } void Td::on_request(uint64 id, td_api::editChatInviteLink &request) { - CLEAN_INPUT_STRING(request.title_); + CLEAN_INPUT_STRING(request.name_); CLEAN_INPUT_STRING(request.invite_link_); CREATE_REQUEST_PROMISE(); - contacts_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, - std::move(request.title_), request.expire_date_, request.member_limit_, - request.requires_approval_, std::move(promise)); + contacts_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, std::move(request.name_), + request.expire_date_, request.member_limit_, request.creates_join_request_, + std::move(promise)); } void Td::on_request(uint64 id, td_api::getChatInviteLink &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index bc69d2917..bdfbced33 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2954,23 +2954,23 @@ class CliClient final : public Actor { send_request(td_api::make_object(as_chat_id(chat_id))); } else if (op == "ccilt") { string chat_id; - string title; + string name; int32 expire_date; int32 member_limit; - bool requires_approval; - get_args(args, chat_id, title, expire_date, member_limit, requires_approval); - send_request(td_api::make_object(as_chat_id(chat_id), title, expire_date, - member_limit, requires_approval)); + bool creates_join_request; + get_args(args, chat_id, name, expire_date, member_limit, creates_join_request); + send_request(td_api::make_object(as_chat_id(chat_id), name, expire_date, + member_limit, creates_join_request)); } else if (op == "ecil") { string chat_id; string invite_link; - string title; + string name; int32 expire_date; int32 member_limit; - bool requires_approval; - get_args(args, chat_id, invite_link, title, expire_date, member_limit, requires_approval); - send_request(td_api::make_object(as_chat_id(chat_id), invite_link, title, expire_date, - member_limit, requires_approval)); + bool creates_join_request; + get_args(args, chat_id, invite_link, name, expire_date, member_limit, creates_join_request); + send_request(td_api::make_object(as_chat_id(chat_id), invite_link, name, expire_date, + member_limit, creates_join_request)); } else if (op == "rcil") { string chat_id; string invite_link; From eb2c0c9315dad89f67dacb752ff1001d9e464c55 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 4 Nov 2021 11:41:07 +0300 Subject: [PATCH 76/82] Check for is_bot just in case. --- td/telegram/StickersManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index ee1e44856..33a139133 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -4314,7 +4314,7 @@ void StickersManager::get_animated_emoji(string emoji, bool is_recursive, void StickersManager::get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, Promise> &&promise) { - if (disable_animated_emojis_) { + if (disable_animated_emojis_ || td_->auth_manager_->is_bot()) { return promise.set_value(nullptr); } @@ -4379,7 +4379,7 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic return promise.set_error(Status::Error(400, "Message is not an animated emoji message")); } - if (disable_animated_emojis_) { + if (disable_animated_emojis_ || td_->auth_manager_->is_bot()) { return promise.set_value(nullptr); } @@ -4657,7 +4657,7 @@ void StickersManager::schedule_update_animated_emoji_clicked(const StickerSet *s } void StickersManager::send_update_animated_emoji_clicked(FullMessageId full_message_id, FileId sticker_id) { - if (G()->close_flag() || disable_animated_emojis_) { + if (G()->close_flag() || disable_animated_emojis_ || td_->auth_manager_->is_bot()) { return; } if (td_->messages_manager_->is_message_edited_recently(full_message_id, 2)) { From ca7947cf44c429d962002b9a28e85b3d75e51138 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 4 Nov 2021 12:46:08 +0300 Subject: [PATCH 77/82] Minor improvements. --- benchmark/bench_actor.cpp | 1 - benchmark/bench_http.cpp | 1 + benchmark/bench_http_server.cpp | 1 + benchmark/bench_queue.cpp | 2 -- td/telegram/DocumentsManager.cpp | 1 + td/telegram/SponsoredMessageManager.cpp | 1 + td/telegram/StickersManager.cpp | 2 ++ tdactor/td/actor/impl/Scheduler.h | 2 -- tdnet/td/net/HttpInboundConnection.h | 1 + tdnet/td/net/HttpOutboundConnection.h | 1 + tdnet/td/net/Wget.cpp | 1 + tdutils/CMakeLists.txt | 1 + tdutils/td/utils/TlStorerToString.h | 1 + tdutils/td/utils/tl_storers.h | 1 - test/mtproto.cpp | 1 + 15 files changed, 12 insertions(+), 6 deletions(-) diff --git a/benchmark/bench_actor.cpp b/benchmark/bench_actor.cpp index 338442c62..82c88cfdd 100644 --- a/benchmark/bench_actor.cpp +++ b/benchmark/bench_actor.cpp @@ -43,7 +43,6 @@ class td::ActorTraits { }; class CreateActorBench final : public td::Benchmark { - private: td::ConcurrentScheduler scheduler_; void start_up() final { diff --git a/benchmark/bench_http.cpp b/benchmark/bench_http.cpp index 5fc8ba1f3..9e468f025 100644 --- a/benchmark/bench_http.cpp +++ b/benchmark/bench_http.cpp @@ -12,6 +12,7 @@ #include "td/actor/ConcurrentScheduler.h" #include "td/utils/buffer.h" +#include "td/utils/BufferedFd.h" #include "td/utils/logging.h" #include "td/utils/port/IPAddress.h" #include "td/utils/port/SocketFd.h" diff --git a/benchmark/bench_http_server.cpp b/benchmark/bench_http_server.cpp index 4351f03a5..88fef3814 100644 --- a/benchmark/bench_http_server.cpp +++ b/benchmark/bench_http_server.cpp @@ -13,6 +13,7 @@ #include "td/actor/ConcurrentScheduler.h" #include "td/utils/buffer.h" +#include "td/utils/BufferedFd.h" #include "td/utils/logging.h" #include "td/utils/port/SocketFd.h" #include "td/utils/Slice.h" diff --git a/benchmark/bench_queue.cpp b/benchmark/bench_queue.cpp index 2fc85bbf9..6205f37bb 100644 --- a/benchmark/bench_queue.cpp +++ b/benchmark/bench_queue.cpp @@ -17,8 +17,6 @@ // TODO: all return values must be checked #include -#include -#include #if TD_PORT_POSIX #include diff --git a/td/telegram/DocumentsManager.cpp b/td/telegram/DocumentsManager.cpp index c40a210a3..f81a38349 100644 --- a/td/telegram/DocumentsManager.cpp +++ b/td/telegram/DocumentsManager.cpp @@ -17,6 +17,7 @@ #include "td/telegram/misc.h" #include "td/telegram/net/DcId.h" #include "td/telegram/Photo.h" +#include "td/telegram/PhotoSizeSource.h" #include "td/telegram/secret_api.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" diff --git a/td/telegram/SponsoredMessageManager.cpp b/td/telegram/SponsoredMessageManager.cpp index 519829481..0fce4c90e 100644 --- a/td/telegram/SponsoredMessageManager.cpp +++ b/td/telegram/SponsoredMessageManager.cpp @@ -21,6 +21,7 @@ #include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/logging.h" +#include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" #include diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 33a139133..c4b959e68 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -26,6 +26,7 @@ #include "td/telegram/net/DcId.h" #include "td/telegram/net/MtprotoHeader.h" #include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/PhotoSizeSource.h" #include "td/telegram/secret_api.h" #include "td/telegram/StickerSetId.hpp" #include "td/telegram/StickersManager.hpp" @@ -43,6 +44,7 @@ #include "td/actor/SleepActor.h" #include "td/utils/algorithm.h" +#include "td/utils/base64.h" #include "td/utils/emoji.h" #include "td/utils/format.h" #include "td/utils/JsonBuilder.h" diff --git a/tdactor/td/actor/impl/Scheduler.h b/tdactor/td/actor/impl/Scheduler.h index 715960e7a..94c9b8f99 100644 --- a/tdactor/td/actor/impl/Scheduler.h +++ b/tdactor/td/actor/impl/Scheduler.h @@ -12,7 +12,6 @@ #include "td/utils/common.h" #include "td/utils/Heap.h" #include "td/utils/logging.h" -#include "td/utils/MpscPollableQueue.h" #include "td/utils/ObjectPool.h" #include "td/utils/port/detail/PollableFd.h" #include "td/utils/port/PollFlags.h" @@ -20,7 +19,6 @@ #include "td/utils/Time.h" #include -#include #include #include diff --git a/tdnet/td/net/HttpInboundConnection.h b/tdnet/td/net/HttpInboundConnection.h index 31e2633bf..4073792d2 100644 --- a/tdnet/td/net/HttpInboundConnection.h +++ b/tdnet/td/net/HttpInboundConnection.h @@ -11,6 +11,7 @@ #include "td/actor/actor.h" +#include "td/utils/BufferedFd.h" #include "td/utils/port/SocketFd.h" #include "td/utils/Status.h" diff --git a/tdnet/td/net/HttpOutboundConnection.h b/tdnet/td/net/HttpOutboundConnection.h index 900489026..f9ed2a2cb 100644 --- a/tdnet/td/net/HttpOutboundConnection.h +++ b/tdnet/td/net/HttpOutboundConnection.h @@ -12,6 +12,7 @@ #include "td/actor/actor.h" +#include "td/utils/BufferedFd.h" #include "td/utils/port/SocketFd.h" #include "td/utils/Status.h" diff --git a/tdnet/td/net/Wget.cpp b/tdnet/td/net/Wget.cpp index 6873aca0e..5912f1f4a 100644 --- a/tdnet/td/net/Wget.cpp +++ b/tdnet/td/net/Wget.cpp @@ -11,6 +11,7 @@ #include "td/net/SslStream.h" #include "td/utils/buffer.h" +#include "td/utils/BufferedFd.h" #include "td/utils/HttpUrl.h" #include "td/utils/logging.h" #include "td/utils/misc.h" diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index dda68f389..039d5802d 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -262,6 +262,7 @@ set(TDUTILS_SOURCE td/utils/tl_parsers.h td/utils/tl_storers.h td/utils/TlDowncastHelper.h + td/utils/TlStorerToString.h td/utils/translit.h td/utils/TsCerr.h td/utils/TsFileLog.h diff --git a/tdutils/td/utils/TlStorerToString.h b/tdutils/td/utils/TlStorerToString.h index 512378c38..a8578b965 100644 --- a/tdutils/td/utils/TlStorerToString.h +++ b/tdutils/td/utils/TlStorerToString.h @@ -7,6 +7,7 @@ #pragma once #include "td/utils/common.h" +#include "td/utils/SharedSlice.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" #include "td/utils/UInt.h" diff --git a/tdutils/td/utils/tl_storers.h b/tdutils/td/utils/tl_storers.h index c8920547b..e5870551c 100644 --- a/tdutils/td/utils/tl_storers.h +++ b/tdutils/td/utils/tl_storers.h @@ -8,7 +8,6 @@ #include "td/utils/common.h" #include "td/utils/logging.h" -#include "td/utils/SharedSlice.h" #include "td/utils/Slice.h" #include "td/utils/StorerBase.h" diff --git a/test/mtproto.cpp b/test/mtproto.cpp index 11fc2e724..a9a0cb09c 100644 --- a/test/mtproto.cpp +++ b/test/mtproto.cpp @@ -32,6 +32,7 @@ #include "td/actor/PromiseFuture.h" #include "td/utils/base64.h" +#include "td/utils/BufferedFd.h" #include "td/utils/common.h" #include "td/utils/crypto.h" #include "td/utils/logging.h" From e57e938e56d443c69d770430236a831b2fc33ece Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 4 Nov 2021 13:01:20 +0300 Subject: [PATCH 78/82] Improve documentation. --- td/generate/scheme/td_api.tl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e5412b01c..ac5d5a80d 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -564,14 +564,14 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@description Contains a chat invite link //@invite_link Chat invite link -//@name Name of the chat invite link +//@name Name of the link //@creator_user_id User identifier of an administrator created the link //@date Point in time (Unix timestamp) when the link was created //@edit_date Point in time (Unix timestamp) when the link was last edited; 0 if never or unknown //@expire_date Point in time (Unix timestamp) when the link will expire; 0 if never //@member_limit The maximum number of members, which can join the chat using the link simultaneously; 0 if not limited. Always 0 if the link requires approval //@member_count Number of chat members, which joined the chat using the link -//@pending_join_request_count Number of pending join requests, created using this link +//@pending_join_request_count Number of pending join requests created using this link //@creates_join_request True, if the link only creates join request. If true, total number of joining members will be unlimited //@is_primary True, if the link is primary. Primary invite link can't have name, expire date or usage limit. There is exactly one primary invite link for each administrator with can_invite_users right at a given time //@is_revoked True, if the link was revoked @@ -608,13 +608,13 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@is_public True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector creates_join_request:Bool is_public:Bool = ChatInviteLinkInfo; -//@description Describes a user waiting administrator approval to join a chat @user_id User identifier @request_date Point in time (Unix timestamp) when the user sent the chat join request @bio A short bio of the user +//@description Describes a user that sent a join request and waits for administrator approval @user_id User identifier @request_date Point in time (Unix timestamp) when the user sent the join request @bio A short bio of the user chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; //@description Contains a list of chat join requests @total_count Approximate total count of requests found @requests List of the requests chatJoinRequests total_count:int32 requests:vector = ChatJoinRequests; -//@description Contains information about pending chat join requests @total_count Number of pending join requests, which wait administrator approval @user_ids List of identifiers, of users with newest pending requests +//@description Contains information about pending chat join requests @total_count Total number of pending join requests @user_ids Identifiers of users sent the newest pending join requests chatJoinRequestsInfo total_count:int32 user_ids:vector = ChatJoinRequestsInfo; From 8bc413742d2352dad2b7a2e060fc543c5b5fd96c Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 4 Nov 2021 13:13:52 +0300 Subject: [PATCH 79/82] Simplify field name. --- td/generate/scheme/td_api.tl | 4 ++-- td/telegram/ContactsManager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index ac5d5a80d..ab4e66ffd 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -608,8 +608,8 @@ chatInviteLinkMembers total_count:int32 members:vector = C //@is_public True, if the chat is a public supergroup or channel, i.e. it has a username or it is a location-based supergroup chatInviteLinkInfo chat_id:int53 accessible_for:int32 type:ChatType title:string photo:chatPhotoInfo description:string member_count:int32 member_user_ids:vector creates_join_request:Bool is_public:Bool = ChatInviteLinkInfo; -//@description Describes a user that sent a join request and waits for administrator approval @user_id User identifier @request_date Point in time (Unix timestamp) when the user sent the join request @bio A short bio of the user -chatJoinRequest user_id:int53 request_date:int32 bio:string = ChatJoinRequest; +//@description Describes a user that sent a join request and waits for administrator approval @user_id User identifier @date Point in time (Unix timestamp) when the user sent the join request @bio A short bio of the user +chatJoinRequest user_id:int53 date:int32 bio:string = ChatJoinRequest; //@description Contains a list of chat join requests @total_count Approximate total count of requests found @requests List of the requests chatJoinRequests total_count:int32 requests:vector = ChatJoinRequests; diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index db1b00eb8..7b0adf0f8 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -7559,7 +7559,7 @@ void ContactsManager::get_dialog_join_requests(DialogId dialog_id, const string int32 offset_date = 0; if (offset_request != nullptr) { offset_user_id = UserId(offset_request->user_id_); - offset_date = offset_request->request_date_; + offset_date = offset_request->date_; } td_->create_handler(std::move(promise)) From b7cf2e578d730f52dfeeaccbc4fa90b3a02f09a7 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 5 Nov 2021 03:31:48 +0300 Subject: [PATCH 80/82] Save reference to UpdatesManager in promise. --- td/telegram/UpdatesManager.cpp | 26 ++++++++++++++++++++++++-- td/telegram/UpdatesManager.h | 9 ++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index edaf2400b..d783ef8c1 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -176,6 +176,28 @@ void UpdatesManager::tear_down() { parent_.reset(); } +void UpdatesManager::hangup_shared() { + ref_cnt_--; + if (ref_cnt_ == 0) { + stop(); + } +} + +void UpdatesManager::hangup() { + pending_pts_updates_.clear(); + postponed_pts_updates_.clear(); + postponed_updates_.clear(); + pending_seq_updates_.clear(); + pending_qts_updates_.clear(); + + hangup_shared(); +} + +ActorShared UpdatesManager::create_reference() { + ref_cnt_++; + return actor_shared(this, 1); +} + void UpdatesManager::fill_pts_gap(void *td) { CHECK(td != nullptr); if (G()->close_flag()) { @@ -1652,7 +1674,7 @@ void UpdatesManager::on_pending_updates(vector &&result) mutable { + mpas.add_promise([actor_id = create_reference(), promise = std::move(promise)](Result &&result) mutable { send_closure(actor_id, &UpdatesManager::on_pending_updates_processed, std::move(result), std::move(promise)); }); auto lock = mpas.get_promise(); @@ -1773,7 +1795,7 @@ void UpdatesManager::on_pending_updates(vector &&result, Promise &&promise) { +void UpdatesManager::on_pending_updates_processed(Result result, Promise promise) { promise.set_result(std::move(result)); } diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index 96a619498..ee80cc0d6 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -181,6 +181,7 @@ class UpdatesManager final : public Actor { Td *td_; ActorShared<> parent_; + int32 ref_cnt_ = 1; PtsManager pts_manager_; PtsManager qts_manager_; @@ -225,6 +226,12 @@ class UpdatesManager final : public Actor { void tear_down() final; + void hangup_shared() final; + + void hangup() final; + + ActorShared create_reference(); + int32 get_pts() const { return pts_manager_.mem_pts(); } @@ -268,7 +275,7 @@ class UpdatesManager final : public Actor { void on_pending_updates(vector> &&updates, int32 seq_begin, int32 seq_end, int32 date, double receive_time, Promise &&promise, const char *source); - void on_pending_updates_processed(Result &&result, Promise &&promise); + void on_pending_updates_processed(Result result, Promise promise); void process_updates(vector> &&updates, bool force_apply, Promise &&promise); From 7d41d9eaa58a6e0927806283252dc9e74eda5512 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 5 Nov 2021 03:34:52 +0300 Subject: [PATCH 81/82] Update version to 1.7.9. --- CMakeLists.txt | 2 +- README.md | 2 +- example/cpp/CMakeLists.txt | 2 +- example/uwp/extension.vsixmanifest | 2 +- td/telegram/Td.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6dd54fe78..2f33e5fbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ if (POLICY CMP0065) cmake_policy(SET CMP0065 NEW) endif() -project(TDLib VERSION 1.7.8 LANGUAGES CXX C) +project(TDLib VERSION 1.7.9 LANGUAGES CXX C) if (NOT DEFINED CMAKE_MODULE_PATH) set(CMAKE_MODULE_PATH "") diff --git a/README.md b/README.md index d2b8a62a5..46902f446 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ target_link_libraries(YourTarget PRIVATE Td::TdStatic) Or you could install `TDLib` and then reference it in your CMakeLists.txt like this: ``` -find_package(Td 1.7.8 REQUIRED) +find_package(Td 1.7.9 REQUIRED) target_link_libraries(YourTarget PRIVATE Td::TdStatic) ``` See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt). diff --git a/example/cpp/CMakeLists.txt b/example/cpp/CMakeLists.txt index b3c6878a0..585ba56b4 100644 --- a/example/cpp/CMakeLists.txt +++ b/example/cpp/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.4 FATAL_ERROR) project(TdExample VERSION 1.0 LANGUAGES CXX) -find_package(Td 1.7.8 REQUIRED) +find_package(Td 1.7.9 REQUIRED) add_executable(tdjson_example tdjson_example.cpp) target_link_libraries(tdjson_example PRIVATE Td::TdJson) diff --git a/example/uwp/extension.vsixmanifest b/example/uwp/extension.vsixmanifest index ffc5a2b06..d058a8005 100644 --- a/example/uwp/extension.vsixmanifest +++ b/example/uwp/extension.vsixmanifest @@ -1,6 +1,6 @@ - + TDLib for Universal Windows Platform TDLib is a library for building Telegram clients https://core.telegram.org/tdlib diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 9d1be0fd3..3427f8c51 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -244,7 +244,7 @@ class Td final : public Actor { static td_api::object_ptr static_request(td_api::object_ptr function); private: - static constexpr const char *TDLIB_VERSION = "1.7.8"; + static constexpr const char *TDLIB_VERSION = "1.7.9"; static constexpr int64 ONLINE_ALARM_ID = 0; static constexpr int64 PING_SERVER_ALARM_ID = -1; static constexpr int32 PING_SERVER_TIMEOUT = 300; From eb346f5573040803d4424049dd2ba8aaa039fa56 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 5 Nov 2021 10:10:11 +0300 Subject: [PATCH 82/82] Return both first and last error from mkpath. --- tdutils/td/utils/port/path.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tdutils/td/utils/port/path.cpp b/tdutils/td/utils/port/path.cpp index b256ca57f..d7c705597 100644 --- a/tdutils/td/utils/port/path.cpp +++ b/tdutils/td/utils/port/path.cpp @@ -75,7 +75,10 @@ Status mkpath(CSlice path, int32 mode) { } } if (last_error.is_error()) { - return first_error; + if (last_error.message() == first_error.message() && last_error.code() == first_error.code()) { + return first_error; + } + return last_error.move_as_error_suffix(PSLICE() << ": " << first_error); } return Status::OK(); }