Move option-related functions to OptionManager.
This commit is contained in:
parent
6f7e775dee
commit
149d505781
@ -303,7 +303,6 @@ set(TDLIB_SOURCE
|
||||
td/telegram/ChannelParticipantFilter.cpp
|
||||
td/telegram/ClientActor.cpp
|
||||
td/telegram/ConfigManager.cpp
|
||||
td/telegram/ConfigShared.cpp
|
||||
td/telegram/ConnectionState.cpp
|
||||
td/telegram/Contact.cpp
|
||||
td/telegram/ContactsManager.cpp
|
||||
@ -508,7 +507,6 @@ set(TDLIB_SOURCE
|
||||
td/telegram/ChatId.h
|
||||
td/telegram/ClientActor.h
|
||||
td/telegram/ConfigManager.h
|
||||
td/telegram/ConfigShared.h
|
||||
td/telegram/ConnectionState.h
|
||||
td/telegram/Contact.h
|
||||
td/telegram/ContactsManager.h
|
||||
|
@ -281,7 +281,6 @@ function split_file($file, $chunks, $undo) {
|
||||
'audios_manager[_(-][^.]|AudiosManager' => "AudiosManager",
|
||||
'auth_manager[_(-][^.]|AuthManager' => 'AuthManager',
|
||||
'background_manager[_(-][^.]|BackgroundManager' => "BackgroundManager",
|
||||
'ConfigShared|shared_config[(]' => 'ConfigShared',
|
||||
'contacts_manager[_(-][^.]|ContactsManager([^ ;.]| [^*])' => 'ContactsManager',
|
||||
'country_info_manager[_(-][^.]|CountryInfoManager' => 'CountryInfoManager',
|
||||
'documents_manager[_(-][^.]|DocumentsManager' => "DocumentsManager",
|
||||
|
@ -1,118 +0,0 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||
//
|
||||
// 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/ConfigShared.h"
|
||||
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
ConfigShared::ConfigShared(std::shared_ptr<KeyValueSyncInterface> config_pmc) : config_pmc_(std::move(config_pmc)) {
|
||||
}
|
||||
|
||||
void ConfigShared::set_callback(unique_ptr<Callback> callback) {
|
||||
callback_ = std::move(callback);
|
||||
if (callback_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto &key_value : config_pmc_->get_all()) {
|
||||
on_option_updated(key_value.first);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigShared::set_option_boolean(Slice name, bool value) {
|
||||
if (set_option(name, value ? Slice("Btrue") : Slice("Bfalse"))) {
|
||||
on_option_updated(name);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigShared::set_option_empty(Slice name) {
|
||||
if (set_option(name, Slice())) {
|
||||
on_option_updated(name);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigShared::set_option_integer(Slice name, int64 value) {
|
||||
if (set_option(name, PSLICE() << 'I' << value)) {
|
||||
on_option_updated(name);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigShared::set_option_string(Slice name, Slice value) {
|
||||
if (set_option(name, PSLICE() << 'S' << value)) {
|
||||
on_option_updated(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigShared::have_option(Slice name) const {
|
||||
return config_pmc_->isset(name.str());
|
||||
}
|
||||
|
||||
string ConfigShared::get_option(Slice name) const {
|
||||
return config_pmc_->get(name.str());
|
||||
}
|
||||
|
||||
std::unordered_map<string, string> ConfigShared::get_options() const {
|
||||
return config_pmc_->get_all();
|
||||
}
|
||||
|
||||
bool ConfigShared::get_option_boolean(Slice name, bool default_value) const {
|
||||
auto value = get_option(name);
|
||||
if (value.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
if (value == "Btrue") {
|
||||
return true;
|
||||
}
|
||||
if (value == "Bfalse") {
|
||||
return false;
|
||||
}
|
||||
LOG(ERROR) << "Found \"" << value << "\" instead of boolean option " << name;
|
||||
return default_value;
|
||||
}
|
||||
|
||||
int64 ConfigShared::get_option_integer(Slice name, int64 default_value) const {
|
||||
auto value = get_option(name);
|
||||
if (value.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
if (value[0] != 'I') {
|
||||
LOG(ERROR) << "Found \"" << value << "\" instead of integer option " << name;
|
||||
return default_value;
|
||||
}
|
||||
return to_integer<int64>(value.substr(1));
|
||||
}
|
||||
|
||||
string ConfigShared::get_option_string(Slice name, string default_value) const {
|
||||
auto value = get_option(name);
|
||||
if (value.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
if (value[0] != 'S') {
|
||||
LOG(ERROR) << "Found \"" << value << "\" instead of string option " << name;
|
||||
return default_value;
|
||||
}
|
||||
return value.substr(1);
|
||||
}
|
||||
|
||||
bool ConfigShared::set_option(Slice name, Slice value) {
|
||||
if (value.empty()) {
|
||||
return config_pmc_->erase(name.str()) != 0;
|
||||
} else {
|
||||
return config_pmc_->set(name.str(), value.str()) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigShared::on_option_updated(Slice name) const {
|
||||
if (callback_ != nullptr) {
|
||||
callback_->on_option_updated(name.str(), get_option(name));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
@ -1,60 +0,0 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
||||
//
|
||||
// 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/db/KeyValueSyncInterface.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace td {
|
||||
|
||||
class ConfigShared {
|
||||
public:
|
||||
class Callback {
|
||||
public:
|
||||
Callback() = default;
|
||||
Callback(const Callback &) = delete;
|
||||
Callback &operator=(const Callback &) = delete;
|
||||
Callback(Callback &&) = delete;
|
||||
Callback &operator=(Callback &&) = delete;
|
||||
virtual ~Callback() = default;
|
||||
virtual void on_option_updated(const string &name, const string &value) const = 0;
|
||||
};
|
||||
|
||||
explicit ConfigShared(std::shared_ptr<KeyValueSyncInterface> config_pmc);
|
||||
|
||||
void set_callback(unique_ptr<Callback> callback);
|
||||
|
||||
void set_option_boolean(Slice name, bool value);
|
||||
void set_option_empty(Slice name);
|
||||
void set_option_integer(Slice name, int64 value);
|
||||
void set_option_string(Slice name, Slice value);
|
||||
|
||||
bool have_option(Slice name) const;
|
||||
|
||||
string get_option(Slice name) const;
|
||||
|
||||
std::unordered_map<string, string> 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;
|
||||
|
||||
private:
|
||||
std::shared_ptr<KeyValueSyncInterface> config_pmc_;
|
||||
unique_ptr<Callback> callback_;
|
||||
|
||||
bool set_option(Slice name, Slice value);
|
||||
|
||||
void on_option_updated(Slice name) const;
|
||||
};
|
||||
|
||||
} // namespace td
|
@ -7,7 +7,6 @@
|
||||
#include "td/telegram/Global.h"
|
||||
|
||||
#include "td/telegram/AuthManager.h"
|
||||
#include "td/telegram/ConfigShared.h"
|
||||
#include "td/telegram/net/ConnectionCreator.h"
|
||||
#include "td/telegram/net/NetQueryDispatcher.h"
|
||||
#include "td/telegram/net/TempAuthKeyWatchdog.h"
|
||||
@ -248,48 +247,46 @@ void Global::set_net_query_dispatcher(unique_ptr<NetQueryDispatcher> net_query_d
|
||||
net_query_dispatcher_ = std::move(net_query_dispatcher);
|
||||
}
|
||||
|
||||
void Global::set_shared_config(unique_ptr<ConfigShared> shared_config) {
|
||||
shared_config_ = std::move(shared_config);
|
||||
const OptionManager *Global::get_option_manager() const {
|
||||
CHECK(!option_manager_.empty())
|
||||
return option_manager_.get_actor_unsafe();
|
||||
}
|
||||
|
||||
OptionManager *Global::get_option_manager() {
|
||||
CHECK(!option_manager_.empty())
|
||||
return option_manager_.get_actor_unsafe();
|
||||
}
|
||||
|
||||
void Global::set_option_empty(Slice name) {
|
||||
shared_config_->set_option_empty(name);
|
||||
get_option_manager()->set_option_empty(name);
|
||||
}
|
||||
|
||||
void Global::set_option_boolean(Slice name, bool value) {
|
||||
shared_config_->set_option_boolean(name, value);
|
||||
get_option_manager()->set_option_boolean(name, value);
|
||||
}
|
||||
|
||||
void Global::set_option_integer(Slice name, int64 value) {
|
||||
shared_config_->set_option_integer(name, value);
|
||||
get_option_manager()->set_option_integer(name, value);
|
||||
}
|
||||
|
||||
void Global::set_option_string(Slice name, Slice value) {
|
||||
shared_config_->set_option_string(name, value);
|
||||
get_option_manager()->set_option_string(name, value);
|
||||
}
|
||||
|
||||
bool Global::have_option(Slice name) const {
|
||||
return shared_config_->have_option(name);
|
||||
}
|
||||
|
||||
string Global::get_option(Slice name) const {
|
||||
return shared_config_->get_option(name);
|
||||
}
|
||||
|
||||
std::unordered_map<string, string> Global::get_options() const {
|
||||
return shared_config_->get_options();
|
||||
return get_option_manager()->have_option(name);
|
||||
}
|
||||
|
||||
bool Global::get_option_boolean(Slice name, bool default_value) const {
|
||||
return shared_config_->get_option_boolean(name, default_value);
|
||||
return get_option_manager()->get_option_boolean(name, default_value);
|
||||
}
|
||||
|
||||
int64 Global::get_option_integer(Slice name, int64 default_value) const {
|
||||
return shared_config_->get_option_integer(name, default_value);
|
||||
return get_option_manager()->get_option_integer(name, default_value);
|
||||
}
|
||||
|
||||
string Global::get_option_string(Slice name, string default_value) const {
|
||||
return shared_config_->get_option_string(name, std::move(default_value));
|
||||
return get_option_manager()->get_option_string(name, std::move(default_value));
|
||||
}
|
||||
|
||||
int64 Global::get_location_key(double latitude, double longitude) {
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace td {
|
||||
|
||||
@ -38,7 +37,6 @@ class AuthManager;
|
||||
class BackgroundManager;
|
||||
class CallManager;
|
||||
class ConfigManager;
|
||||
class ConfigShared;
|
||||
class ConnectionCreator;
|
||||
class ContactsManager;
|
||||
class DownloadManager;
|
||||
@ -129,8 +127,6 @@ class Global final : public ActorContext {
|
||||
return net_query_dispatcher_.get() != nullptr;
|
||||
}
|
||||
|
||||
void set_shared_config(unique_ptr<ConfigShared> shared_config);
|
||||
|
||||
void set_option_empty(Slice name);
|
||||
|
||||
void set_option_boolean(Slice name, bool value);
|
||||
@ -141,10 +137,6 @@ class Global final : public ActorContext {
|
||||
|
||||
bool have_option(Slice name) const;
|
||||
|
||||
string get_option(Slice name) const;
|
||||
|
||||
std::unordered_map<string, string> 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;
|
||||
@ -540,8 +532,6 @@ class Global final : public ActorContext {
|
||||
LazySchedulerLocalStorage<unique_ptr<NetQueryCreator>> net_query_creator_;
|
||||
unique_ptr<NetQueryDispatcher> net_query_dispatcher_;
|
||||
|
||||
unique_ptr<ConfigShared> shared_config_;
|
||||
|
||||
int64 my_id_ = 0; // hack
|
||||
|
||||
static int64 get_location_key(double latitude, double longitude);
|
||||
@ -550,6 +540,10 @@ class Global final : public ActorContext {
|
||||
|
||||
int32 to_unix_time(double server_time) const;
|
||||
|
||||
const OptionManager *get_option_manager() const;
|
||||
|
||||
OptionManager *get_option_manager();
|
||||
|
||||
void do_save_server_time_difference();
|
||||
|
||||
void do_close(Promise<> on_finish, bool destroy_flag);
|
||||
|
@ -28,7 +28,13 @@
|
||||
#include "td/telegram/TdDb.h"
|
||||
#include "td/telegram/TopDialogManager.h"
|
||||
|
||||
#include "td/db/KeyValueSyncInterface.h"
|
||||
#include "td/db/TsSeqKeyValue.h"
|
||||
|
||||
#include "td/actor/actor.h"
|
||||
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/port/Clocks.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
@ -40,55 +46,77 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
OptionManager::OptionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||
OptionManager::OptionManager(Td *td, ActorShared<> parent)
|
||||
: td_(td)
|
||||
, parent_(std::move(parent))
|
||||
, options_(td::make_unique<TsSeqKeyValue>())
|
||||
, option_pmc_(G()->td_db()->get_config_pmc_shared()) {
|
||||
send_unix_time_update();
|
||||
|
||||
if (G()->have_option("language_database_path")) {
|
||||
G()->set_option_string("language_pack_database_path", G()->get_option_string("language_database_path"));
|
||||
G()->set_option_empty("language_database_path");
|
||||
for (const auto &name_value : option_pmc_->get_all()) {
|
||||
const string &name = name_value.first;
|
||||
const string &value = name_value.second;
|
||||
options_->set(name, value);
|
||||
if (!is_internal_option(name)) {
|
||||
if (name != "utc_time_offset") {
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
td_api::make_object<td_api::updateOption>(name, get_option_value_object(value)));
|
||||
}
|
||||
} else if (name == "otherwise_relogin_days") {
|
||||
auto days = narrow_cast<int32>(get_option_integer(name));
|
||||
if (days > 0) {
|
||||
vector<SuggestedAction> added_actions{SuggestedAction{SuggestedAction::Type::SetPassword, DialogId(), days}};
|
||||
send_closure(G()->td(), &Td::send_update, get_update_suggested_actions_object(added_actions, {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (G()->have_option("language_pack")) {
|
||||
G()->set_option_string("localization_target", G()->get_option_string("language_pack"));
|
||||
G()->set_option_empty("language_pack");
|
||||
|
||||
if (have_option("language_database_path")) {
|
||||
set_option_string("language_pack_database_path", get_option_string("language_database_path"));
|
||||
set_option_empty("language_database_path");
|
||||
}
|
||||
if (G()->have_option("language_code")) {
|
||||
G()->set_option_string("language_pack_id", G()->get_option_string("language_code"));
|
||||
G()->set_option_empty("language_code");
|
||||
if (have_option("language_pack")) {
|
||||
set_option_string("localization_target", get_option_string("language_pack"));
|
||||
set_option_empty("language_pack");
|
||||
}
|
||||
if (!G()->have_option("message_text_length_max")) {
|
||||
G()->set_option_integer("message_text_length_max", 4096);
|
||||
if (have_option("language_code")) {
|
||||
set_option_string("language_pack_id", get_option_string("language_code"));
|
||||
set_option_empty("language_code");
|
||||
}
|
||||
if (!G()->have_option("message_caption_length_max")) {
|
||||
G()->set_option_integer("message_caption_length_max", 1024);
|
||||
if (!have_option("message_text_length_max")) {
|
||||
set_option_integer("message_text_length_max", 4096);
|
||||
}
|
||||
if (!G()->have_option("bio_length_max")) {
|
||||
G()->set_option_integer("bio_length_max", 70);
|
||||
if (!have_option("message_caption_length_max")) {
|
||||
set_option_integer("message_caption_length_max", 1024);
|
||||
}
|
||||
if (!G()->have_option("suggested_video_note_length")) {
|
||||
G()->set_option_integer("suggested_video_note_length", 384);
|
||||
if (!have_option("bio_length_max")) {
|
||||
set_option_integer("bio_length_max", 70);
|
||||
}
|
||||
if (!G()->have_option("suggested_video_note_video_bitrate")) {
|
||||
G()->set_option_integer("suggested_video_note_video_bitrate", 1000);
|
||||
if (!have_option("suggested_video_note_length")) {
|
||||
set_option_integer("suggested_video_note_length", 384);
|
||||
}
|
||||
if (!G()->have_option("suggested_video_note_audio_bitrate")) {
|
||||
G()->set_option_integer("suggested_video_note_audio_bitrate", 64);
|
||||
if (!have_option("suggested_video_note_video_bitrate")) {
|
||||
set_option_integer("suggested_video_note_video_bitrate", 1000);
|
||||
}
|
||||
if (!G()->have_option("notification_sound_duration_max")) {
|
||||
G()->set_option_integer("notification_sound_duration_max", 5);
|
||||
if (!have_option("suggested_video_note_audio_bitrate")) {
|
||||
set_option_integer("suggested_video_note_audio_bitrate", 64);
|
||||
}
|
||||
if (!G()->have_option("notification_sound_size_max")) {
|
||||
G()->set_option_integer("notification_sound_size_max", 307200);
|
||||
if (!have_option("notification_sound_duration_max")) {
|
||||
set_option_integer("notification_sound_duration_max", 5);
|
||||
}
|
||||
if (!G()->have_option("notification_sound_count_max")) {
|
||||
G()->set_option_integer("notification_sound_count_max", G()->is_test_dc() ? 5 : 100);
|
||||
if (!have_option("notification_sound_size_max")) {
|
||||
set_option_integer("notification_sound_size_max", 307200);
|
||||
}
|
||||
if (!G()->have_option("chat_filter_count_max")) {
|
||||
G()->set_option_integer("chat_filter_count_max", G()->is_test_dc() ? 3 : 10);
|
||||
if (!have_option("notification_sound_count_max")) {
|
||||
set_option_integer("notification_sound_count_max", G()->is_test_dc() ? 5 : 100);
|
||||
}
|
||||
if (!G()->have_option("chat_filter_chosen_chat_count_max")) {
|
||||
G()->set_option_integer("chat_filter_chosen_chat_count_max", G()->is_test_dc() ? 5 : 100);
|
||||
if (!have_option("chat_filter_count_max")) {
|
||||
set_option_integer("chat_filter_count_max", G()->is_test_dc() ? 3 : 10);
|
||||
}
|
||||
G()->set_option_integer("utc_time_offset", Clocks::tz_offset());
|
||||
if (!have_option("chat_filter_chosen_chat_count_max")) {
|
||||
set_option_integer("chat_filter_chosen_chat_count_max", G()->is_test_dc() ? 5 : 100);
|
||||
}
|
||||
set_option_integer("utc_time_offset", Clocks::tz_offset());
|
||||
}
|
||||
|
||||
void OptionManager::tear_down() {
|
||||
@ -97,6 +125,86 @@ void OptionManager::tear_down() {
|
||||
|
||||
OptionManager::~OptionManager() = default;
|
||||
|
||||
void OptionManager::set_option_boolean(Slice name, bool value) {
|
||||
set_option(name, value ? Slice("Btrue") : Slice("Bfalse"));
|
||||
}
|
||||
|
||||
void OptionManager::set_option_empty(Slice name) {
|
||||
set_option(name, Slice());
|
||||
}
|
||||
|
||||
void OptionManager::set_option_integer(Slice name, int64 value) {
|
||||
set_option(name, PSLICE() << 'I' << value);
|
||||
}
|
||||
|
||||
void OptionManager::set_option_string(Slice name, Slice value) {
|
||||
set_option(name, PSLICE() << 'S' << value);
|
||||
}
|
||||
|
||||
bool OptionManager::have_option(Slice name) const {
|
||||
return options_->isset(name.str());
|
||||
}
|
||||
|
||||
bool OptionManager::get_option_boolean(Slice name, bool default_value) const {
|
||||
auto value = get_option(name);
|
||||
if (value.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
if (value == "Btrue") {
|
||||
return true;
|
||||
}
|
||||
if (value == "Bfalse") {
|
||||
return false;
|
||||
}
|
||||
LOG(ERROR) << "Found \"" << value << "\" instead of boolean option " << name;
|
||||
return default_value;
|
||||
}
|
||||
|
||||
int64 OptionManager::get_option_integer(Slice name, int64 default_value) const {
|
||||
auto value = get_option(name);
|
||||
if (value.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
if (value[0] != 'I') {
|
||||
LOG(ERROR) << "Found \"" << value << "\" instead of integer option " << name;
|
||||
return default_value;
|
||||
}
|
||||
return to_integer<int64>(value.substr(1));
|
||||
}
|
||||
|
||||
string OptionManager::get_option_string(Slice name, string default_value) const {
|
||||
auto value = get_option(name);
|
||||
if (value.empty()) {
|
||||
return default_value;
|
||||
}
|
||||
if (value[0] != 'S') {
|
||||
LOG(ERROR) << "Found \"" << value << "\" instead of string option " << name;
|
||||
return default_value;
|
||||
}
|
||||
return value.substr(1);
|
||||
}
|
||||
|
||||
void OptionManager::set_option(Slice name, Slice value) {
|
||||
CHECK(!name.empty());
|
||||
CHECK(Scheduler::instance()->sched_id() == 0);
|
||||
if (value.empty()) {
|
||||
if (option_pmc_->erase(name.str()) == 0) {
|
||||
return;
|
||||
}
|
||||
option_pmc_->erase(name.str());
|
||||
} else {
|
||||
if (options_->set(name, value) == 0) {
|
||||
return;
|
||||
}
|
||||
option_pmc_->set(name.str(), value.str());
|
||||
}
|
||||
on_option_updated(name);
|
||||
}
|
||||
|
||||
string OptionManager::get_option(Slice name) const {
|
||||
return options_->get(name.str());
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::OptionValue> OptionManager::get_unix_time_option_value_object() {
|
||||
return td_api::make_object<td_api::optionValueInteger>(G()->unix_time());
|
||||
}
|
||||
@ -115,7 +223,7 @@ void OptionManager::on_update_server_time_difference() {
|
||||
}
|
||||
|
||||
void OptionManager::clear_options() {
|
||||
for (const auto &option : G()->get_options()) {
|
||||
for (const auto &option : options_->get_all()) {
|
||||
if (!is_internal_option(option.first)) {
|
||||
send_closure(
|
||||
G()->td(), &Td::send_update,
|
||||
@ -185,7 +293,7 @@ bool OptionManager::is_synchronous_option(Slice name) {
|
||||
return td::contains(get_synchronous_options(), name);
|
||||
}
|
||||
|
||||
void OptionManager::on_option_updated(const string &name) {
|
||||
void OptionManager::on_option_updated(Slice name) {
|
||||
if (G()->close_flag()) {
|
||||
return;
|
||||
}
|
||||
@ -208,13 +316,13 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
break;
|
||||
case 'c':
|
||||
if (name == "connection_parameters") {
|
||||
if (G()->mtproto_header().set_parameters(G()->get_option_string(name))) {
|
||||
if (G()->mtproto_header().set_parameters(get_option_string(name))) {
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (name == "default_reaction_needs_sync" && G()->get_option_boolean(name)) {
|
||||
if (name == "default_reaction_needs_sync" && get_option_boolean(name)) {
|
||||
send_set_default_reaction_query(td_);
|
||||
}
|
||||
if (name == "dice_emojis") {
|
||||
@ -231,8 +339,7 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
&NotificationManager::on_disable_contact_registered_notifications_changed);
|
||||
}
|
||||
if (name == "disable_top_chats") {
|
||||
send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::update_is_enabled,
|
||||
!G()->get_option_boolean(name));
|
||||
send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::update_is_enabled, !get_option_boolean(name));
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
@ -250,7 +357,7 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
send_closure(td_->contacts_manager_actor_, &ContactsManager::on_ignored_restriction_reasons_changed);
|
||||
}
|
||||
if (name == "is_emulator") {
|
||||
if (G()->mtproto_header().set_is_emulator(G()->get_option_boolean(name))) {
|
||||
if (G()->mtproto_header().set_is_emulator(get_option_boolean(name))) {
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
}
|
||||
@ -258,7 +365,7 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
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()->get_option_string(name))) {
|
||||
if (G()->mtproto_header().set_language_code(get_option_string(name))) {
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
send_closure(td_->attach_menu_manager_actor_, &AttachMenuManager::reload_attach_menu_bots, Promise<Unit>());
|
||||
@ -268,14 +375,14 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
}
|
||||
if (name == "localization_target") {
|
||||
send_closure(td_->language_pack_manager_, &LanguagePackManager::on_language_pack_changed);
|
||||
if (G()->mtproto_header().set_language_pack(G()->get_option_string(name))) {
|
||||
if (G()->mtproto_header().set_language_pack(get_option_string(name))) {
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (name == "my_id") {
|
||||
G()->set_my_id(G()->get_option_integer(name));
|
||||
G()->set_my_id(get_option_integer(name));
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
@ -298,7 +405,7 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
send_closure(td_->notification_manager_actor_, &NotificationManager::on_online_cloud_timeout_changed);
|
||||
}
|
||||
if (name == "otherwise_relogin_days") {
|
||||
auto days = narrow_cast<int32>(G()->get_option_integer(name));
|
||||
auto days = narrow_cast<int32>(get_option_integer(name));
|
||||
if (days > 0) {
|
||||
vector<SuggestedAction> added_actions{SuggestedAction{SuggestedAction::Type::SetPassword, DialogId(), days}};
|
||||
send_closure(G()->td(), &Td::send_update, get_update_suggested_actions_object(added_actions, {}));
|
||||
@ -329,7 +436,7 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
send_closure(td_->storage_manager_, &StorageManager::update_use_storage_optimizer);
|
||||
}
|
||||
if (name == "utc_time_offset") {
|
||||
if (G()->mtproto_header().set_tz_offset(static_cast<int32>(G()->get_option_integer(name)))) {
|
||||
if (G()->mtproto_header().set_tz_offset(static_cast<int32>(get_option_integer(name)))) {
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
}
|
||||
@ -342,16 +449,16 @@ void OptionManager::on_option_updated(const string &name) {
|
||||
return;
|
||||
}
|
||||
|
||||
// send_closure was already used in the callback
|
||||
td_->send_update(td_api::make_object<td_api::updateOption>(name, get_option_value_object(G()->get_option(name))));
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
td_api::make_object<td_api::updateOption>(name.str(), get_option_value_object(get_option(name))));
|
||||
}
|
||||
|
||||
void OptionManager::get_option(const string &name, Promise<td_api::object_ptr<td_api::OptionValue>> &&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 {
|
||||
auto wrap_promise = [this, &promise, &name] {
|
||||
return PromiseCreator::lambda([this, promise = std::move(promise), name](Unit result) mutable {
|
||||
// the option is already updated on success, ignore errors
|
||||
promise.set_value(get_option_value_object(G()->get_option(name)));
|
||||
promise.set_value(get_option_value_object(get_option(name)));
|
||||
});
|
||||
};
|
||||
switch (name[0]) {
|
||||
@ -422,7 +529,7 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
return false;
|
||||
}
|
||||
if (value_constructor_id == td_api::optionValueEmpty::ID) {
|
||||
G()->set_option_empty(option_name);
|
||||
set_option_empty(option_name);
|
||||
} else {
|
||||
if (value_constructor_id != td_api::optionValueInteger::ID) {
|
||||
promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" must have integer value"));
|
||||
@ -436,7 +543,7 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
<< max_value << "]"));
|
||||
return false;
|
||||
}
|
||||
G()->set_option_integer(name, int_value);
|
||||
set_option_integer(name, int_value);
|
||||
}
|
||||
promise.set_value(Unit());
|
||||
return true;
|
||||
@ -447,7 +554,7 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
return false;
|
||||
}
|
||||
if (value_constructor_id == td_api::optionValueEmpty::ID) {
|
||||
G()->set_option_empty(name);
|
||||
set_option_empty(name);
|
||||
} else {
|
||||
if (value_constructor_id != td_api::optionValueBoolean::ID) {
|
||||
promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" must have boolean value"));
|
||||
@ -455,7 +562,7 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
}
|
||||
|
||||
bool bool_value = static_cast<td_api::optionValueBoolean *>(value.get())->value_;
|
||||
G()->set_option_boolean(name, bool_value);
|
||||
set_option_boolean(name, bool_value);
|
||||
}
|
||||
promise.set_value(Unit());
|
||||
return true;
|
||||
@ -466,7 +573,7 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
return false;
|
||||
}
|
||||
if (value_constructor_id == td_api::optionValueEmpty::ID) {
|
||||
G()->set_option_empty(name);
|
||||
set_option_empty(name);
|
||||
} else {
|
||||
if (value_constructor_id != td_api::optionValueString::ID) {
|
||||
promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" must have string value"));
|
||||
@ -475,10 +582,10 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
|
||||
const string &str_value = static_cast<td_api::optionValueString *>(value.get())->value_;
|
||||
if (str_value.empty()) {
|
||||
G()->set_option_empty(name);
|
||||
set_option_empty(name);
|
||||
} else {
|
||||
if (check_value(str_value)) {
|
||||
G()->set_option_string(name, str_value);
|
||||
set_option_string(name, str_value);
|
||||
} else {
|
||||
promise.set_error(Status::Error(400, PSLICE() << "Option \"" << name << "\" can't have specified value"));
|
||||
return false;
|
||||
@ -571,7 +678,7 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
return;
|
||||
}
|
||||
if (!is_bot && name == "ignore_sensitive_content_restrictions") {
|
||||
if (!G()->get_option_boolean("can_ignore_sensitive_content_restrictions")) {
|
||||
if (!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"));
|
||||
}
|
||||
@ -691,16 +798,16 @@ void OptionManager::set_option(const string &name, td_api::object_ptr<td_api::Op
|
||||
}
|
||||
switch (value_constructor_id) {
|
||||
case td_api::optionValueBoolean::ID:
|
||||
G()->set_option_boolean(name, static_cast<const td_api::optionValueBoolean *>(value.get())->value_);
|
||||
set_option_boolean(name, static_cast<const td_api::optionValueBoolean *>(value.get())->value_);
|
||||
break;
|
||||
case td_api::optionValueEmpty::ID:
|
||||
G()->set_option_empty(name);
|
||||
set_option_empty(name);
|
||||
break;
|
||||
case td_api::optionValueInteger::ID:
|
||||
G()->set_option_integer(name, static_cast<const td_api::optionValueInteger *>(value.get())->value_);
|
||||
set_option_integer(name, static_cast<const td_api::optionValueInteger *>(value.get())->value_);
|
||||
break;
|
||||
case td_api::optionValueString::ID:
|
||||
G()->set_option_string(name, static_cast<const td_api::optionValueString *>(value.get())->value_);
|
||||
set_option_string(name, static_cast<const td_api::optionValueString *>(value.get())->value_);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -752,7 +859,7 @@ void OptionManager::get_current_state(vector<td_api::object_ptr<td_api::Update>>
|
||||
|
||||
updates.push_back(td_api::make_object<td_api::updateOption>("unix_time", get_unix_time_option_value_object()));
|
||||
|
||||
for (const auto &option : G()->get_options()) {
|
||||
for (const auto &option : options_->get_all()) {
|
||||
if (!is_internal_option(option.first)) {
|
||||
updates.push_back(
|
||||
td_api::make_object<td_api::updateOption>(option.first, get_option_value_object(option.second)));
|
||||
|
@ -14,9 +14,13 @@
|
||||
#include "td/utils/Promise.h"
|
||||
#include "td/utils/Slice.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace td {
|
||||
|
||||
class KeyValueSyncInterface;
|
||||
class Td;
|
||||
class TsSeqKeyValue;
|
||||
|
||||
class OptionManager final : public Actor {
|
||||
public:
|
||||
@ -28,15 +32,29 @@ class OptionManager final : public Actor {
|
||||
OptionManager &operator=(OptionManager &&) = delete;
|
||||
~OptionManager() final;
|
||||
|
||||
void on_update_server_time_difference();
|
||||
void set_option_boolean(Slice name, bool value);
|
||||
|
||||
void on_option_updated(const string &name);
|
||||
void set_option_empty(Slice name);
|
||||
|
||||
void set_option_integer(Slice name, int64 value);
|
||||
|
||||
void set_option_string(Slice name, Slice value);
|
||||
|
||||
bool have_option(Slice name) 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;
|
||||
|
||||
void on_update_server_time_difference();
|
||||
|
||||
void get_option(const string &name, Promise<td_api::object_ptr<td_api::OptionValue>> &&promise);
|
||||
|
||||
void set_option(const string &name, td_api::object_ptr<td_api::OptionValue> &&value, Promise<Unit> &&promise);
|
||||
|
||||
static void clear_options();
|
||||
void clear_options();
|
||||
|
||||
static bool is_synchronous_option(Slice name);
|
||||
|
||||
@ -49,6 +67,12 @@ class OptionManager final : public Actor {
|
||||
private:
|
||||
void tear_down() final;
|
||||
|
||||
void set_option(Slice name, Slice value);
|
||||
|
||||
void on_option_updated(Slice name);
|
||||
|
||||
string get_option(Slice name) const;
|
||||
|
||||
static bool is_internal_option(Slice name);
|
||||
|
||||
static const vector<Slice> &get_synchronous_options();
|
||||
@ -62,6 +86,9 @@ class OptionManager final : public Actor {
|
||||
Td *td_;
|
||||
ActorShared<> parent_;
|
||||
|
||||
unique_ptr<TsSeqKeyValue> options_;
|
||||
std::shared_ptr<KeyValueSyncInterface> option_pmc_;
|
||||
|
||||
double last_sent_server_time_difference_ = 1e100;
|
||||
};
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "td/telegram/ChannelType.h"
|
||||
#include "td/telegram/ChatId.h"
|
||||
#include "td/telegram/ConfigManager.h"
|
||||
#include "td/telegram/ConfigShared.h"
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/CountryInfoManager.h"
|
||||
#include "td/telegram/DeviceTokenManager.h"
|
||||
@ -3298,7 +3297,6 @@ void Td::dec_actor_refcnt() {
|
||||
LOG(DEBUG) << "WebPagesManager was cleared" << timer;
|
||||
Promise<> promise = PromiseCreator::lambda([actor_id = create_reference()](Unit) mutable { actor_id.reset(); });
|
||||
|
||||
G()->set_shared_config(nullptr);
|
||||
if (destroy_flag_) {
|
||||
G()->close_and_destroy_all(std::move(promise));
|
||||
} else {
|
||||
@ -3371,7 +3369,7 @@ void Td::clear() {
|
||||
|
||||
Timer timer;
|
||||
if (destroy_flag_) {
|
||||
OptionManager::clear_options();
|
||||
option_manager_->clear_options();
|
||||
if (!auth_manager_->is_bot()) {
|
||||
notification_manager_->destroy_all_notifications();
|
||||
}
|
||||
@ -3643,6 +3641,9 @@ void Td::init(Result<TdDb::OpenedDatabase> r_opened_database) {
|
||||
|
||||
init_options_and_network();
|
||||
|
||||
// we need to process td_api::getOption along with td_api::setOption for consistency
|
||||
// we need to process td_api::setOption before managers and MTProto header are created,
|
||||
// because their initialiation may be affected by the options
|
||||
complete_pending_preauthentication_requests([](int32 id) {
|
||||
switch (id) {
|
||||
case td_api::getOption::ID:
|
||||
@ -3711,6 +3712,10 @@ void Td::init(Result<TdDb::OpenedDatabase> r_opened_database) {
|
||||
on_save_app_log_binlog_event(this, std::move(event));
|
||||
}
|
||||
|
||||
if (option_manager_->get_option_boolean("default_reaction_needs_sync")) {
|
||||
send_set_default_reaction_query(this);
|
||||
}
|
||||
|
||||
if (is_online_) {
|
||||
on_online_updated(true, true);
|
||||
}
|
||||
@ -3805,10 +3810,10 @@ void Td::init_options_and_network() {
|
||||
send_closure(state_manager_, &StateManager::add_callback, make_unique<StateManagerCallback>(create_reference()));
|
||||
G()->set_state_manager(state_manager_.get());
|
||||
|
||||
VLOG(td_init) << "Create ConfigShared";
|
||||
auto config_shared = td::make_unique<ConfigShared>(G()->td_db()->get_config_pmc_shared());
|
||||
auto config_shared_ptr = config_shared.get();
|
||||
G()->set_shared_config(std::move(config_shared));
|
||||
VLOG(td_init) << "Create OptionManager";
|
||||
option_manager_ = make_unique<OptionManager>(this, create_reference());
|
||||
option_manager_actor_ = register_actor("OptionManager", option_manager_.get());
|
||||
G()->set_option_manager(option_manager_actor_.get());
|
||||
|
||||
init_connection_creator();
|
||||
|
||||
@ -3819,30 +3824,6 @@ void Td::init_options_and_network() {
|
||||
VLOG(td_init) << "Create ConfigManager";
|
||||
config_manager_ = create_actor<ConfigManager>("ConfigManager", create_reference());
|
||||
G()->set_config_manager(config_manager_.get());
|
||||
|
||||
VLOG(td_init) << "Create OptionManager";
|
||||
option_manager_ = make_unique<OptionManager>(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_later(G()->option_manager(), &OptionManager::on_option_updated, name);
|
||||
}
|
||||
~ConfigSharedCallback() final {
|
||||
LOG(INFO) << "Destroy ConfigSharedCallback";
|
||||
}
|
||||
};
|
||||
// we need to set ConfigShared callback before td_api::getOption requests are processed for consistency
|
||||
// TODO currently they will be inconsistent anyway, because td_api::getOption returns current value,
|
||||
// but in td_api::updateOption there will be a newer value, obtained at the time of update creation
|
||||
// so, there can be even two succesive updateOption with the same value
|
||||
// we need to process td_api::getOption along with td_api::setOption for consistency
|
||||
// we need to process td_api::setOption before managers and MTProto header are created,
|
||||
// because their initialiation may be affected by the options
|
||||
config_shared_ptr->set_callback(make_unique<ConfigSharedCallback>());
|
||||
}
|
||||
|
||||
void Td::init_connection_creator() {
|
||||
|
@ -1126,6 +1126,12 @@ class CliClient final : public Actor {
|
||||
send_request(td_api::make_object<td_api::getTextEntities>(
|
||||
"@telegram /test_command https://telegram.org telegram.me @gif @test"));
|
||||
|
||||
send_request(
|
||||
td_api::make_object<td_api::setOption>("xxx", td_api::make_object<td_api::optionValueBoolean>(true)));
|
||||
send_request(td_api::make_object<td_api::setOption>("xxx", td_api::make_object<td_api::optionValueInteger>(1)));
|
||||
send_request(td_api::make_object<td_api::setOption>("xxx", td_api::make_object<td_api::optionValueString>("2")));
|
||||
send_request(td_api::make_object<td_api::setOption>("xxx", td_api::make_object<td_api::optionValueEmpty>()));
|
||||
|
||||
send_request(td_api::make_object<td_api::getOption>("use_pfs"));
|
||||
send_request(td_api::make_object<td_api::setOption>(
|
||||
"use_pfs", td_api::make_object<td_api::optionValueBoolean>(std::time(nullptr) / 86400 % 2 == 0)));
|
||||
|
Loading…
Reference in New Issue
Block a user