From 191b4ee5d55c49f6824ac65704ec1f878e43204e Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 01:09:59 +0300 Subject: [PATCH 01/16] Add empty OptionManager. --- CMakeLists.txt | 2 ++ SplitSource.php | 1 + td/telegram/OptionManager.cpp | 20 ++++++++++++++++++++ td/telegram/OptionManager.h | 34 ++++++++++++++++++++++++++++++++++ td/telegram/Td.cpp | 9 ++++++++- td/telegram/Td.h | 3 +++ 6 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 td/telegram/OptionManager.cpp create mode 100644 td/telegram/OptionManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c36803e6..56b77d61a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -385,6 +385,7 @@ set(TDLIB_SOURCE td/telegram/NotificationManager.cpp td/telegram/NotificationSettings.cpp td/telegram/NotificationType.cpp + td/telegram/OptionManager.cpp td/telegram/Payments.cpp td/telegram/PasswordManager.cpp td/telegram/PhoneNumberManager.cpp @@ -599,6 +600,7 @@ set(TDLIB_SOURCE td/telegram/NotificationManager.h td/telegram/NotificationSettings.h td/telegram/NotificationType.h + td/telegram/OptionManager.h td/telegram/PasswordManager.h td/telegram/Payments.h td/telegram/PhoneNumberManager.h diff --git a/SplitSource.php b/SplitSource.php index 9ba0e74e7..1000b88ac 100644 --- a/SplitSource.php +++ b/SplitSource.php @@ -297,6 +297,7 @@ function split_file($file, $chunks, $undo) { 'MessageCopyOptions' => 'MessageCopyOptions', 'messages_manager[_(-][^.]|MessagesManager' => 'MessagesManager', 'notification_manager[_(-][^.]|NotificationManager|notifications[)]' => 'NotificationManager', + 'option_manager[_(-][^.]|OptionManager' => "OptionManager", 'phone_number_manager[_(-][^.]|PhoneNumberManager' => "PhoneNumberManager", 'poll_manager[_(-][^.]|PollManager' => "PollManager", 'PublicDialogType|get_public_dialog_type' => 'PublicDialogType', diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp new file mode 100644 index 000000000..bf42caeb4 --- /dev/null +++ b/td/telegram/OptionManager.cpp @@ -0,0 +1,20 @@ +// +// 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) +// +#include "td/telegram/OptionManager.h" + +namespace td { + +OptionManager::OptionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void OptionManager::tear_down() { + parent_.reset(); +} + +OptionManager::~OptionManager() = default; + +} // namespace td diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h new file mode 100644 index 000000000..dd1451986 --- /dev/null +++ b/td/telegram/OptionManager.h @@ -0,0 +1,34 @@ +// +// 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/actor/actor.h" + +#include "td/utils/common.h" + +namespace td { + +class Td; + +class OptionManager final : public Actor { + public: + OptionManager(Td *td, ActorShared<> parent); + + OptionManager(const OptionManager &) = delete; + OptionManager &operator=(const OptionManager &) = delete; + OptionManager(OptionManager &&) = delete; + OptionManager &operator=(OptionManager &&) = delete; + ~OptionManager() final; + + private: + void tear_down() final; + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 276132c23..0cb984a42 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -80,6 +80,7 @@ #include "td/telegram/NotificationId.h" #include "td/telegram/NotificationManager.h" #include "td/telegram/NotificationSettings.h" +#include "td/telegram/OptionManager.h" #include "td/telegram/PasswordManager.h" #include "td/telegram/Payments.h" #include "td/telegram/PhoneNumberManager.h" @@ -3556,6 +3557,8 @@ void Td::dec_actor_refcnt() { LOG(DEBUG) << "MessagesManager was cleared" << timer; notification_manager_.reset(); LOG(DEBUG) << "NotificationManager was cleared" << timer; + option_manager_.reset(); + LOG(DEBUG) << "OptionManager was cleared" << timer; poll_manager_.reset(); LOG(DEBUG) << "PollManager was cleared" << timer; sponsored_message_manager_.reset(); @@ -3746,6 +3749,8 @@ void Td::clear() { LOG(DEBUG) << "MessagesManager actor was cleared" << timer; notification_manager_actor_.reset(); LOG(DEBUG) << "NotificationManager actor was cleared" << timer; + option_manager_actor_.reset(); + LOG(DEBUG) << "OptionManager actor was cleared" << timer; poll_manager_actor_.reset(); LOG(DEBUG) << "PollManager actor was cleared" << timer; sponsored_message_manager_actor_.reset(); @@ -4209,9 +4214,11 @@ void Td::init_managers() { G()->set_messages_manager(messages_manager_actor_.get()); notification_manager_ = make_unique(this, create_reference()); notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get()); + G()->set_notification_manager(notification_manager_actor_.get()); + option_manager_ = make_unique(this, create_reference()); + option_manager_actor_ = register_actor("OptionManager", option_manager_.get()); poll_manager_ = make_unique(this, create_reference()); poll_manager_actor_ = register_actor("PollManager", poll_manager_.get()); - G()->set_notification_manager(notification_manager_actor_.get()); sponsored_message_manager_ = make_unique(this, create_reference()); sponsored_message_manager_actor_ = register_actor("SponsoredMessageManager", sponsored_message_manager_.get()); G()->set_sponsored_message_manager(sponsored_message_manager_actor_.get()); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index e9db3fdfa..4ae113c40 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -59,6 +59,7 @@ class LinkManager; class MessagesManager; class NetStatsManager; class NotificationManager; +class OptionManager; class PasswordManager; class PhoneNumberManager; class PollManager; @@ -175,6 +176,8 @@ class Td final : public Actor { ActorOwn messages_manager_actor_; unique_ptr notification_manager_; ActorOwn notification_manager_actor_; + unique_ptr option_manager_; + ActorOwn option_manager_actor_; unique_ptr poll_manager_; ActorOwn poll_manager_actor_; unique_ptr sponsored_message_manager_; From 4254614e9737783abcb2c3a574b582b9f315f628 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 01:45:43 +0300 Subject: [PATCH 02/16] Move option-related methods to OptionManager. --- td/telegram/Global.h | 9 ++ td/telegram/OptionManager.cpp | 239 ++++++++++++++++++++++++++++++++++ td/telegram/OptionManager.h | 11 ++ td/telegram/Td.cpp | 224 +------------------------------ td/telegram/Td.h | 4 - 5 files changed, 266 insertions(+), 221 deletions(-) diff --git a/td/telegram/Global.h b/td/telegram/Global.h index 1cefd0e4e..9887f8d3b 100644 --- a/td/telegram/Global.h +++ b/td/telegram/Global.h @@ -46,6 +46,7 @@ class MessagesManager; class MtprotoHeader; class NetQueryDispatcher; class NotificationManager; +class OptionManager; class PasswordManager; class SecretChatsManager; class SponsoredMessageManager; @@ -260,6 +261,13 @@ class Global final : public ActorContext { notification_manager_ = notification_manager; } + ActorId option_manager() const { + return option_manager_; + } + void set_option_manager(ActorId option_manager) { + option_manager_ = option_manager; + } + ActorId password_manager() const { return password_manager_; } @@ -437,6 +445,7 @@ class Global final : public ActorContext { ActorId link_manager_; ActorId messages_manager_; ActorId notification_manager_; + ActorId option_manager_; ActorId password_manager_; ActorId secret_chats_manager_; ActorId sponsored_message_manager_; diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index bf42caeb4..e0c4447ca 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -6,6 +6,23 @@ // #include "td/telegram/OptionManager.h" +#include "td/telegram/AnimationsManager.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ConfigShared.h" +#include "td/telegram/ContactsManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/LanguagePackManager.h" +#include "td/telegram/net/MtprotoHeader.h" +#include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/NotificationManager.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/StorageManager.h" +#include "td/telegram/SuggestedAction.h" +#include "td/telegram/Td.h" +#include "td/telegram/TopDialogManager.h" + +#include "td/utils/misc.h" + namespace td { OptionManager::OptionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { @@ -17,4 +34,226 @@ void OptionManager::tear_down() { OptionManager::~OptionManager() = default; +void OptionManager::clear_options() { + for (auto &option : G()->shared_config().get_options()) { + if (!is_internal_option(option.first)) { + send_closure( + G()->td(), &Td::send_update, + td_api::make_object(option.first, td_api::make_object())); + } + } +} + +bool OptionManager::is_internal_option(Slice name) { + switch (name[0]) { + case 'a': + 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': + return name == "call_ring_timeout_ms" || name == "call_receive_timeout_ms" || + name == "channels_read_media_period" || name == "chat_read_mark_expire_period" || + name == "chat_read_mark_size_threshold"; + case 'd': + return name == "dc_txt_domain_name" || name == "dice_emojis" || name == "dice_success_values"; + case 'e': + return name == "edit_time_limit" || name == "emoji_sounds"; + case 'i': + return name == "ignored_restriction_reasons"; + case 'l': + return name == "language_pack_version"; + case 'm': + return name == "my_phone_number"; + case 'n': + return name == "notification_cloud_delay_ms" || name == "notification_default_delay_ms"; + case 'o': + return name == "online_update_period_ms" || name == "online_cloud_timeout_ms" || name == "otherwise_relogin_days"; + case 'r': + return name == "revoke_pm_inbox" || name == "revoke_time_limit" || name == "revoke_pm_time_limit" || + name == "rating_e_decay" || name == "recent_stickers_limit"; + case 's': + return name == "saved_animations_limit" || name == "session_count"; + case 'v': + return name == "video_note_size_max"; + case 'w': + return name == "webfile_dc_id"; + default: + return false; + } +} + +void OptionManager::on_option_updated(const string &name) { + if (G()->close_flag()) { + return; + } + switch (name[0]) { + case 'a': + if (name == "animated_emoji_zoom") { + // nothing to do: animated emoji zoom is updated only at launch + } + if (name == "animation_search_emojis") { + td_->animations_manager_->on_update_animation_search_emojis(G()->shared_config().get_option_string(name)); + } + if (name == "animation_search_provider") { + td_->animations_manager_->on_update_animation_search_provider(G()->shared_config().get_option_string(name)); + } + if (name == "auth") { + send_closure(td_->auth_manager_actor_, &AuthManager::on_authorization_lost, + G()->shared_config().get_option_string(name)); + } + break; + case 'b': + if (name == "base_language_pack_version") { + send_closure(td_->language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, true, -1); + } + break; + case 'c': + if (name == "connection_parameters") { + if (G()->mtproto_header().set_parameters(G()->shared_config().get_option_string(name))) { + G()->net_query_dispatcher().update_mtproto_header(); + } + } + break; + case 'd': + if (name == "dice_emojis") { + send_closure(td_->stickers_manager_actor_, &StickersManager::on_update_dice_emojis); + } + if (name == "dice_success_values") { + send_closure(td_->stickers_manager_actor_, &StickersManager::on_update_dice_success_values); + } + if (name == "disable_animated_emoji") { + td_->stickers_manager_->on_update_disable_animated_emojis(); + } + if (name == "disable_contact_registered_notifications") { + send_closure(td_->notification_manager_actor_, + &NotificationManager::on_disable_contact_registered_notifications_changed); + } + if (name == "disable_top_chats") { + send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::update_is_enabled, + !G()->shared_config().get_option_boolean(name)); + } + break; + case 'e': + if (name == "emoji_sounds") { + send_closure(td_->stickers_manager_actor_, &StickersManager::on_update_emoji_sounds); + } + break; + case 'f': + if (name == "favorite_stickers_limit") { + td_->stickers_manager_->on_update_favorite_stickers_limit( + narrow_cast(G()->shared_config().get_option_integer(name))); + } + break; + case 'i': + if (name == "ignored_restriction_reasons") { + send_closure(td_->contacts_manager_actor_, &ContactsManager::on_ignored_restriction_reasons_changed); + } + if (name == "is_emulator") { + if (G()->mtproto_header().set_is_emulator(G()->shared_config().get_option_boolean(name))) { + G()->net_query_dispatcher().update_mtproto_header(); + } + } + break; + case 'l': + if (name == "language_pack_id") { + send_closure(td_->language_pack_manager_, &LanguagePackManager::on_language_code_changed); + if (G()->mtproto_header().set_language_code(G()->shared_config().get_option_string(name))) { + G()->net_query_dispatcher().update_mtproto_header(); + } + } + if (name == "language_pack_version") { + send_closure(td_->language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, false, -1); + } + if (name == "localization_target") { + send_closure(td_->language_pack_manager_, &LanguagePackManager::on_language_pack_changed); + if (G()->mtproto_header().set_language_pack(G()->shared_config().get_option_string(name))) { + G()->net_query_dispatcher().update_mtproto_header(); + } + } + break; + case 'm': + if (name == "my_id") { + G()->set_my_id(G()->shared_config().get_option_integer(name)); + } + break; + case 'n': + if (name == "notification_cloud_delay_ms") { + send_closure(td_->notification_manager_actor_, &NotificationManager::on_notification_cloud_delay_changed); + } + if (name == "notification_default_delay_ms") { + send_closure(td_->notification_manager_actor_, &NotificationManager::on_notification_default_delay_changed); + } + if (name == "notification_group_count_max") { + send_closure(td_->notification_manager_actor_, &NotificationManager::on_notification_group_count_max_changed, + true); + } + if (name == "notification_group_size_max") { + send_closure(td_->notification_manager_actor_, &NotificationManager::on_notification_group_size_max_changed); + } + break; + case 'o': + if (name == "online_cloud_timeout_ms") { + send_closure(td_->notification_manager_actor_, &NotificationManager::on_online_cloud_timeout_changed); + } + if (name == "otherwise_relogin_days") { + auto days = narrow_cast(G()->shared_config().get_option_integer(name)); + if (days > 0) { + vector added_actions{SuggestedAction{SuggestedAction::Type::SetPassword, DialogId(), days}}; + send_closure(G()->td(), &Td::send_update, get_update_suggested_actions_object(added_actions, {})); + } + } + break; + case 'r': + if (name == "rating_e_decay") { + send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::update_rating_e_decay); + } + if (name == "recent_stickers_limit") { + td_->stickers_manager_->on_update_recent_stickers_limit( + narrow_cast(G()->shared_config().get_option_integer(name))); + } + break; + case 's': + if (name == "saved_animations_limit") { + td_->animations_manager_->on_update_saved_animations_limit( + narrow_cast(G()->shared_config().get_option_integer(name))); + } + if (name == "session_count") { + G()->net_query_dispatcher().update_session_count(); + } + break; + case 'u': + if (name == "use_pfs") { + G()->net_query_dispatcher().update_use_pfs(); + } + if (name == "use_storage_optimizer") { + send_closure(td_->storage_manager_, &StorageManager::update_use_storage_optimizer); + } + 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(); + } + } + break; + default: + break; + } + + if (is_internal_option(name)) { + return; + } + + // send_closure was already used in the callback + td_->send_update(td_api::make_object(name, G()->shared_config().get_option_value(name))); +} + +void OptionManager::get_current_state(vector> &updates) { + for (const auto &option : G()->shared_config().get_options()) { + if (!is_internal_option(option.first)) { + updates.push_back(td_api::make_object( + option.first, ConfigShared::get_option_value_object(option.second))); + } + } +} + } // namespace td diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index dd1451986..28f382df6 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -6,9 +6,12 @@ // #pragma once +#include "td/telegram/td_api.h" + #include "td/actor/actor.h" #include "td/utils/common.h" +#include "td/utils/Slice.h" namespace td { @@ -24,9 +27,17 @@ class OptionManager final : public Actor { OptionManager &operator=(OptionManager &&) = delete; ~OptionManager() final; + void on_option_updated(const string &name); + + static void clear_options(); + + static void get_current_state(vector> &updates); + private: void tear_down() final; + static bool is_internal_option(Slice name); + Td *td_; ActorShared<> parent_; }; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 0cb984a42..69997a82f 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3239,208 +3239,6 @@ void Td::on_result(NetQueryPtr query) { query->clear(); } -bool Td::is_internal_config_option(Slice name) { - switch (name[0]) { - case 'a': - 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': - return name == "call_ring_timeout_ms" || name == "call_receive_timeout_ms" || - name == "channels_read_media_period" || name == "chat_read_mark_expire_period" || - name == "chat_read_mark_size_threshold"; - case 'd': - return name == "dc_txt_domain_name" || name == "dice_emojis" || name == "dice_success_values"; - case 'e': - return name == "edit_time_limit" || name == "emoji_sounds"; - case 'i': - return name == "ignored_restriction_reasons"; - case 'l': - return name == "language_pack_version"; - case 'm': - return name == "my_phone_number"; - case 'n': - return name == "notification_cloud_delay_ms" || name == "notification_default_delay_ms"; - case 'o': - return name == "online_update_period_ms" || name == "online_cloud_timeout_ms" || name == "otherwise_relogin_days"; - case 'r': - return name == "revoke_pm_inbox" || name == "revoke_time_limit" || name == "revoke_pm_time_limit" || - name == "rating_e_decay" || name == "recent_stickers_limit"; - case 's': - return name == "saved_animations_limit" || name == "session_count"; - case 'v': - return name == "video_note_size_max"; - case 'w': - return name == "webfile_dc_id"; - default: - return false; - } -} - -void Td::on_config_option_updated(const string &name) { - if (close_flag_) { - return; - } - switch (name[0]) { - case 'a': - if (name == "animated_emoji_zoom") { - // nothing to do: animated emoji zoom is updated only at launch - } - if (name == "animation_search_emojis") { - animations_manager_->on_update_animation_search_emojis(G()->shared_config().get_option_string(name)); - } - if (name == "animation_search_provider") { - animations_manager_->on_update_animation_search_provider(G()->shared_config().get_option_string(name)); - } - if (name == "auth") { - send_closure(auth_manager_actor_, &AuthManager::on_authorization_lost, - G()->shared_config().get_option_string(name)); - } - break; - case 'b': - if (name == "base_language_pack_version") { - send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, true, -1); - } - break; - case 'c': - if (name == "connection_parameters") { - if (G()->mtproto_header().set_parameters(G()->shared_config().get_option_string(name))) { - G()->net_query_dispatcher().update_mtproto_header(); - } - } - break; - case 'd': - if (name == "dice_emojis") { - send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_emojis); - } - if (name == "dice_success_values") { - send_closure(stickers_manager_actor_, &StickersManager::on_update_dice_success_values); - } - if (name == "disable_animated_emoji") { - stickers_manager_->on_update_disable_animated_emojis(); - } - if (name == "disable_contact_registered_notifications") { - send_closure(notification_manager_actor_, - &NotificationManager::on_disable_contact_registered_notifications_changed); - } - if (name == "disable_top_chats") { - send_closure(top_dialog_manager_actor_, &TopDialogManager::update_is_enabled, - !G()->shared_config().get_option_boolean(name)); - } - break; - case 'e': - if (name == "emoji_sounds") { - send_closure(stickers_manager_actor_, &StickersManager::on_update_emoji_sounds); - } - break; - case 'f': - if (name == "favorite_stickers_limit") { - stickers_manager_->on_update_favorite_stickers_limit( - narrow_cast(G()->shared_config().get_option_integer(name))); - } - break; - case 'i': - if (name == "ignored_restriction_reasons") { - send_closure(contacts_manager_actor_, &ContactsManager::on_ignored_restriction_reasons_changed); - } - if (name == "is_emulator") { - if (G()->mtproto_header().set_is_emulator(G()->shared_config().get_option_boolean(name))) { - G()->net_query_dispatcher().update_mtproto_header(); - } - } - break; - case 'l': - if (name == "language_pack_id") { - send_closure(language_pack_manager_, &LanguagePackManager::on_language_code_changed); - if (G()->mtproto_header().set_language_code(G()->shared_config().get_option_string(name))) { - G()->net_query_dispatcher().update_mtproto_header(); - } - } - if (name == "language_pack_version") { - send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, false, -1); - } - if (name == "localization_target") { - send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_changed); - if (G()->mtproto_header().set_language_pack(G()->shared_config().get_option_string(name))) { - G()->net_query_dispatcher().update_mtproto_header(); - } - } - break; - case 'm': - if (name == "my_id") { - G()->set_my_id(G()->shared_config().get_option_integer(name)); - } - break; - case 'n': - if (name == "notification_cloud_delay_ms") { - send_closure(notification_manager_actor_, &NotificationManager::on_notification_cloud_delay_changed); - } - if (name == "notification_default_delay_ms") { - send_closure(notification_manager_actor_, &NotificationManager::on_notification_default_delay_changed); - } - if (name == "notification_group_count_max") { - send_closure(notification_manager_actor_, &NotificationManager::on_notification_group_count_max_changed, true); - } - if (name == "notification_group_size_max") { - send_closure(notification_manager_actor_, &NotificationManager::on_notification_group_size_max_changed); - } - break; - case 'o': - if (name == "online_cloud_timeout_ms") { - send_closure(notification_manager_actor_, &NotificationManager::on_online_cloud_timeout_changed); - } - if (name == "otherwise_relogin_days") { - auto days = narrow_cast(G()->shared_config().get_option_integer(name)); - if (days > 0) { - vector added_actions{SuggestedAction{SuggestedAction::Type::SetPassword, DialogId(), days}}; - send_closure(G()->td(), &Td::send_update, get_update_suggested_actions_object(added_actions, {})); - } - } - break; - case 'r': - if (name == "rating_e_decay") { - send_closure(top_dialog_manager_actor_, &TopDialogManager::update_rating_e_decay); - } - if (name == "recent_stickers_limit") { - stickers_manager_->on_update_recent_stickers_limit( - narrow_cast(G()->shared_config().get_option_integer(name))); - } - break; - case 's': - if (name == "saved_animations_limit") { - animations_manager_->on_update_saved_animations_limit( - narrow_cast(G()->shared_config().get_option_integer(name))); - } - if (name == "session_count") { - G()->net_query_dispatcher().update_session_count(); - } - break; - case 'u': - if (name == "use_pfs") { - G()->net_query_dispatcher().update_use_pfs(); - } - if (name == "use_storage_optimizer") { - send_closure(storage_manager_, &StorageManager::update_use_storage_optimizer); - } - 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(); - } - } - break; - default: - break; - } - - if (is_internal_config_option(name)) { - return; - } - - // send_closure was already used in the callback - send_update(make_tl_object(name, G()->shared_config().get_option_value(name))); -} - void Td::on_connection_state_changed(ConnectionState new_state) { if (new_state == connection_state_) { LOG(ERROR) << "State manager sends update about unchanged state " << static_cast(new_state); @@ -3655,11 +3453,7 @@ void Td::clear() { Timer timer; if (destroy_flag_) { - for (auto &option : G()->shared_config().get_options()) { - if (!is_internal_config_option(option.first)) { - send_update(make_tl_object(option.first, make_tl_object())); - } - } + OptionManager::clear_options(); if (!auth_manager_->is_bot()) { notification_manager_->destroy_all_notifications(); } @@ -3668,11 +3462,10 @@ void Td::clear() { notification_manager_->flush_all_notifications(); } } - LOG(DEBUG) << "Options was cleared" << timer; G()->net_query_creator().stop_check(); result_handlers_.clear(); - LOG(DEBUG) << "Handlers was cleared" << timer; + LOG(DEBUG) << "Handlers were cleared" << timer; G()->net_query_dispatcher().stop(); LOG(DEBUG) << "NetQueryDispatcher was stopped" << timer; state_manager_.reset(); @@ -3685,7 +3478,7 @@ void Td::clear() { alarm_timeout_.cancel_timeout(PING_SERVER_ALARM_ID); alarm_timeout_.cancel_timeout(TERMS_OF_SERVICE_ALARM_ID); alarm_timeout_.cancel_timeout(PROMO_DATA_ALARM_ID); - LOG(DEBUG) << "Requests was answered" << timer; + LOG(DEBUG) << "Requests were answered" << timer; // close all pure actors call_manager_.reset(); @@ -4065,7 +3858,7 @@ void Td::init_options_and_network() { class ConfigSharedCallback final : public ConfigShared::Callback { public: void on_option_updated(const string &name, const string &value) const final { - send_closure(G()->td(), &Td::on_config_option_updated, name); + send_closure(G()->option_manager(), &OptionManager::on_option_updated, name); } ~ConfigSharedCallback() final { LOG(INFO) << "Destroy ConfigSharedCallback"; @@ -4217,6 +4010,7 @@ void Td::init_managers() { G()->set_notification_manager(notification_manager_actor_.get()); option_manager_ = make_unique(this, create_reference()); option_manager_actor_ = register_actor("OptionManager", option_manager_.get()); + G()->set_option_manager(option_manager_actor_.get()); poll_manager_ = make_unique(this, create_reference()); poll_manager_actor_ = register_actor("PollManager", poll_manager_.get()); sponsored_message_manager_ = make_unique(this, create_reference()); @@ -4610,12 +4404,8 @@ void Td::on_request(uint64 id, const td_api::getCurrentState &request) { "unix_time", make_tl_object(G()->unix_time()))); updates.push_back(td_api::make_object( "version", td_api::make_object(TDLIB_VERSION))); - for (auto &option : G()->shared_config().get_options()) { - if (!is_internal_config_option(option.first)) { - updates.push_back(td_api::make_object( - option.first, ConfigShared::get_option_value_object(option.second))); - } - } + + OptionManager::get_current_state(updates); auto state = auth_manager_->get_current_authorization_state_object(); if (state != nullptr) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 4ae113c40..afb4eb19f 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -351,10 +351,6 @@ class Td final : public Actor { void on_file_download_finished(FileId file_id); - static bool is_internal_config_option(Slice name); - - void on_config_option_updated(const string &name); - class OnRequest; class DownloadFileCallback; From a333f3fb61c582d0624ef9140959e0ca118d54fc Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 12:07:32 +0300 Subject: [PATCH 03/16] Move getOption handling to OptionManager. --- td/telegram/ConfigShared.cpp | 2 - td/telegram/OptionManager.cpp | 55 +++++++++++++++++++++++ td/telegram/OptionManager.h | 3 ++ td/telegram/Td.cpp | 85 +++-------------------------------- td/telegram/Td.h | 3 +- 5 files changed, 65 insertions(+), 83 deletions(-) diff --git a/td/telegram/ConfigShared.cpp b/td/telegram/ConfigShared.cpp index b821f69e9..457a8c8d0 100644 --- a/td/telegram/ConfigShared.cpp +++ b/td/telegram/ConfigShared.cpp @@ -6,8 +6,6 @@ // #include "td/telegram/ConfigShared.h" -#include "td/telegram/td_api.h" - #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/SliceBuilder.h" diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index e0c4447ca..334cadaaf 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -8,6 +8,7 @@ #include "td/telegram/AnimationsManager.h" #include "td/telegram/AuthManager.h" +#include "td/telegram/ConfigManager.h" #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" @@ -247,6 +248,60 @@ void OptionManager::on_option_updated(const string &name) { td_->send_update(td_api::make_object(name, G()->shared_config().get_option_value(name))); } +void OptionManager::get_option(const string &name, Promise> &&promise) { + bool is_bot = td_->auth_manager_ != nullptr && td_->auth_manager_->is_authorized() && td_->auth_manager_->is_bot(); + auto wrap_promise = [&] { + return PromiseCreator::lambda([promise = std::move(promise), name](Unit result) mutable { + // the option is already updated on success, ignore errors + promise.set_value(G()->shared_config().get_option_value(name)); + }); + }; + switch (name[0]) { + // all these options should be added to getCurrentState + case 'a': + if (!is_bot && name == "archive_and_mute_new_chats_from_unknown_users") { + return send_closure_later(td_->config_manager_, &ConfigManager::get_global_privacy_settings, wrap_promise()); + } + break; + case 'c': + if (!is_bot && name == "can_ignore_sensitive_content_restrictions") { + return send_closure_later(td_->config_manager_, &ConfigManager::get_content_settings, wrap_promise()); + } + break; + case 'd': + if (!is_bot && name == "disable_contact_registered_notifications") { + return send_closure_later(td_->notification_manager_actor_, + &NotificationManager::get_disable_contact_registered_notifications, wrap_promise()); + } + break; + case 'i': + if (!is_bot && name == "ignore_sensitive_content_restrictions") { + return send_closure_later(td_->config_manager_, &ConfigManager::get_content_settings, wrap_promise()); + } + if (!is_bot && name == "is_location_visible") { + return send_closure_later(td_->contacts_manager_actor_, &ContactsManager::get_is_location_visible, + wrap_promise()); + } + break; + case 'o': + if (name == "online") { + return promise.set_value(td_api::make_object(td_->is_online())); + } + break; + case 'u': + if (name == "unix_time") { + return promise.set_value(td_api::make_object(G()->unix_time())); + } + break; + case 'v': + if (name == "version") { + return promise.set_value(td_api::make_object(Td::TDLIB_VERSION)); + } + break; + } + wrap_promise().set_value(Unit()); +} + void OptionManager::get_current_state(vector> &updates) { for (const auto &option : G()->shared_config().get_options()) { if (!is_internal_option(option.first)) { diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index 28f382df6..957034ec9 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -9,6 +9,7 @@ #include "td/telegram/td_api.h" #include "td/actor/actor.h" +#include "td/actor/PromiseFuture.h" #include "td/utils/common.h" #include "td/utils/Slice.h" @@ -29,6 +30,8 @@ class OptionManager final : public Actor { void on_option_updated(const string &name); + void get_option(const string &name, Promise> &&promise); + static void clear_options(); static void get_current_state(vector> &updates); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 69997a82f..afaa95906 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -4398,12 +4398,13 @@ void Td::on_request(uint64 id, td_api::confirmQrCodeAuthentication &request) { void Td::on_request(uint64 id, const td_api::getCurrentState &request) { vector> updates; + updates.push_back(td_api::make_object( + "version", td_api::make_object(TDLIB_VERSION))); + updates.push_back( td_api::make_object("online", make_tl_object(is_online_))); updates.push_back(td_api::make_object( "unix_time", make_tl_object(G()->unix_time()))); - updates.push_back(td_api::make_object( - "version", td_api::make_object(TDLIB_VERSION))); OptionManager::get_current_state(updates); @@ -7120,84 +7121,8 @@ void Td::on_request(uint64 id, td_api::deleteLanguagePack &request) { void Td::on_request(uint64 id, td_api::getOption &request) { CLEAN_INPUT_STRING(request.name_); - - tl_object_ptr option_value; - bool is_bot = auth_manager_ != nullptr && auth_manager_->is_authorized() && auth_manager_->is_bot(); - switch (request.name_[0]) { - // all these options should be added to getCurrentState - case 'a': - if (!is_bot && request.name_ == "archive_and_mute_new_chats_from_unknown_users") { - 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("archive_and_mute_new_chats_from_unknown_users")); - }); - send_closure_later(config_manager_, &ConfigManager::get_global_privacy_settings, std::move(promise)); - return; - } - break; - case 'c': - if (!is_bot && request.name_ == "can_ignore_sensitive_content_restrictions") { - 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("can_ignore_sensitive_content_restrictions")); - }); - send_closure_later(config_manager_, &ConfigManager::get_content_settings, std::move(promise)); - return; - } - break; - case 'd': - if (!is_bot && request.name_ == "disable_contact_registered_notifications") { - 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("disable_contact_registered_notifications")); - }); - send_closure_later(notification_manager_actor_, - &NotificationManager::get_disable_contact_registered_notifications, std::move(promise)); - return; - } - break; - case 'i': - if (!is_bot && request.name_ == "ignore_sensitive_content_restrictions") { - 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("ignore_sensitive_content_restrictions")); - }); - 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") { - option_value = make_tl_object(is_online_); - } - break; - case 'u': - if (request.name_ == "unix_time") { - option_value = make_tl_object(G()->unix_time()); - } - break; - case 'v': - if (request.name_ == "version") { - option_value = make_tl_object(TDLIB_VERSION); - } - break; - } - if (option_value == nullptr) { - option_value = G()->shared_config().get_option_value(request.name_); - } - send_closure(actor_id(this), &Td::send_result, id, std::move(option_value)); + CREATE_REQUEST_PROMISE(); + option_manager_->get_option(request.name_, std::move(promise)); } void Td::on_request(uint64 id, td_api::setOption &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index afb4eb19f..a0802dbc7 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -98,6 +98,8 @@ class Td final : public Actor { Td &operator=(Td &&) = delete; ~Td() final; + static constexpr const char *TDLIB_VERSION = "1.7.10"; + struct Options { std::shared_ptr net_query_stats; }; @@ -253,7 +255,6 @@ 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.10"; static constexpr int64 ONLINE_ALARM_ID = 0; static constexpr int64 PING_SERVER_ALARM_ID = -1; static constexpr int32 PING_SERVER_TIMEOUT = 300; From 10505fae724f1295c6581a6aea6851fff6dba1cd Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 12:16:09 +0300 Subject: [PATCH 04/16] Move the rest options to OptionManager::get_current_state. --- td/telegram/OptionManager.cpp | 10 +++++++++- td/telegram/OptionManager.h | 2 +- td/telegram/Td.cpp | 10 +--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index 334cadaaf..ac7f312ef 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -302,7 +302,15 @@ void OptionManager::get_option(const string &name, Promise> &updates) { +void OptionManager::get_current_state(vector> &updates) const { + updates.push_back(td_api::make_object( + "version", td_api::make_object(Td::TDLIB_VERSION))); + + updates.push_back( + td_api::make_object("online", td_api::make_object(td_->is_online()))); + updates.push_back(td_api::make_object( + "unix_time", td_api::make_object(G()->unix_time()))); + for (const auto &option : G()->shared_config().get_options()) { if (!is_internal_option(option.first)) { updates.push_back(td_api::make_object( diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index 957034ec9..5dda42b81 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -34,7 +34,7 @@ class OptionManager final : public Actor { static void clear_options(); - static void get_current_state(vector> &updates); + void get_current_state(vector> &updates) const; private: void tear_down() final; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index afaa95906..19b60c0fb 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -4398,15 +4398,7 @@ void Td::on_request(uint64 id, td_api::confirmQrCodeAuthentication &request) { void Td::on_request(uint64 id, const td_api::getCurrentState &request) { vector> updates; - updates.push_back(td_api::make_object( - "version", td_api::make_object(TDLIB_VERSION))); - - updates.push_back( - td_api::make_object("online", make_tl_object(is_online_))); - updates.push_back(td_api::make_object( - "unix_time", make_tl_object(G()->unix_time()))); - - OptionManager::get_current_state(updates); + option_manager_->get_current_state(updates); auto state = auth_manager_->get_current_authorization_state_object(); if (state != nullptr) { From ee629c342b7df57117bc37838559b9f2ffdedfa4 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 13:13:14 +0300 Subject: [PATCH 05/16] Move setOption handling to OptionManager. --- td/telegram/OptionManager.cpp | 304 ++++++++++++++++++++++++++++++++- td/telegram/OptionManager.h | 2 + td/telegram/Td.cpp | 311 ++-------------------------------- td/telegram/Td.h | 3 + 4 files changed, 320 insertions(+), 300 deletions(-) diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index ac7f312ef..9033c5ac2 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -12,17 +12,23 @@ #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" +#include "td/telegram/JsonValue.h" #include "td/telegram/LanguagePackManager.h" #include "td/telegram/net/MtprotoHeader.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/NotificationManager.h" +#include "td/telegram/StateManager.h" #include "td/telegram/StickersManager.h" #include "td/telegram/StorageManager.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" #include "td/telegram/TopDialogManager.h" #include "td/utils/misc.h" +#include "td/utils/SliceBuilder.h" + +#include namespace td { @@ -302,12 +308,306 @@ void OptionManager::get_option(const string &name, Promise &&value, + Promise &&promise) { + int32 value_constructor_id = value == nullptr ? td_api::optionValueEmpty::ID : value->get_id(); + + auto set_integer_option = [&](Slice option_name, int64 min_value = 0, + int64 max_value = std::numeric_limits::max()) { + if (name != option_name) { + return false; + } + if (value_constructor_id != td_api::optionValueInteger::ID && + value_constructor_id != td_api::optionValueEmpty::ID) { + promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" must have integer value")); + return true; + } + if (value_constructor_id == td_api::optionValueEmpty::ID) { + G()->shared_config().set_option_empty(option_name); + } else { + int64 int_value = static_cast(value.get())->value_; + if (int_value < min_value || int_value > max_value) { + promise.set_error(Status::Error(400, PSLICE() << "Option's \"" << name << "\" value " << int_value + << " is outside of the valid range [" << min_value << ", " + << max_value << "]")); + return true; + } + G()->shared_config().set_option_integer(name, int_value); + } + promise.set_value(Unit()); + return true; + }; + + auto set_boolean_option = [&](Slice option_name) { + if (name != option_name) { + return false; + } + if (value_constructor_id != td_api::optionValueBoolean::ID && + value_constructor_id != td_api::optionValueEmpty::ID) { + promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" must have boolean value")); + return true; + } + if (value_constructor_id == td_api::optionValueEmpty::ID) { + G()->shared_config().set_option_empty(name); + } else { + bool bool_value = static_cast(value.get())->value_; + G()->shared_config().set_option_boolean(name, bool_value); + } + promise.set_value(Unit()); + return true; + }; + + auto set_string_option = [&](Slice option_name, auto check_value) { + if (name != option_name) { + return false; + } + if (value_constructor_id != td_api::optionValueString::ID && value_constructor_id != td_api::optionValueEmpty::ID) { + promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" must have string value")); + return true; + } + if (value_constructor_id == td_api::optionValueEmpty::ID) { + G()->shared_config().set_option_empty(name); + } else { + const string &str_value = static_cast(value.get())->value_; + if (str_value.empty()) { + G()->shared_config().set_option_empty(name); + } else { + if (check_value(str_value)) { + G()->shared_config().set_option_string(name, str_value); + } else { + promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" can't have specified value")); + return true; + } + } + } + promise.set_value(Unit()); + return true; + }; + + bool is_bot = td_->auth_manager_ != nullptr && td_->auth_manager_->is_authorized() && td_->auth_manager_->is_bot(); + switch (name[0]) { + case 'a': + if (set_boolean_option("always_parse_markdown")) { + return; + } + if (!is_bot && name == "archive_and_mute_new_chats_from_unknown_users") { + if (value_constructor_id != td_api::optionValueBoolean::ID && + value_constructor_id != td_api::optionValueEmpty::ID) { + return promise.set_error( + Status::Error(400, "Option \"archive_and_mute_new_chats_from_unknown_users\" must have boolean value")); + } + + auto archive_and_mute = value_constructor_id == td_api::optionValueBoolean::ID && + static_cast(value.get())->value_; + send_closure_later(td_->config_manager_, &ConfigManager::set_archive_and_mute, archive_and_mute, + std::move(promise)); + return; + } + break; + case 'c': + if (!is_bot && set_string_option("connection_parameters", [](Slice value) { + string value_copy = value.str(); + auto r_json_value = get_json_value(value_copy); + if (r_json_value.is_error()) { + return false; + } + return r_json_value.ok()->get_id() == td_api::jsonValueObject::ID; + })) { + return; + } + break; + case 'd': + if (!is_bot && set_boolean_option("disable_animated_emoji")) { + return; + } + if (!is_bot && set_boolean_option("disable_contact_registered_notifications")) { + return; + } + if (!is_bot && set_boolean_option("disable_sent_scheduled_message_notifications")) { + return; + } + if (!is_bot && set_boolean_option("disable_top_chats")) { + return; + } + if (set_boolean_option("disable_persistent_network_statistics")) { + return; + } + if (set_boolean_option("disable_time_adjustment_protection")) { + return; + } + if (name == "drop_notification_ids") { + G()->td_db()->get_binlog_pmc()->erase("notification_id_current"); + G()->td_db()->get_binlog_pmc()->erase("notification_group_id_current"); + return promise.set_value(Unit()); + } + break; + case 'i': + if (set_boolean_option("ignore_background_updates")) { + return; + } + if (set_boolean_option("ignore_default_disable_notification")) { + return; + } + if (set_boolean_option("ignore_inline_thumbnails")) { + return; + } + if (set_boolean_option("ignore_platform_restrictions")) { + return; + } + if (set_boolean_option("is_emulator")) { + return; + } + if (!is_bot && name == "ignore_sensitive_content_restrictions") { + if (!G()->shared_config().get_option_boolean("can_ignore_sensitive_content_restrictions")) { + return promise.set_error( + Status::Error(400, "Option \"ignore_sensitive_content_restrictions\" can't be changed by the user")); + } + + if (value_constructor_id != td_api::optionValueBoolean::ID && + value_constructor_id != td_api::optionValueEmpty::ID) { + return promise.set_error( + Status::Error(400, "Option \"ignore_sensitive_content_restrictions\" must have boolean value")); + } + + auto ignore_sensitive_content_restrictions = value_constructor_id == td_api::optionValueBoolean::ID && + static_cast(value.get())->value_; + send_closure_later(td_->config_manager_, &ConfigManager::set_content_settings, + ignore_sensitive_content_restrictions, std::move(promise)); + return; + } + if (!is_bot && set_boolean_option("is_location_visible")) { + td_->contacts_manager_->set_location_visibility(); + return; + } + break; + case 'l': + if (!is_bot && set_string_option("language_pack_database_path", [](Slice value) { return true; })) { + return; + } + if (!is_bot && set_string_option("localization_target", LanguagePackManager::check_language_pack_name)) { + return; + } + if (!is_bot && set_string_option("language_pack_id", LanguagePackManager::check_language_code_name)) { + return; + } + break; + case 'm': + if (set_integer_option("message_unload_delay", 60, 86400)) { + return; + } + break; + case 'n': + if (!is_bot && + set_integer_option("notification_group_count_max", NotificationManager::MIN_NOTIFICATION_GROUP_COUNT_MAX, + NotificationManager::MAX_NOTIFICATION_GROUP_COUNT_MAX)) { + return; + } + if (!is_bot && + set_integer_option("notification_group_size_max", NotificationManager::MIN_NOTIFICATION_GROUP_SIZE_MAX, + NotificationManager::MAX_NOTIFICATION_GROUP_SIZE_MAX)) { + return; + } + break; + case 'o': + if (name == "online") { + if (value_constructor_id != td_api::optionValueBoolean::ID && + value_constructor_id != td_api::optionValueEmpty::ID) { + return promise.set_error(Status::Error(400, "Option \"online\" must have boolean value")); + } + bool is_online = value_constructor_id == td_api::optionValueEmpty::ID || + static_cast(value.get())->value_; + if (!is_bot) { + send_closure(td_->state_manager_, &StateManager::on_online, is_online); + } + td_->set_is_online(is_online); + return promise.set_value(Unit()); + } + break; + case 'p': + if (set_boolean_option("prefer_ipv6")) { + send_closure(td_->state_manager_, &StateManager::on_network_updated); + return; + } + break; + case 'r': + // temporary option + if (set_boolean_option("reuse_uploaded_photos_by_hash")) { + return; + } + break; + case 's': + if (set_integer_option("storage_max_files_size")) { + return; + } + if (set_integer_option("storage_max_time_from_last_access")) { + return; + } + if (set_integer_option("storage_max_file_count")) { + return; + } + if (set_integer_option("storage_immunity_delay")) { + return; + } + if (set_boolean_option("store_all_files_in_files_directory")) { + return; + } + break; + case 't': + if (set_boolean_option("test_flood_wait")) { + 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 (name.size() > 255) { + return promise.set_error(Status::Error(400, "Option name is too long")); + } + switch (value_constructor_id) { + case td_api::optionValueBoolean::ID: + G()->shared_config().set_option_boolean(name, + static_cast(value.get())->value_); + break; + case td_api::optionValueEmpty::ID: + G()->shared_config().set_option_empty(name); + break; + case td_api::optionValueInteger::ID: + G()->shared_config().set_option_integer(name, + static_cast(value.get())->value_); + break; + case td_api::optionValueString::ID: + G()->shared_config().set_option_string(name, + static_cast(value.get())->value_); + break; + default: + UNREACHABLE(); + } + return promise.set_value(Unit()); + } + } + + promise.set_error(Status::Error(400, "Option can't be set")); +} + void OptionManager::get_current_state(vector> &updates) const { updates.push_back(td_api::make_object( "version", td_api::make_object(Td::TDLIB_VERSION))); - updates.push_back( - td_api::make_object("online", td_api::make_object(td_->is_online()))); + updates.push_back(td_api::make_object( + "online", td_api::make_object(td_->is_online()))); updates.push_back(td_api::make_object( "unix_time", td_api::make_object(G()->unix_time()))); diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index 5dda42b81..5631516f2 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -32,6 +32,8 @@ class OptionManager final : public Actor { void get_option(const string &name, Promise> &&promise); + void set_option(const string &name, td_api::object_ptr &&value, Promise &&promise); + static void clear_options(); void get_current_state(vector> &updates) const; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 19b60c0fb..11327521b 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -2878,6 +2878,17 @@ bool Td::is_online() const { return is_online_; } +void Td::set_is_online(bool is_online) { + if (is_online == is_online_) { + return; + } + + is_online_ = is_online; + if (auth_manager_ != nullptr) { // postpone if there is no AuthManager yet + on_online_updated(true, true); + } +} + void Td::set_is_bot_online(bool is_bot_online) { if (G()->shared_config().get_option_integer("session_count") > 1) { is_bot_online = false; @@ -7119,304 +7130,8 @@ void Td::on_request(uint64 id, td_api::getOption &request) { void Td::on_request(uint64 id, td_api::setOption &request) { CLEAN_INPUT_STRING(request.name_); - int32 value_constructor_id = request.value_ == nullptr ? td_api::optionValueEmpty::ID : request.value_->get_id(); - - LOG(INFO) << "Set option " << request.name_; - - auto set_integer_option = [&](Slice name, int64 min_value = 0, int64 max_value = std::numeric_limits::max()) { - if (request.name_ != name) { - return false; - } - if (value_constructor_id != td_api::optionValueInteger::ID && - value_constructor_id != td_api::optionValueEmpty::ID) { - send_error_raw(id, 400, PSLICE() << "Option \"" << name << "\" must have integer value"); - return true; - } - if (value_constructor_id == td_api::optionValueEmpty::ID) { - G()->shared_config().set_option_empty(name); - } else { - int64 value = static_cast(request.value_.get())->value_; - if (value < min_value || value > max_value) { - send_error_raw(id, 400, - PSLICE() << "Option's \"" << name << "\" value " << value << " is outside of a valid range [" - << min_value << ", " << max_value << "]"); - return true; - } - G()->shared_config().set_option_integer(name, clamp(value, min_value, max_value)); - } - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - return true; - }; - - auto set_boolean_option = [&](Slice name) { - if (request.name_ != name) { - return false; - } - if (value_constructor_id != td_api::optionValueBoolean::ID && - value_constructor_id != td_api::optionValueEmpty::ID) { - send_error_raw(id, 400, PSLICE() << "Option \"" << name << "\" must have boolean value"); - return true; - } - if (value_constructor_id == td_api::optionValueEmpty::ID) { - G()->shared_config().set_option_empty(name); - } else { - bool value = static_cast(request.value_.get())->value_; - G()->shared_config().set_option_boolean(name, value); - } - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - return true; - }; - - auto set_string_option = [&](Slice name, auto check_value) { - if (request.name_ != name) { - return false; - } - if (value_constructor_id != td_api::optionValueString::ID && value_constructor_id != td_api::optionValueEmpty::ID) { - send_error_raw(id, 400, PSLICE() << "Option \"" << name << "\" must have string value"); - return true; - } - if (value_constructor_id == td_api::optionValueEmpty::ID) { - G()->shared_config().set_option_empty(name); - } else { - const string &value = static_cast(request.value_.get())->value_; - if (value.empty()) { - G()->shared_config().set_option_empty(name); - } else { - if (check_value(value)) { - G()->shared_config().set_option_string(name, value); - } else { - send_error_raw(id, 400, PSLICE() << "Option \"" << name << "\" can't have specified value"); - return true; - } - } - } - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - return true; - }; - - bool is_bot = auth_manager_ != nullptr && auth_manager_->is_authorized() && auth_manager_->is_bot(); - switch (request.name_[0]) { - case 'a': - if (set_boolean_option("always_parse_markdown")) { - return; - } - if (!is_bot && request.name_ == "archive_and_mute_new_chats_from_unknown_users") { - if (value_constructor_id != td_api::optionValueBoolean::ID && - value_constructor_id != td_api::optionValueEmpty::ID) { - return send_error_raw(id, 400, - "Option \"archive_and_mute_new_chats_from_unknown_users\" must have boolean value"); - } - - auto archive_and_mute = value_constructor_id == td_api::optionValueBoolean::ID && - static_cast(request.value_.get())->value_; - CREATE_OK_REQUEST_PROMISE(); - send_closure_later(config_manager_, &ConfigManager::set_archive_and_mute, archive_and_mute, std::move(promise)); - return; - } - break; - case 'c': - if (!is_bot && set_string_option("connection_parameters", [](Slice value) { - string value_copy = value.str(); - auto r_json_value = get_json_value(value_copy); - if (r_json_value.is_error()) { - return false; - } - return r_json_value.ok()->get_id() == td_api::jsonValueObject::ID; - })) { - return; - } - break; - case 'd': - if (!is_bot && set_boolean_option("disable_animated_emoji")) { - return; - } - if (!is_bot && set_boolean_option("disable_contact_registered_notifications")) { - return; - } - if (!is_bot && set_boolean_option("disable_sent_scheduled_message_notifications")) { - return; - } - if (!is_bot && set_boolean_option("disable_top_chats")) { - return; - } - if (set_boolean_option("disable_persistent_network_statistics")) { - return; - } - if (set_boolean_option("disable_time_adjustment_protection")) { - return; - } - if (request.name_ == "drop_notification_ids") { - G()->td_db()->get_binlog_pmc()->erase("notification_id_current"); - G()->td_db()->get_binlog_pmc()->erase("notification_group_id_current"); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - return; - } - break; - case 'i': - if (set_boolean_option("ignore_background_updates")) { - return; - } - if (set_boolean_option("ignore_default_disable_notification")) { - return; - } - if (set_boolean_option("ignore_inline_thumbnails")) { - return; - } - if (set_boolean_option("ignore_platform_restrictions")) { - return; - } - if (set_boolean_option("is_emulator")) { - return; - } - if (!is_bot && request.name_ == "ignore_sensitive_content_restrictions") { - if (!G()->shared_config().get_option_boolean("can_ignore_sensitive_content_restrictions")) { - return send_error_raw(id, 400, - "Option \"ignore_sensitive_content_restrictions\" can't be changed by the user"); - } - - if (value_constructor_id != td_api::optionValueBoolean::ID && - value_constructor_id != td_api::optionValueEmpty::ID) { - return send_error_raw(id, 400, "Option \"ignore_sensitive_content_restrictions\" must have boolean value"); - } - - auto ignore_sensitive_content_restrictions = - value_constructor_id == td_api::optionValueBoolean::ID && - static_cast(request.value_.get())->value_; - CREATE_OK_REQUEST_PROMISE(); - send_closure_later(config_manager_, &ConfigManager::set_content_settings, ignore_sensitive_content_restrictions, - std::move(promise)); - return; - } - if (!is_bot && set_boolean_option("is_location_visible")) { - contacts_manager_->set_location_visibility(); - return; - } - break; - case 'l': - if (!is_bot && set_string_option("language_pack_database_path", [](Slice value) { return true; })) { - return; - } - if (!is_bot && set_string_option("localization_target", LanguagePackManager::check_language_pack_name)) { - return; - } - if (!is_bot && set_string_option("language_pack_id", LanguagePackManager::check_language_code_name)) { - return; - } - break; - case 'm': - if (set_integer_option("message_unload_delay", 60, 86400)) { - return; - } - break; - case 'n': - if (!is_bot && - set_integer_option("notification_group_count_max", NotificationManager::MIN_NOTIFICATION_GROUP_COUNT_MAX, - NotificationManager::MAX_NOTIFICATION_GROUP_COUNT_MAX)) { - return; - } - if (!is_bot && - set_integer_option("notification_group_size_max", NotificationManager::MIN_NOTIFICATION_GROUP_SIZE_MAX, - NotificationManager::MAX_NOTIFICATION_GROUP_SIZE_MAX)) { - return; - } - break; - case 'o': - if (request.name_ == "online") { - if (value_constructor_id != td_api::optionValueBoolean::ID && - value_constructor_id != td_api::optionValueEmpty::ID) { - return send_error_raw(id, 400, "Option \"online\" must have boolean value"); - } - bool is_online = value_constructor_id == td_api::optionValueEmpty::ID || - static_cast(request.value_.get())->value_; - if (!is_bot) { - send_closure(G()->state_manager(), &StateManager::on_online, is_online); - } - if (is_online != is_online_) { - is_online_ = is_online; - if (auth_manager_ != nullptr) { // postpone if there is no AuthManager yet - on_online_updated(true, true); - } - } - return send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - } - break; - case 'p': - if (set_boolean_option("prefer_ipv6")) { - send_closure(state_manager_, &StateManager::on_network_updated); - return; - } - break; - case 'r': - // temporary option - if (set_boolean_option("reuse_uploaded_photos_by_hash")) { - return; - } - break; - case 's': - if (set_integer_option("storage_max_files_size")) { - return; - } - if (set_integer_option("storage_max_time_from_last_access")) { - return; - } - if (set_integer_option("storage_max_file_count")) { - return; - } - if (set_integer_option("storage_immunity_delay")) { - return; - } - if (set_boolean_option("store_all_files_in_files_directory")) { - return; - } - break; - case 't': - if (set_boolean_option("test_flood_wait")) { - 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) { - return send_error_raw(id, 400, "Option name is too long"); - } - switch (value_constructor_id) { - case td_api::optionValueBoolean::ID: - G()->shared_config().set_option_boolean( - request.name_, static_cast(request.value_.get())->value_); - break; - case td_api::optionValueEmpty::ID: - G()->shared_config().set_option_empty(request.name_); - break; - case td_api::optionValueInteger::ID: - G()->shared_config().set_option_integer( - request.name_, static_cast(request.value_.get())->value_); - break; - case td_api::optionValueString::ID: - G()->shared_config().set_option_string( - request.name_, static_cast(request.value_.get())->value_); - break; - default: - UNREACHABLE(); - } - return send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - } - } - - return send_error_raw(id, 400, "Option can't be set"); + CREATE_OK_REQUEST_PROMISE(); + option_manager_->set_option(request.name_, std::move(request.value_), std::move(promise)); } void Td::on_request(uint64 id, td_api::setPollAnswer &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index a0802dbc7..b43b31b92 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -121,10 +121,13 @@ class Td final : public Actor { void on_update_server_time_difference(); void on_online_updated(bool force, bool send_update); + void on_update_status_success(bool is_online); bool is_online() const; + void set_is_online(bool is_online); + void set_is_bot_online(bool is_bot_online); template From d75f0a4e944f259701b7581989283102d4c5ad6a Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 15:18:51 +0300 Subject: [PATCH 06/16] Move "unix_time" option handling to OptionManager. --- td/telegram/Global.cpp | 4 ++-- td/telegram/OptionManager.cpp | 25 ++++++++++++++++++++++--- td/telegram/OptionManager.h | 8 ++++++++ td/telegram/Td.cpp | 25 ++++++------------------- td/telegram/Td.h | 4 ---- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/td/telegram/Global.cpp b/td/telegram/Global.cpp index b10aa0aa6..21b686013 100644 --- a/td/telegram/Global.cpp +++ b/td/telegram/Global.cpp @@ -11,8 +11,8 @@ #include "td/telegram/net/MtprotoHeader.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/net/TempAuthKeyWatchdog.h" +#include "td/telegram/OptionManager.h" #include "td/telegram/StateManager.h" -#include "td/telegram/Td.h" #include "td/telegram/TdDb.h" #include "td/actor/PromiseFuture.h" @@ -149,7 +149,7 @@ void Global::update_server_time_difference(double diff) { do_save_server_time_difference(); CHECK(Scheduler::instance()); - send_closure(td(), &Td::on_update_server_time_difference); + send_closure(option_manager(), &OptionManager::on_update_server_time_difference); } } diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index 9033c5ac2..b25abce76 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -28,11 +28,13 @@ #include "td/utils/misc.h" #include "td/utils/SliceBuilder.h" +#include #include namespace td { OptionManager::OptionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + send_unix_time_update(); } void OptionManager::tear_down() { @@ -41,6 +43,23 @@ void OptionManager::tear_down() { OptionManager::~OptionManager() = default; +td_api::object_ptr OptionManager::get_unix_time_option_value_object() { + return td_api::make_object(G()->unix_time()); +} + +void OptionManager::send_unix_time_update() { + last_sent_server_time_difference_ = G()->get_server_time_difference(); + td_->send_update(td_api::make_object("unix_time", get_unix_time_option_value_object())); +} + +void OptionManager::on_update_server_time_difference() { + if (std::abs(G()->get_server_time_difference() - last_sent_server_time_difference_) < 0.5) { + return; + } + + send_unix_time_update(); +} + void OptionManager::clear_options() { for (auto &option : G()->shared_config().get_options()) { if (!is_internal_option(option.first)) { @@ -296,7 +315,7 @@ void OptionManager::get_option(const string &name, Promise(G()->unix_time())); + return promise.set_value(get_unix_time_option_value_object()); } break; case 'v': @@ -608,8 +627,8 @@ void OptionManager::get_current_state(vector> updates.push_back(td_api::make_object( "online", td_api::make_object(td_->is_online()))); - updates.push_back(td_api::make_object( - "unix_time", td_api::make_object(G()->unix_time()))); + + updates.push_back(td_api::make_object("unix_time", get_unix_time_option_value_object())); for (const auto &option : G()->shared_config().get_options()) { if (!is_internal_option(option.first)) { diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index 5631516f2..4dbbec97e 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -28,6 +28,8 @@ class OptionManager final : public Actor { OptionManager &operator=(OptionManager &&) = delete; ~OptionManager() final; + void on_update_server_time_difference(); + void on_option_updated(const string &name); void get_option(const string &name, Promise> &&promise); @@ -43,8 +45,14 @@ class OptionManager final : public Actor { static bool is_internal_option(Slice name); + static td_api::object_ptr get_unix_time_option_value_object(); + + void send_unix_time_update(); + Td *td_; ActorShared<> parent_; + + double last_sent_server_time_difference_ = 1e100; }; } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 11327521b..da9c01fe0 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -147,7 +147,6 @@ #include "td/utils/tl_parsers.h" #include "td/utils/utf8.h" -#include #include #include #include @@ -2704,17 +2703,6 @@ void Td::on_alarm_timeout_callback(void *td_ptr, int64 alarm_id) { send_closure_later(td_id, &Td::on_alarm_timeout, alarm_id); } -void Td::on_update_server_time_difference() { - auto diff = G()->get_server_time_difference(); - if (std::abs(diff - last_sent_server_time_difference_) < 0.5) { - return; - } - - last_sent_server_time_difference_ = diff; - send_update(td_api::make_object( - "unix_time", td_api::make_object(G()->unix_time()))); -} - void Td::on_alarm_timeout(int64 alarm_id) { if (alarm_id == ONLINE_ALARM_ID) { on_online_updated(false, true); @@ -3677,9 +3665,6 @@ Status Td::init(DbKey key) { VLOG(td_init) << "Successfully inited database"; G()->init(parameters_, actor_id(this), r_td_db.move_as_ok()).ensure(); - last_sent_server_time_difference_ = G()->get_server_time_difference(); - send_update(td_api::make_object( - "unix_time", td_api::make_object(G()->unix_time()))); init_options_and_network(); @@ -3865,11 +3850,16 @@ void Td::init_options_and_network() { config_manager_ = create_actor("ConfigManager", create_reference()); G()->set_config_manager(config_manager_.get()); + VLOG(td_init) << "Create OptionManager"; + option_manager_ = make_unique(this, create_reference()); + option_manager_actor_ = register_actor("OptionManager", option_manager_.get()); + G()->set_option_manager(option_manager_actor_.get()); + VLOG(td_init) << "Set ConfigShared callback"; class ConfigSharedCallback final : public ConfigShared::Callback { public: void on_option_updated(const string &name, const string &value) const final { - send_closure(G()->option_manager(), &OptionManager::on_option_updated, name); + send_closure_later(G()->option_manager(), &OptionManager::on_option_updated, name); } ~ConfigSharedCallback() final { LOG(INFO) << "Destroy ConfigSharedCallback"; @@ -4019,9 +4009,6 @@ void Td::init_managers() { notification_manager_ = make_unique(this, create_reference()); notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get()); G()->set_notification_manager(notification_manager_actor_.get()); - option_manager_ = make_unique(this, create_reference()); - option_manager_actor_ = register_actor("OptionManager", option_manager_.get()); - G()->set_option_manager(option_manager_actor_.get()); poll_manager_ = make_unique(this, create_reference()); poll_manager_actor_ = register_actor("PollManager", poll_manager_.get()); sponsored_message_manager_ = make_unique(this, create_reference()); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index b43b31b92..2010b66b0 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -118,8 +118,6 @@ class Td final : public Actor { void on_result(NetQueryPtr query); - void on_update_server_time_difference(); - void on_online_updated(bool force, bool send_update); void on_update_status_success(bool is_online); @@ -318,8 +316,6 @@ class Td final : public Actor { TermsOfService pending_terms_of_service_; - double last_sent_server_time_difference_ = 1e100; - struct DownloadInfo { int32 offset = -1; int32 limit = -1; From 1782b8e478d61ac6cddf2837e9acf80f96176308 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 16:16:34 +0300 Subject: [PATCH 07/16] Minor improvements. --- td/telegram/OptionManager.cpp | 2 ++ tddb/td/db/SqliteKeyValueAsync.h | 2 ++ tdutils/td/utils/buffer.cpp | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index b25abce76..fd53fb569 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -11,6 +11,7 @@ #include "td/telegram/ConfigManager.h" #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" +#include "td/telegram/DialogId.h" #include "td/telegram/Global.h" #include "td/telegram/JsonValue.h" #include "td/telegram/LanguagePackManager.h" @@ -27,6 +28,7 @@ #include "td/utils/misc.h" #include "td/utils/SliceBuilder.h" +#include "td/utils/Status.h" #include #include diff --git a/tddb/td/db/SqliteKeyValueAsync.h b/tddb/td/db/SqliteKeyValueAsync.h index 075eca1b3..462287f18 100644 --- a/tddb/td/db/SqliteKeyValueAsync.h +++ b/tddb/td/db/SqliteKeyValueAsync.h @@ -10,6 +10,8 @@ #include "td/actor/PromiseFuture.h" +#include "td/utils/common.h" + #include #include diff --git a/tdutils/td/utils/buffer.cpp b/tdutils/td/utils/buffer.cpp index d6e70a4cd..1f99540bc 100644 --- a/tdutils/td/utils/buffer.cpp +++ b/tdutils/td/utils/buffer.cpp @@ -30,7 +30,6 @@ int64 BufferAllocator::get_buffer_slice_size() { } void BufferAllocator::track_buffer_slice(int64 size) { - return; } size_t BufferAllocator::get_buffer_mem() { From 745ecb18269d2983dbc0d20930c18d9e9bab942d Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 17:45:52 +0300 Subject: [PATCH 08/16] Expect no access to a chat only if this is not a private chat. --- td/telegram/MessagesManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index db5999ede..d9648170e 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -13738,7 +13738,7 @@ std::pair> MessagesManager::creat bool has_forward_info = message_info.forward_header != nullptr; if (sender_dialog_id.is_valid() && sender_dialog_id != dialog_id && have_dialog_info_force(sender_dialog_id)) { - force_create_dialog(sender_dialog_id, "create_message", true); + force_create_dialog(sender_dialog_id, "create_message", sender_dialog_id.get_type() != DialogType::User); } LOG(INFO) << "Receive " << message_id << " in " << dialog_id << " from " << sender_user_id << "/" << sender_dialog_id; From 01b02e90285891c0c26a016f98dc653f7833fe87 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 19:19:32 +0300 Subject: [PATCH 09/16] Remove deprecated EM_LOG_DEMANGLE flag. --- tdutils/td/utils/logging.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tdutils/td/utils/logging.cpp b/tdutils/td/utils/logging.cpp index 85d14dcd5..d5cd7cad8 100644 --- a/tdutils/td/utils/logging.cpp +++ b/tdutils/td/utils/logging.cpp @@ -191,9 +191,8 @@ class DefaultLog final : public LogInterface { #elif TD_EMSCRIPTEN switch (log_level) { case VERBOSITY_NAME(FATAL): - emscripten_log( - EM_LOG_ERROR | EM_LOG_CONSOLE | EM_LOG_C_STACK | EM_LOG_JS_STACK | EM_LOG_DEMANGLE | EM_LOG_FUNC_PARAMS, - "%s", slice.c_str()); + emscripten_log(EM_LOG_ERROR | EM_LOG_CONSOLE | EM_LOG_C_STACK | EM_LOG_JS_STACK | EM_LOG_FUNC_PARAMS, "%s", + slice.c_str()); EM_ASM(throw(UTF8ToString($0)), slice.c_str()); break; case VERBOSITY_NAME(ERROR): From c743f540c568952d999f81a315fe073bc4558aec Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 19:30:38 +0300 Subject: [PATCH 10/16] Log received userFull. --- td/telegram/ContactsManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index ceb39df94..50613e0c9 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -10305,6 +10305,8 @@ void ContactsManager::on_get_users(vector> &&u } void ContactsManager::on_get_user_full(tl_object_ptr &&user) { + LOG(INFO) << "Receive " << to_string(user); + UserId user_id(user->id_); User *u = get_user(user_id); if (u == nullptr) { From cfc254e9b172499ff1975e2a0fc2ec0d437295de Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 21:25:54 +0300 Subject: [PATCH 11/16] tg_cli: fix test_init. --- td/telegram/cli.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index af6259d6b..d39457e79 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1002,8 +1002,6 @@ class CliClient final : public Actor { bad_parameters->api_id_ = api_id_; bad_parameters->api_hash_ = api_hash_; send_request(td_api::make_object(std::move(bad_parameters))); - - send_closure_later(actor_id(this), &CliClient::create_td, Slice("ClientActor3")); } } From b060536ae38f810be1b088a97cce5b9f7f002d5f Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 22:46:03 +0300 Subject: [PATCH 12/16] Return Result<...> from get_input_user. --- td/telegram/BotCommandScope.cpp | 4 +- td/telegram/ContactsManager.cpp | 202 ++++++++++++++------------- td/telegram/ContactsManager.h | 2 +- td/telegram/DialogEventLog.cpp | 8 +- td/telegram/Game.cpp | 6 +- td/telegram/GameManager.cpp | 33 ++--- td/telegram/GroupCallManager.cpp | 8 +- td/telegram/InlineQueriesManager.cpp | 14 +- td/telegram/MessageEntity.cpp | 6 +- td/telegram/MessagesManager.cpp | 33 +++-- td/telegram/PrivacyManager.cpp | 6 +- td/telegram/ReplyMarkup.cpp | 19 +-- td/telegram/StickersManager.cpp | 49 ++----- td/telegram/Td.cpp | 17 ++- 14 files changed, 195 insertions(+), 212 deletions(-) diff --git a/td/telegram/BotCommandScope.cpp b/td/telegram/BotCommandScope.cpp index 74c3ac29b..6445e7ac6 100644 --- a/td/telegram/BotCommandScope.cpp +++ b/td/telegram/BotCommandScope.cpp @@ -100,7 +100,9 @@ telegram_api::object_ptr BotCommandScope::get_inp const Td *td) const { auto input_peer = dialog_id_.is_valid() ? td->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read) : nullptr; - auto input_user = user_id_.is_valid() ? td->contacts_manager_->get_input_user(user_id_) : nullptr; + auto input_user = td->contacts_manager_->have_input_user(user_id_) + ? td->contacts_manager_->get_input_user(user_id_).move_as_ok() + : nullptr; switch (type_) { case Type::Default: return telegram_api::make_object(); diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 50613e0c9..00f03f5b1 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -1431,8 +1431,8 @@ class GetExportedChatInvitesQuery final : public Td::ResultHandler { return on_error(Status::Error(400, "Can't access the chat")); } - auto input_user = td_->contacts_manager_->get_input_user(creator_user_id); - CHECK(input_user != nullptr); + auto r_input_user = td_->contacts_manager_->get_input_user(creator_user_id); + CHECK(r_input_user.is_ok()); int32 flags = 0; if (!offset_invite_link.empty() || offset_date != 0) { @@ -1442,9 +1442,9 @@ class GetExportedChatInvitesQuery final : public Td::ResultHandler { if (is_revoked) { flags |= telegram_api::messages_getExportedChatInvites::REVOKED_MASK; } - send_query(G()->net_query_creator().create( - telegram_api::messages_getExportedChatInvites(flags, false /*ignored*/, std::move(input_peer), - std::move(input_user), offset_date, offset_invite_link, limit))); + send_query(G()->net_query_creator().create(telegram_api::messages_getExportedChatInvites( + flags, false /*ignored*/, std::move(input_peer), r_input_user.move_as_ok(), offset_date, offset_invite_link, + limit))); } void on_result(BufferSlice packet) final { @@ -1548,15 +1548,15 @@ class GetChatInviteImportersQuery final : public Td::ResultHandler { return on_error(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(); + auto r_input_user = td_->contacts_manager_->get_input_user(offset_user_id); + if (r_input_user.is_error()) { + r_input_user = make_tl_object(); } 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))); + string(), offset_date, r_input_user.move_as_ok(), limit))); } void on_result(BufferSlice packet) final { @@ -1619,9 +1619,9 @@ class GetChatJoinRequestsQuery final : public Td::ResultHandler { return on_error(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(); + auto r_input_user = td_->contacts_manager_->get_input_user(offset_user_id); + if (r_input_user.is_error()) { + r_input_user = make_tl_object(); } int32 flags = telegram_api::messages_getChatInviteImporters::REQUESTED_MASK; @@ -1633,7 +1633,7 @@ class GetChatJoinRequestsQuery final : public Td::ResultHandler { } 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))); + query, offset_date, r_input_user.move_as_ok(), limit))); } void on_result(BufferSlice packet) final { @@ -1696,9 +1696,9 @@ class HideChatJoinRequestQuery final : public Td::ResultHandler { return on_error(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(Status::Error(400, "Can't find user")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); } int32 flags = 0; @@ -1706,7 +1706,7 @@ class HideChatJoinRequestQuery final : public Td::ResultHandler { 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)))); + flags, false /*ignored*/, std::move(input_peer), r_input_user.move_as_ok()))); } void on_result(BufferSlice packet) final { @@ -1893,11 +1893,11 @@ class DeleteRevokedExportedChatInvitesQuery final : public Td::ResultHandler { return on_error(Status::Error(400, "Can't access the chat")); } - auto input_user = td_->contacts_manager_->get_input_user(creator_user_id); - CHECK(input_user != nullptr); + auto r_input_user = td_->contacts_manager_->get_input_user(creator_user_id); + CHECK(r_input_user.is_ok()); send_query(G()->net_query_creator().create( - telegram_api::messages_deleteRevokedExportedChatInvites(std::move(input_peer), std::move(input_user)))); + telegram_api::messages_deleteRevokedExportedChatInvites(std::move(input_peer), r_input_user.move_as_ok()))); } void on_result(BufferSlice packet) final { @@ -2208,10 +2208,10 @@ class CanEditChannelCreatorQuery final : public Td::ResultHandler { } void send() { - auto input_user = td_->contacts_manager_->get_input_user(td_->contacts_manager_->get_my_id()); - CHECK(input_user != nullptr); + auto r_input_user = td_->contacts_manager_->get_input_user(td_->contacts_manager_->get_my_id()); + CHECK(r_input_user.is_ok()); send_query(G()->net_query_creator().create(telegram_api::channels_editCreator( - telegram_api::make_object(), std::move(input_user), + telegram_api::make_object(), r_input_user.move_as_ok(), make_tl_object()))); } @@ -2246,12 +2246,12 @@ class EditChannelCreatorQuery final : public Td::ResultHandler { if (input_channel == nullptr) { return promise_.set_error(Status::Error(400, "Have no access to the chat")); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise_.set_error(Status::Error(400, "Have no access to the user")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise_.set_error(r_input_user.move_as_error()); } send_query(G()->net_query_creator().create(telegram_api::channels_editCreator( - std::move(input_channel), std::move(input_user), std::move(input_check_password)))); + std::move(input_channel), r_input_user.move_as_ok(), std::move(input_check_password)))); } void on_result(BufferSlice packet) final { @@ -4359,17 +4359,20 @@ void ContactsManager::SecretChat::parse(ParserT &parser) { } } -tl_object_ptr ContactsManager::get_input_user(UserId user_id) const { +Result> ContactsManager::get_input_user(UserId user_id) const { if (user_id == get_my_id()) { return make_tl_object(); } const User *u = get_user(user_id); - if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { + if (u == nullptr) { + return Status::Error(400, "User not found"); + } + if (u->access_hash == -1 || u->is_min_access_hash) { if (td_->auth_manager_->is_bot() && user_id.is_valid()) { return make_tl_object(user_id.get(), 0); } - return nullptr; + return Status::Error(400, "Have no access to the user"); } return make_tl_object(user_id.get(), u->access_hash); @@ -5166,13 +5169,13 @@ void ContactsManager::add_contact(Contact contact, bool share_phone_number, Prom LOG(INFO) << "Add " << contact << " with share_phone_number = " << share_phone_number; auto user_id = contact.get_user_id(); - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } td_->create_handler(std::move(promise)) - ->send(user_id, std::move(input_user), contact, share_phone_number); + ->send(user_id, r_input_user.move_as_ok(), contact, share_phone_number); } std::pair, vector> ContactsManager::import_contacts(const vector &contacts, @@ -5302,10 +5305,10 @@ void ContactsManager::remove_contacts(const vector &user_ids, Promiseis_contact) { - auto input_user = get_input_user(user_id); - if (input_user != nullptr) { + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_ok()) { to_delete_user_ids.push_back(user_id); - input_users.push_back(std::move(input_user)); + input_users.push_back(r_input_user.move_as_ok()); } } } @@ -5652,14 +5655,14 @@ void ContactsManager::share_phone_number(UserId user_id, Promise &&promise } LOG(INFO) << "Share phone number with " << user_id; - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } td_->messages_manager_->hide_dialog_action_bar(DialogId(user_id)); - td_->create_handler(std::move(promise))->send(user_id, std::move(input_user)); + td_->create_handler(std::move(promise))->send(user_id, r_input_user.move_as_ok()); } void ContactsManager::search_dialogs_nearby(const Location &location, @@ -6773,13 +6776,13 @@ void ContactsManager::add_chat_participant(ChatId chat_id, UserId user_id, int32 } // TODO upper bound on forward_limit - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } // TODO invoke after - td_->create_handler(std::move(promise))->send(chat_id, std::move(input_user), forward_limit); + td_->create_handler(std::move(promise))->send(chat_id, r_input_user.move_as_ok(), forward_limit); } void ContactsManager::add_channel_participant(ChannelId channel_id, UserId user_id, @@ -6792,9 +6795,9 @@ void ContactsManager::add_channel_participant(ChannelId channel_id, UserId user_ if (c == nullptr) { return promise.set_error(Status::Error(400, "Chat info not found")); } - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } if (user_id == get_my_id()) { @@ -6814,7 +6817,7 @@ void ContactsManager::add_channel_participant(ChannelId channel_id, UserId user_ speculative_add_channel_user(channel_id, user_id, DialogParticipantStatus::Member(), old_status); vector> input_users; - input_users.push_back(std::move(input_user)); + input_users.push_back(r_input_user.move_as_ok()); td_->create_handler(std::move(promise))->send(channel_id, std::move(input_users)); } @@ -6835,16 +6838,16 @@ void ContactsManager::add_channel_participants(ChannelId channel_id, const vecto vector> input_users; for (auto user_id : user_ids) { - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } if (user_id == get_my_id()) { // can't invite self continue; } - input_users.push_back(std::move(input_user)); + input_users.push_back(r_input_user.move_as_ok()); } if (input_users.empty()) { @@ -6921,9 +6924,10 @@ void ContactsManager::set_channel_participant_status_impl(ChannelId channel_id, } if (status.is_member() == old_status.is_member()) { // change rank and is_anonymous - auto input_user = get_input_user(get_my_id()); - CHECK(input_user != nullptr); - td_->create_handler(std::move(promise))->send(channel_id, std::move(input_user), status); + auto r_input_user = get_input_user(get_my_id()); + CHECK(r_input_user.is_ok()); + td_->create_handler(std::move(promise)) + ->send(channel_id, r_input_user.move_as_ok(), status); return; } if (status.is_member()) { @@ -7002,13 +7006,13 @@ void ContactsManager::promote_channel_participant(ChannelId channel_id, UserId u CHECK(!status.is_creator()); } - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } speculative_add_channel_user(channel_id, user_id, status, old_status); - td_->create_handler(std::move(promise))->send(channel_id, std::move(input_user), status); + td_->create_handler(std::move(promise))->send(channel_id, r_input_user.move_as_ok(), status); } void ContactsManager::set_chat_participant_status(ChatId chat_id, UserId user_id, DialogParticipantStatus status, @@ -7080,12 +7084,13 @@ void ContactsManager::set_chat_participant_status(ChatId chat_id, UserId user_id void ContactsManager::send_edit_chat_admin_query(ChatId chat_id, UserId user_id, bool is_administrator, Promise &&promise) { - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } - td_->create_handler(std::move(promise))->send(chat_id, std::move(input_user), is_administrator); + td_->create_handler(std::move(promise)) + ->send(chat_id, r_input_user.move_as_ok(), is_administrator); } void ContactsManager::can_transfer_ownership(Promise &&promise) { @@ -7472,13 +7477,14 @@ void ContactsManager::delete_chat_participant(ChatId chat_id, UserId user_id, bo } } } - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } // TODO invoke after - td_->create_handler(std::move(promise))->send(chat_id, std::move(input_user), revoke_messages); + td_->create_handler(std::move(promise)) + ->send(chat_id, r_input_user.move_as_ok(), revoke_messages); } void ContactsManager::restrict_channel_participant(ChannelId channel_id, DialogId participant_dialog_id, @@ -13956,14 +13962,14 @@ bool ContactsManager::get_user(UserId user_id, int left_tries, Promise &&p std::move(promise)); return false; } - auto input_user = get_input_user(user_id); - if (left_tries == 1 || input_user == nullptr) { - promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (left_tries == 1 || r_input_user.is_error()) { + promise.set_error(r_input_user.move_as_error()); return false; } vector> users; - users.push_back(std::move(input_user)); + users.push_back(r_input_user.move_as_ok()); td_->create_handler(std::move(promise))->send(std::move(users)); return false; } @@ -14014,14 +14020,14 @@ void ContactsManager::reload_user(UserId user_id, Promise &&promise) { } have_user_force(user_id); - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User info not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } // there is no much reason to combine different requests into one request vector> users; - users.push_back(std::move(input_user)); + users.push_back(r_input_user.move_as_ok()); td_->create_handler(std::move(promise))->send(std::move(users)); } @@ -14033,30 +14039,30 @@ void ContactsManager::load_user_full(UserId user_id, bool force, Promise & auto user_full = get_user_full_force(user_id); if (user_full == nullptr) { - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "Can't get info about inaccessible user")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } - return send_get_user_full_query(user_id, std::move(input_user), std::move(promise), source); + return send_get_user_full_query(user_id, r_input_user.move_as_ok(), std::move(promise), source); } if (user_full->is_expired()) { - auto input_user = get_input_user(user_id); - CHECK(input_user != nullptr); + auto r_input_user = get_input_user(user_id); + CHECK(r_input_user.is_ok()); if (td_->auth_manager_->is_bot() && !force) { - return send_get_user_full_query(user_id, std::move(input_user), std::move(promise), "load expired user_full"); + return send_get_user_full_query(user_id, r_input_user.move_as_ok(), std::move(promise), "load expired user_full"); } - send_get_user_full_query(user_id, std::move(input_user), Auto(), "load expired user_full"); + send_get_user_full_query(user_id, r_input_user.move_as_ok(), Auto(), "load expired user_full"); } promise.set_value(Unit()); } void ContactsManager::reload_user_full(UserId user_id) { - auto input_user = get_input_user(user_id); - if (input_user != nullptr) { - send_get_user_full_query(user_id, std::move(input_user), Auto(), "reload_user_full"); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_ok()) { + send_get_user_full_query(user_id, r_input_user.move_as_ok(), Auto(), "reload_user_full"); } } @@ -14089,9 +14095,9 @@ std::pair> ContactsManager::get_user_profile_photos limit = MAX_GET_PROFILE_PHOTOS; } - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + promise.set_error(r_input_user.move_as_error()); return result; } @@ -14141,20 +14147,22 @@ std::pair> ContactsManager::get_user_profile_photos limit = MAX_GET_PROFILE_PHOTOS / 5; // make limit reasonable } - td_->create_handler(std::move(promise))->send(user_id, std::move(input_user), offset, limit, 0); + td_->create_handler(std::move(promise)) + ->send(user_id, r_input_user.move_as_ok(), offset, limit, 0); return result; } void ContactsManager::reload_user_profile_photo(UserId user_id, int64 photo_id, Promise &&promise) { get_user_force(user_id); - auto input_user = get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User info not found")); + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } // this request will be needed only to download the photo, // so there is no reason to combine different requests for a photo into one request - td_->create_handler(std::move(promise))->send(user_id, std::move(input_user), -1, 1, photo_id); + td_->create_handler(std::move(promise)) + ->send(user_id, r_input_user.move_as_ok(), -1, 1, photo_id); } FileSourceId ContactsManager::get_user_profile_photo_file_source_id(UserId user_id, int64 photo_id) { @@ -15154,9 +15162,9 @@ void ContactsManager::get_channel_participant(ChannelId channel_id, DialogId par Promise &&promise) { LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id; - auto input_peer = td_->messages_manager_->get_input_peer(participant_dialog_id, AccessRights::Read); + auto input_peer = td_->messages_manager_->get_input_peer(participant_dialog_id, AccessRights::Know); if (input_peer == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + return promise.set_error(Status::Error(400, "Member not found")); } if (have_channel_participant_cache(channel_id)) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 4b589aafb..fc54082f5 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -72,7 +72,7 @@ class ContactsManager final : public Actor { static ChatId get_chat_id(const tl_object_ptr &chat); static ChannelId get_channel_id(const tl_object_ptr &chat); - tl_object_ptr get_input_user(UserId user_id) const; + Result> get_input_user(UserId user_id) const; bool have_input_user(UserId user_id) const; // TODO get_input_chat ??? diff --git a/td/telegram/DialogEventLog.cpp b/td/telegram/DialogEventLog.cpp index e6b96efd1..bc4be6089 100644 --- a/td/telegram/DialogEventLog.cpp +++ b/td/telegram/DialogEventLog.cpp @@ -488,11 +488,11 @@ void get_dialog_event_log(Td *td, DialogId dialog_id, const string &query, int64 vector> input_users; for (auto user_id : user_ids) { - auto input_user = td->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = td->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } - input_users.push_back(std::move(input_user)); + input_users.push_back(r_input_user.move_as_ok()); } td->create_handler(std::move(promise)) diff --git a/td/telegram/Game.cpp b/td/telegram/Game.cpp index 436c7fdc2..a5467597e 100644 --- a/td/telegram/Game.cpp +++ b/td/telegram/Game.cpp @@ -90,10 +90,10 @@ bool Game::has_input_media() const { } tl_object_ptr Game::get_input_media_game(const Td *td) const { - auto input_user = td->contacts_manager_->get_input_user(bot_user_id_); - CHECK(input_user != nullptr); + auto r_input_user = td->contacts_manager_->get_input_user(bot_user_id_); + CHECK(r_input_user.is_ok()); return make_tl_object( - make_tl_object(std::move(input_user), short_name_)); + make_tl_object(r_input_user.move_as_ok(), short_name_)); } bool operator==(const Game &lhs, const Game &rhs) { diff --git a/td/telegram/GameManager.cpp b/td/telegram/GameManager.cpp index 81bbfb482..648397930 100644 --- a/td/telegram/GameManager.cpp +++ b/td/telegram/GameManager.cpp @@ -217,9 +217,9 @@ void GameManager::set_game_score(FullMessageId full_message_id, bool edit_messag return promise.set_error(Status::Error(400, "Can't access the chat")); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "Invalid user identifier specified")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } if (!td_->messages_manager_->can_set_game_score(full_message_id)) { @@ -234,7 +234,7 @@ void GameManager::set_game_score(FullMessageId full_message_id, bool edit_messag send_closure(actor_id, &GameManager::on_set_game_score, full_message_id, std::move(promise)); }); send_closure(td_->create_net_actor(std::move(query_promise)), &SetGameScoreActor::send, dialog_id, - full_message_id.get_message_id(), edit_message, std::move(input_user), score, force, + full_message_id.get_message_id(), edit_message, r_input_user.move_as_ok(), score, force, MessagesManager::get_sequence_dispatcher_id(dialog_id, MessageContentType::None)); } @@ -252,13 +252,13 @@ void GameManager::set_inline_game_score(const string &inline_message_id, bool ed return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "Wrong user identifier specified")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } td_->create_handler(std::move(promise)) - ->send(std::move(input_bot_inline_message_id), edit_message, std::move(input_user), score, force); + ->send(std::move(input_bot_inline_message_id), edit_message, r_input_user.move_as_ok(), score, force); } void GameManager::get_game_high_scores(FullMessageId full_message_id, UserId user_id, @@ -278,12 +278,13 @@ void GameManager::get_game_high_scores(FullMessageId full_message_id, UserId use return promise.set_error(Status::Error(400, "Wrong message identifier specified")); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "Wrong user identifier specified")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } - td_->create_handler(std::move(promise))->send(dialog_id, message_id, std::move(input_user)); + td_->create_handler(std::move(promise)) + ->send(dialog_id, message_id, r_input_user.move_as_ok()); } void GameManager::get_inline_game_high_scores(const string &inline_message_id, UserId user_id, @@ -295,13 +296,13 @@ void GameManager::get_inline_game_high_scores(const string &inline_message_id, U return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "Wrong user identifier specified")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } td_->create_handler(std::move(promise)) - ->send(std::move(input_bot_inline_message_id), std::move(input_user)); + ->send(std::move(input_bot_inline_message_id), r_input_user.move_as_ok()); } td_api::object_ptr GameManager::get_game_high_scores_object( diff --git a/td/telegram/GroupCallManager.cpp b/td/telegram/GroupCallManager.cpp index 9beec6c29..8d27acb30 100644 --- a/td/telegram/GroupCallManager.cpp +++ b/td/telegram/GroupCallManager.cpp @@ -3329,16 +3329,16 @@ void GroupCallManager::invite_group_call_participants(GroupCallId group_call_id, vector> input_users; auto my_user_id = td_->contacts_manager_->get_my_id(); for (auto user_id : user_ids) { - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } if (user_id == my_user_id) { // can't invite self continue; } - input_users.push_back(std::move(input_user)); + input_users.push_back(r_input_user.move_as_ok()); } if (input_users.empty()) { diff --git a/td/telegram/InlineQueriesManager.cpp b/td/telegram/InlineQueriesManager.cpp index a74f2c824..575cd5d60 100644 --- a/td/telegram/InlineQueriesManager.cpp +++ b/td/telegram/InlineQueriesManager.cpp @@ -876,17 +876,17 @@ void InlineQueriesManager::loop() { auto now = Time::now(); if (now >= next_inline_query_time_) { LOG(INFO) << "Send inline query " << pending_inline_query_->query_hash; - auto bot_input_user = td_->contacts_manager_->get_input_user(pending_inline_query_->bot_user_id); - if (bot_input_user != nullptr) { + auto r_bot_input_user = td_->contacts_manager_->get_input_user(pending_inline_query_->bot_user_id); + if (r_bot_input_user.is_ok()) { if (!sent_query_.empty()) { LOG(INFO) << "Cancel inline query request"; cancel_query(sent_query_); } - sent_query_ = - td_->create_handler(std::move(pending_inline_query_->promise)) - ->send(pending_inline_query_->bot_user_id, pending_inline_query_->dialog_id, std::move(bot_input_user), - std::move(pending_inline_query_->input_peer), pending_inline_query_->user_location, - pending_inline_query_->query, pending_inline_query_->offset, pending_inline_query_->query_hash); + sent_query_ = td_->create_handler(std::move(pending_inline_query_->promise)) + ->send(pending_inline_query_->bot_user_id, pending_inline_query_->dialog_id, + r_bot_input_user.move_as_ok(), std::move(pending_inline_query_->input_peer), + pending_inline_query_->user_location, pending_inline_query_->query, + pending_inline_query_->offset, pending_inline_query_->query_hash); next_inline_query_time_ = now + INLINE_QUERY_DELAY_MS * 1e-3; } diff --git a/td/telegram/MessageEntity.cpp b/td/telegram/MessageEntity.cpp index af43bad42..c6c274ae3 100644 --- a/td/telegram/MessageEntity.cpp +++ b/td/telegram/MessageEntity.cpp @@ -4171,10 +4171,10 @@ vector> get_input_message_entities(co make_tl_object(entity.offset, entity.length, entity.argument)); break; case MessageEntity::Type::MentionName: { - auto input_user = contacts_manager->get_input_user(entity.user_id); - LOG_CHECK(input_user != nullptr) << source; + auto r_input_user = contacts_manager->get_input_user(entity.user_id); + LOG_CHECK(r_input_user.is_ok()) << source << ' ' << r_input_user.error(); result.push_back(make_tl_object(entity.offset, entity.length, - std::move(input_user))); + r_input_user.move_as_ok())); break; } default: diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d9648170e..ffb47bd5c 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -837,11 +837,11 @@ class GetCommonDialogsQuery final : public Td::ResultHandler { user_id_ = user_id; offset_chat_id_ = offset_chat_id; - auto input_user = td_->contacts_manager_->get_input_user(user_id); - CHECK(input_user != nullptr); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + CHECK(r_input_user.is_ok()); send_query(G()->net_query_creator().create( - telegram_api::messages_getCommonChats(std::move(input_user), offset_chat_id, limit))); + telegram_api::messages_getCommonChats(r_input_user.move_as_ok(), offset_chat_id, limit))); } void on_result(BufferSlice packet) final { @@ -19661,12 +19661,12 @@ DialogId MessagesManager::create_new_group_chat(const vector &user_ids, vector> input_users; for (auto user_id : user_ids) { - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + promise.set_error(r_input_user.move_as_error()); return DialogId(); } - input_users.push_back(std::move(input_user)); + input_users.push_back(r_input_user.move_as_ok()); } do { @@ -19720,11 +19720,14 @@ DialogId MessagesManager::create_new_channel_chat(const string &title, bool is_m } void MessagesManager::create_new_secret_chat(UserId user_id, Promise &&promise) { - auto user_base = td_->contacts_manager_->get_input_user(user_id); - if (user_base == nullptr || user_base->get_id() != telegram_api::inputUser::ID) { - return promise.set_error(Status::Error(400, "User not found")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return promise.set_error(r_input_user.move_as_error()); } - auto user = move_tl_object_as(user_base); + if (r_input_user.ok()->get_id() != telegram_api::inputUser::ID) { + return promise.set_error(Status::Error(400, "Can't create secret chat with self")); + } + auto user = static_cast(r_input_user.ok().get()); send_closure(G()->secret_chats_manager(), &SecretChatsManager::create_chat, UserId(user->user_id_), user->access_hash_, std::move(promise)); @@ -25276,12 +25279,12 @@ void MessagesManager::do_send_bot_start_message(UserId bot_user_id, DialogId dia if (input_peer == nullptr) { return on_send_message_fail(random_id, Status::Error(400, "Have no info about the chat")); } - auto bot_input_user = td_->contacts_manager_->get_input_user(bot_user_id); - if (bot_input_user == nullptr) { - return on_send_message_fail(random_id, Status::Error(400, "Have no info about the bot")); + auto r_bot_input_user = td_->contacts_manager_->get_input_user(bot_user_id); + if (r_bot_input_user.is_error()) { + return on_send_message_fail(random_id, r_bot_input_user.move_as_error()); } - m->send_query_ref = td_->create_handler()->send(std::move(bot_input_user), dialog_id, + m->send_query_ref = td_->create_handler()->send(r_bot_input_user.move_as_ok(), dialog_id, std::move(input_peer), parameter, random_id); } diff --git a/td/telegram/PrivacyManager.cpp b/td/telegram/PrivacyManager.cpp index 6355fba9d..c8d8f0241 100644 --- a/td/telegram/PrivacyManager.cpp +++ b/td/telegram/PrivacyManager.cpp @@ -318,9 +318,9 @@ Result PrivacyManager::UserPrivacySettin vector> PrivacyManager::UserPrivacySettingRule::get_input_users() const { vector> result; for (auto user_id : user_ids_) { - auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(user_id); - if (input_user != nullptr) { - result.push_back(std::move(input_user)); + auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_ok()) { + result.push_back(r_input_user.move_as_ok()); } else { LOG(ERROR) << "Have no access to " << user_id; } diff --git a/td/telegram/ReplyMarkup.cpp b/td/telegram/ReplyMarkup.cpp index b7d3cb441..83d06c5f2 100644 --- a/td/telegram/ReplyMarkup.cpp +++ b/td/telegram/ReplyMarkup.cpp @@ -700,25 +700,26 @@ static tl_object_ptr get_inline_keyboard_button( if (!keyboard_button.forward_text.empty()) { flags |= telegram_api::inputKeyboardButtonUrlAuth::FWD_TEXT_MASK; } - auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(UserId(bot_user_id)); - if (input_user == nullptr) { - LOG(ERROR) << "Failed to get InputUser for " << bot_user_id; + auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(UserId(bot_user_id)); + if (r_input_user.is_error()) { + LOG(ERROR) << "Failed to get InputUser for " << bot_user_id << ": " << r_input_user.error(); return make_tl_object(keyboard_button.text, keyboard_button.data); } return make_tl_object(flags, false /*ignored*/, keyboard_button.text, keyboard_button.forward_text, - keyboard_button.data, std::move(input_user)); + keyboard_button.data, r_input_user.move_as_ok()); } case InlineKeyboardButton::Type::CallbackWithPassword: UNREACHABLE(); break; case InlineKeyboardButton::Type::User: { - auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(keyboard_button.user_id); - if (input_user == nullptr) { - LOG(ERROR) << "Failed to get InputUser for " << keyboard_button.user_id; - input_user = make_tl_object(); + auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(keyboard_button.user_id); + if (r_input_user.is_error()) { + LOG(ERROR) << "Failed to get InputUser for " << keyboard_button.user_id << ": " << r_input_user.error(); + r_input_user = make_tl_object(); } - return make_tl_object(keyboard_button.text, std::move(input_user)); + return make_tl_object(keyboard_button.text, + r_input_user.move_as_ok()); } default: UNREACHABLE(); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 0080bee2c..5fd9e4d7a 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -5453,15 +5453,9 @@ FileId StickersManager::upload_sticker_file(UserId user_id, tl_object_ptrcontacts_manager_->get_my_id(); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - promise.set_error(Status::Error(400, "User not found")); - return FileId(); - } - DialogId dialog_id(user_id); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - if (input_peer == nullptr) { - promise.set_error(Status::Error(400, "Have no access to the user")); + auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + promise.set_error(r_input_user.move_as_error()); return FileId(); } @@ -5579,15 +5573,8 @@ void StickersManager::create_new_sticker_set(UserId user_id, string &title, stri if (!is_bot) { user_id = td_->contacts_manager_->get_my_id(); } - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); - } - DialogId dialog_id(user_id); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - if (input_peer == nullptr) { - return promise.set_error(Status::Error(400, "Have no access to the user")); - } + + TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); title = strip_empty_characters(title, MAX_STICKER_SET_TITLE_LENGTH); if (title.empty()) { @@ -5804,10 +5791,8 @@ void StickersManager::on_new_stickers_uploaded(int64 random_id, Result res CHECK(pending_new_sticker_set->upload_files_multipromise.promise_count() == 0); - auto input_user = td_->contacts_manager_->get_input_user(pending_new_sticker_set->user_id); - if (input_user == nullptr) { - return pending_new_sticker_set->promise.set_error(Status::Error(400, "User not found")); - } + auto &promise = pending_new_sticker_set->promise; + TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(pending_new_sticker_set->user_id)); bool is_masks = pending_new_sticker_set->is_masks; bool is_animated = pending_new_sticker_set->is_animated; @@ -5827,15 +5812,7 @@ void StickersManager::on_new_stickers_uploaded(int64 random_id, Result res void StickersManager::add_sticker_to_set(UserId user_id, string &short_name, tl_object_ptr &&sticker, Promise &&promise) { - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); - } - DialogId dialog_id(user_id); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - if (input_peer == nullptr) { - return promise.set_error(Status::Error(400, "Have no access to the user")); - } + TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); short_name = strip_empty_characters(short_name, MAX_STICKER_SET_SHORT_NAME_LENGTH); if (short_name.empty()) { @@ -5896,15 +5873,7 @@ void StickersManager::on_added_sticker_uploaded(int64 random_id, Result re void StickersManager::set_sticker_set_thumbnail(UserId user_id, string &short_name, tl_object_ptr &&thumbnail, Promise &&promise) { - auto input_user = td_->contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return promise.set_error(Status::Error(400, "User not found")); - } - DialogId dialog_id(user_id); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - if (input_peer == nullptr) { - return promise.set_error(Status::Error(400, "Have no access to the user")); - } + TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); short_name = clean_username(strip_empty_characters(short_name, MAX_STICKER_SET_SHORT_NAME_LENGTH)); if (short_name.empty()) { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index da9c01fe0..7bc1d69e6 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5606,9 +5606,9 @@ void Td::on_request(uint64 id, const td_api::createCall &request) { } UserId user_id(request.user_id_); - auto input_user = contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return send_error_raw(id, 400, "User not found"); + auto r_input_user = contacts_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return send_error_raw(id, r_input_user.error().code(), r_input_user.error().message()); } if (!G()->shared_config().get_option_boolean("calls_enabled")) { @@ -5623,7 +5623,7 @@ void Td::on_request(uint64 id, const td_api::createCall &request) { promise.set_value(result.ok().get_call_id_object()); } }); - send_closure(G()->call_manager(), &CallManager::create_call, user_id, std::move(input_user), + send_closure(G()->call_manager(), &CallManager::create_call, user_id, r_input_user.move_as_ok(), CallProtocol(*request.protocol_), request.is_video_, std::move(query_promise)); } @@ -7317,13 +7317,12 @@ void Td::on_request(uint64 id, const td_api::deletePassportElement &request) { void Td::on_request(uint64 id, td_api::setPassportElementErrors &request) { CHECK_IS_BOT(); - UserId user_id(request.user_id_); - auto input_user = contacts_manager_->get_input_user(user_id); - if (input_user == nullptr) { - return send_error_raw(id, 400, "User not found"); + auto r_input_user = contacts_manager_->get_input_user(UserId(request.user_id_)); + if (r_input_user.is_error()) { + return send_error_raw(id, r_input_user.error().code(), r_input_user.error().message()); } CREATE_OK_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::set_secure_value_errors, this, std::move(input_user), + send_closure(secure_manager_, &SecureManager::set_secure_value_errors, this, r_input_user.move_as_ok(), std::move(request.errors_), std::move(promise)); } From d7e559b45cdebaf44602608eb87c8a3ef1f31ef6 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 22:56:19 +0300 Subject: [PATCH 13/16] Move get_option_value_object to OptionManager. --- td/telegram/ConfigShared.cpp | 27 --------------------------- td/telegram/ConfigShared.h | 11 +++-------- td/telegram/OptionManager.cpp | 34 +++++++++++++++++++++++++++++----- td/telegram/OptionManager.h | 2 ++ 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/td/telegram/ConfigShared.cpp b/td/telegram/ConfigShared.cpp index 457a8c8d0..59378fe66 100644 --- a/td/telegram/ConfigShared.cpp +++ b/td/telegram/ConfigShared.cpp @@ -101,10 +101,6 @@ string ConfigShared::get_option_string(Slice name, string default_value) const { return str_value.substr(1); } -tl_object_ptr ConfigShared::get_option_value(Slice name) const { - return get_option_value_object(get_option(name)); -} - bool ConfigShared::set_option(Slice name, Slice value) { if (value.empty()) { return config_pmc_->erase(name.str()) != 0; @@ -113,29 +109,6 @@ bool ConfigShared::set_option(Slice name, Slice value) { } } -tl_object_ptr ConfigShared::get_option_value_object(Slice value) { - if (value.empty()) { - return make_tl_object(); - } - - switch (value[0]) { - case 'B': - if (value == "Btrue") { - return make_tl_object(true); - } - if (value == "Bfalse") { - return make_tl_object(false); - } - break; - case 'I': - return make_tl_object(to_integer(value.substr(1))); - case 'S': - return make_tl_object(value.substr(1).str()); - } - - return make_tl_object(value.str()); -} - void ConfigShared::on_option_updated(Slice name) const { if (callback_ != nullptr) { callback_->on_option_updated(name.str(), get_option(name)); diff --git a/td/telegram/ConfigShared.h b/td/telegram/ConfigShared.h index 1cb5682fd..b74e4f845 100644 --- a/td/telegram/ConfigShared.h +++ b/td/telegram/ConfigShared.h @@ -6,8 +6,6 @@ // #pragma once -#include "td/telegram/td_api.h" - #include "td/db/KeyValueSyncInterface.h" #include "td/utils/common.h" @@ -41,24 +39,21 @@ class ConfigShared { void set_option_string(Slice name, Slice value); bool have_option(Slice name) const; + + string get_option(Slice name) const; + std::unordered_map get_options() const; bool get_option_boolean(Slice name, bool default_value = false) const; int64 get_option_integer(Slice name, int64 default_value = 0) const; string get_option_string(Slice name, string default_value = "") const; - tl_object_ptr get_option_value(Slice name) const; - - static tl_object_ptr get_option_value_object(Slice value); - private: std::shared_ptr config_pmc_; unique_ptr callback_; bool set_option(Slice name, Slice value); - string get_option(Slice name) const; - void on_option_updated(Slice name) const; }; diff --git a/td/telegram/OptionManager.cpp b/td/telegram/OptionManager.cpp index fd53fb569..71b51cf39 100644 --- a/td/telegram/OptionManager.cpp +++ b/td/telegram/OptionManager.cpp @@ -63,7 +63,7 @@ void OptionManager::on_update_server_time_difference() { } void OptionManager::clear_options() { - for (auto &option : G()->shared_config().get_options()) { + for (const auto &option : G()->shared_config().get_options()) { if (!is_internal_option(option.first)) { send_closure( G()->td(), &Td::send_update, @@ -272,7 +272,8 @@ void OptionManager::on_option_updated(const string &name) { } // send_closure was already used in the callback - td_->send_update(td_api::make_object(name, G()->shared_config().get_option_value(name))); + td_->send_update( + td_api::make_object(name, get_option_value_object(G()->shared_config().get_option(name)))); } void OptionManager::get_option(const string &name, Promise> &&promise) { @@ -280,7 +281,7 @@ void OptionManager::get_option(const string &name, Promiseshared_config().get_option_value(name)); + promise.set_value(get_option_value_object(G()->shared_config().get_option(name))); }); }; switch (name[0]) { @@ -623,6 +624,29 @@ void OptionManager::set_option(const string &name, td_api::object_ptr OptionManager::get_option_value_object(Slice value) { + if (value.empty()) { + return td_api::make_object(); + } + + switch (value[0]) { + case 'B': + if (value == "Btrue") { + return td_api::make_object(true); + } + if (value == "Bfalse") { + return td_api::make_object(false); + } + break; + case 'I': + return td_api::make_object(to_integer(value.substr(1))); + case 'S': + return td_api::make_object(value.substr(1).str()); + } + + return td_api::make_object(value.str()); +} + void OptionManager::get_current_state(vector> &updates) const { updates.push_back(td_api::make_object( "version", td_api::make_object(Td::TDLIB_VERSION))); @@ -634,8 +658,8 @@ void OptionManager::get_current_state(vector> for (const auto &option : G()->shared_config().get_options()) { if (!is_internal_option(option.first)) { - updates.push_back(td_api::make_object( - option.first, ConfigShared::get_option_value_object(option.second))); + updates.push_back( + td_api::make_object(option.first, get_option_value_object(option.second))); } } } diff --git a/td/telegram/OptionManager.h b/td/telegram/OptionManager.h index 4dbbec97e..b975ce778 100644 --- a/td/telegram/OptionManager.h +++ b/td/telegram/OptionManager.h @@ -47,6 +47,8 @@ class OptionManager final : public Actor { static td_api::object_ptr get_unix_time_option_value_object(); + static td_api::object_ptr get_option_value_object(Slice value); + void send_unix_time_update(); Td *td_; From 957670aa0d539f1d1edd106597a922cd3758a812 Mon Sep 17 00:00:00 2001 From: levlam Date: Thu, 16 Dec 2021 23:38:44 +0300 Subject: [PATCH 14/16] Immediately close non-connected sockets. --- tdutils/td/utils/port/SocketFd.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tdutils/td/utils/port/SocketFd.cpp b/tdutils/td/utils/port/SocketFd.cpp index dbb0dcfac..ed68e03e4 100644 --- a/tdutils/td/utils/port/SocketFd.cpp +++ b/tdutils/td/utils/port/SocketFd.cpp @@ -78,11 +78,13 @@ class SocketFdImpl final : private Iocp::Callback { } void close() { - if (!is_write_waiting_) { + if (!is_write_waiting_ && is_connected_) { VLOG(fd) << get_native_fd() << " will close after ongoing write"; auto lock = lock_.lock(); - need_close_after_write_ = true; - return; + if (!is_write_waiting_) { + need_close_after_write_ = true; + return; + } } notify_iocp_close(); } @@ -168,7 +170,7 @@ class SocketFdImpl final : private Iocp::Callback { bool close_flag_{false}; bool need_close_after_write_{false}; - bool is_connected_{false}; + std::atomic is_connected_{false}; bool is_read_active_{false}; ChainBufferWriter input_writer_; ChainBufferReader input_reader_ = input_writer_.extract_reader(); From 8d69520967b5065b99f5e514739e57e92952987c Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 17 Dec 2021 00:28:01 +0300 Subject: [PATCH 15/16] Improve sponsoredMessage documentation. --- td/generate/scheme/td_api.tl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 34f6d2ad2..f56fe08a7 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -829,8 +829,11 @@ messageCalendarDay total_count:int32 message:message = MessageCalendarDay; messageCalendar total_count: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. Currently, can be only of the type messageText +//@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. Currently, can be only of the type messageText sponsoredMessage id:int32 sponsor_chat_id:int53 link:InternalLinkType content:MessageContent = SponsoredMessage; //@description Contains a list of sponsored messages @messages List of sponsored messages From eec1953c75785e790235ac6e9f779f241fa12898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hs=C3=BCan?= <8325632+up9cloud@users.noreply.github.com> Date: Wed, 15 Dec 2021 16:59:21 -0800 Subject: [PATCH 16/16] Ability to override default value of IOS_ARCH --- CMake/iOS.cmake | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/CMake/iOS.cmake b/CMake/iOS.cmake index 2b488c021..4c1e3065f 100644 --- a/CMake/iOS.cmake +++ b/CMake/iOS.cmake @@ -9,12 +9,16 @@ # OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch. # SIMULATOR - used to build for the Simulator platforms, which have an x86 arch. # +# IOS_ARCH = automatic(default) or "arch1;arch2" (e.q. "x86_64;arm64") +# By default this value will be automatically chosen based on the IOS_PLATFORM value above. +# If set manually, it will override the default and force to build those architectures only. +# # CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder -# By default this location is automatcially chosen based on the IOS_PLATFORM value above. +# By default this location is automatically chosen based on the IOS_PLATFORM value above. # If set manually, it will override the default location and force the user of a particular Developer Platform # # CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder -# By default this location is automatcially chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. +# By default this location is automatically chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. # In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path. # If set manually, this will force the use of a specific SDK version @@ -191,23 +195,23 @@ set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the select # Set the sysroot default to the most recent SDK set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") -# set the architecture for iOS -if (IOS_PLATFORM STREQUAL "OS") - set (IOS_ARCH "armv7;armv7s;arm64") -elseif (IOS_PLATFORM STREQUAL "SIMULATOR") - set (IOS_ARCH "i386;x86_64;arm64") -elseif (IOS_PLATFORM STREQUAL "WATCHOS") - set (IOS_ARCH "armv7k;arm64_32") -elseif (IOS_PLATFORM STREQUAL "WATCHSIMULATOR") - set (IOS_ARCH "i386;x86_64;arm64") -elseif (IOS_PLATFORM STREQUAL "TVOS") - set (IOS_ARCH "arm64") -elseif (IOS_PLATFORM STREQUAL "TVSIMULATOR") - set (IOS_ARCH "x86_64;arm64") -else() - message (WARNING "Unknown IOS_PLATFORM=<${IOS_PLATFORM}>") +# Set the architectures unless specified manually with IOS_ARCH +if (NOT DEFINED IOS_ARCH) + if (IOS_PLATFORM STREQUAL "OS") + set (IOS_ARCH "armv7;armv7s;arm64") + elseif (IOS_PLATFORM STREQUAL "SIMULATOR") + set (IOS_ARCH "i386;x86_64;arm64") + elseif (IOS_PLATFORM STREQUAL "WATCHOS") + set (IOS_ARCH "armv7k;arm64_32") + elseif (IOS_PLATFORM STREQUAL "WATCHSIMULATOR") + set (IOS_ARCH "i386;x86_64;arm64") + elseif (IOS_PLATFORM STREQUAL "TVOS") + set (IOS_ARCH "arm64") + elseif (IOS_PLATFORM STREQUAL "TVSIMULATOR") + set (IOS_ARCH "x86_64;arm64") + endif() endif() -message (STATUS ${IOS_ARCH}) +message (STATUS "The iOS architectures: ${IOS_ARCH}") set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")