diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 65b05afd5..1eea81343 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4171,9 +4171,8 @@ sendCallRating call_id:int32 rating:int32 comment:string problems:vector promise_; - int32 offset_; - int32 limit_; - int64 random_id_; - - public: - explicit GetBlockedUsersQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(int32 offset, int32 limit, int64 random_id) { - offset_ = offset; - limit_ = limit; - random_id_ = random_id; - - send_query(G()->net_query_creator().create(telegram_api::contacts_getBlocked(offset, limit))); - } - - void on_result(uint64 id, BufferSlice packet) override { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(id, result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetBlockedUsersQuery: " << to_string(ptr); - - int32 constructor_id = ptr->get_id(); - switch (constructor_id) { - case telegram_api::contacts_blocked::ID: { - auto blocked_users = move_tl_object_as(ptr); - - td->contacts_manager_->on_get_users(std::move(blocked_users->users_), "GetBlockedUsersQuery"); - td->contacts_manager_->on_get_blocked_users_result(offset_, limit_, random_id_, - narrow_cast(blocked_users->blocked_.size()), - std::move(blocked_users->blocked_)); - break; - } - case telegram_api::contacts_blockedSlice::ID: { - auto blocked_users = move_tl_object_as(ptr); - - td->contacts_manager_->on_get_users(std::move(blocked_users->users_), "GetBlockedUsersQuery"); - td->contacts_manager_->on_get_blocked_users_result(offset_, limit_, random_id_, blocked_users->count_, - std::move(blocked_users->blocked_)); - break; - } - default: - UNREACHABLE(); - } - - promise_.set_value(Unit()); - } - - void on_error(uint64 id, Status status) override { - td->contacts_manager_->on_failed_get_blocked_users(random_id_); - promise_.set_error(std::move(status)); - } -}; - class GetContactsQuery : public Td::ResultHandler { public: void send(int32 hash) { @@ -4634,67 +4575,6 @@ bool ContactsManager::is_valid_username(const string &username) { return true; } -int64 ContactsManager::get_blocked_users(int32 offset, int32 limit, Promise &&promise) { - LOG(INFO) << "Get blocked users with offset = " << offset << " and limit = " << limit; - - if (offset < 0) { - promise.set_error(Status::Error(3, "Parameter offset must be non-negative")); - return 0; - } - - if (limit <= 0) { - promise.set_error(Status::Error(3, "Parameter limit must be positive")); - return 0; - } - - int64 random_id; - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || found_blocked_users_.find(random_id) != found_blocked_users_.end()); - found_blocked_users_[random_id]; // reserve place for result - - td_->create_handler(std::move(promise))->send(offset, limit, random_id); - return random_id; -} - -void ContactsManager::on_get_blocked_users_result(int32 offset, int32 limit, int64 random_id, int32 total_count, - vector> &&blocked_peers) { - LOG(INFO) << "Receive " << blocked_peers.size() << " blocked users out of " << total_count; - auto it = found_blocked_users_.find(random_id); - CHECK(it != found_blocked_users_.end()); - - auto &result = it->second.second; - CHECK(result.empty()); - for (auto &blocked_peer : blocked_peers) { - CHECK(blocked_peer != nullptr); - DialogId dialog_id(blocked_peer->peer_id_); - if (dialog_id.get_type() != DialogType::User) { - continue; - } - auto user_id = dialog_id.get_user_id(); - if (have_user(user_id)) { - result.push_back(user_id); - } else { - LOG(ERROR) << "Have no info about " << user_id; - } - } - it->second.first = total_count; -} - -void ContactsManager::on_failed_get_blocked_users(int64 random_id) { - auto it = found_blocked_users_.find(random_id); - CHECK(it != found_blocked_users_.end()); - found_blocked_users_.erase(it); -} - -tl_object_ptr ContactsManager::get_blocked_users_object(int64 random_id) { - auto it = found_blocked_users_.find(random_id); - CHECK(it != found_blocked_users_.end()); - auto result = get_users_object(it->second.first, it->second.second); - found_blocked_users_.erase(it); - return result; -} - int32 ContactsManager::get_user_was_online(const User *u, UserId user_id) const { if (u == nullptr || u->is_deleted) { return 0; diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 49c3a12b4..048bccf34 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -290,15 +290,6 @@ class ContactsManager : public Actor { void disconnect_website(int64 authorizations_id, Promise &&promise) const; void disconnect_all_websites(Promise &&promise) const; - int64 get_blocked_users(int32 offset, int32 limit, Promise &&promise); - - void on_get_blocked_users_result(int32 offset, int32 limit, int64 random_id, int32 total_count, - vector> &&blocked_peers); - - void on_failed_get_blocked_users(int64 random_id); - - tl_object_ptr get_blocked_users_object(int64 random_id); - void add_contact(td_api::object_ptr &&contact, bool share_phone_number, Promise &&promise); std::pair, vector> import_contacts(const vector> &contacts, @@ -1555,9 +1546,6 @@ class ContactsManager : public Actor { std::unordered_map, ChannelIdHash> cached_channel_participants_; - std::unordered_map>> - found_blocked_users_; // random_id -> [total_count, [user_id]...] - bool are_contacts_loaded_ = false; int32 next_contacts_sync_date_ = 0; Hints contacts_hints_; // search contacts by first name, last name and username diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 14c50dc0c..b81fa04af 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -850,6 +850,66 @@ class GetCommonDialogsQuery : public Td::ResultHandler { } }; +class GetBlockedDialogsQuery : public Td::ResultHandler { + Promise promise_; + int32 offset_; + int32 limit_; + int64 random_id_; + + public: + explicit GetBlockedDialogsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(int32 offset, int32 limit, int64 random_id) { + offset_ = offset; + limit_ = limit; + random_id_ = random_id; + + send_query(G()->net_query_creator().create(telegram_api::contacts_getBlocked(offset, limit))); + } + + void on_result(uint64 id, BufferSlice packet) override { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(id, result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetBlockedDialogsQuery: " << to_string(ptr); + + switch (ptr->get_id()) { + case telegram_api::contacts_blocked::ID: { + auto blocked_peers = move_tl_object_as(ptr); + + td->contacts_manager_->on_get_users(std::move(blocked_peers->users_), "GetBlockedDialogsQuery"); + td->contacts_manager_->on_get_chats(std::move(blocked_peers->chats_), "GetBlockedDialogsQuery"); + td->messages_manager_->on_get_blocked_dialogs(offset_, limit_, random_id_, + narrow_cast(blocked_peers->blocked_.size()), + std::move(blocked_peers->blocked_)); + break; + } + case telegram_api::contacts_blockedSlice::ID: { + auto blocked_peers = move_tl_object_as(ptr); + + td->contacts_manager_->on_get_users(std::move(blocked_peers->users_), "GetBlockedDialogsQuery"); + td->contacts_manager_->on_get_chats(std::move(blocked_peers->chats_), "GetBlockedDialogsQuery"); + td->messages_manager_->on_get_blocked_dialogs(offset_, limit_, random_id_, blocked_peers->count_, + std::move(blocked_peers->blocked_)); + break; + } + default: + UNREACHABLE(); + } + + promise_.set_value(Unit()); + } + + void on_error(uint64 id, Status status) override { + td->messages_manager_->on_failed_get_blocked_dialogs(random_id_); + promise_.set_error(std::move(status)); + } +}; + class CreateChatQuery : public Td::ResultHandler { Promise promise_; int64 random_id_; @@ -15507,6 +15567,72 @@ void MessagesManager::on_get_common_dialogs(UserId user_id, int32 offset_chat_id common_dialogs.total_count = total_count; } +std::pair> MessagesManager::get_blocked_dialogs(int32 offset, int32 limit, int64 &random_id, + Promise &&promise) { + LOG(INFO) << "Get blocked chats with offset = " << offset << " and limit = " << limit; + + if (random_id != 0) { + // request has already been sent before + auto it = found_blocked_dialogs_.find(random_id); + CHECK(it != found_blocked_dialogs_.end()); + auto result = std::move(it->second); + found_blocked_dialogs_.erase(it); + + promise.set_value(Unit()); + return result; + } + + if (offset < 0) { + promise.set_error(Status::Error(3, "Parameter offset must be non-negative")); + return {}; + } + + if (limit <= 0) { + promise.set_error(Status::Error(3, "Parameter limit must be positive")); + return {}; + } + + do { + random_id = Random::secure_int64(); + } while (random_id == 0 || found_blocked_dialogs_.find(random_id) != found_blocked_dialogs_.end()); + found_blocked_dialogs_[random_id]; // reserve place for result + + td_->create_handler(std::move(promise))->send(offset, limit, random_id); + return {}; +} + +void MessagesManager::on_get_blocked_dialogs(int32 offset, int32 limit, int64 random_id, int32 total_count, + vector> &&blocked_peers) { + LOG(INFO) << "Receive " << blocked_peers.size() << " blocked chats from offset " << offset << " out of " + << total_count; + auto it = found_blocked_dialogs_.find(random_id); + CHECK(it != found_blocked_dialogs_.end()); + + auto &result = it->second.second; + CHECK(result.empty()); + for (auto &blocked_peer : blocked_peers) { + CHECK(blocked_peer != nullptr); + DialogId dialog_id(blocked_peer->peer_id_); + force_create_dialog(dialog_id, "on_get_blocked_dialogs"); + if (have_dialog(dialog_id)) { + result.push_back(dialog_id); + } else { + LOG(ERROR) << "Have no info about " << dialog_id; + } + } + if (!result.empty() && offset + result.size() > static_cast(total_count)) { + LOG(ERROR) << "Fix total count of blocked chats from " << total_count << " to " << offset + result.size(); + total_count = offset + narrow_cast(result.size()); + } + it->second.first = total_count; +} + +void MessagesManager::on_failed_get_blocked_dialogs(int64 random_id) { + auto it = found_blocked_dialogs_.find(random_id); + CHECK(it != found_blocked_dialogs_.end()); + found_blocked_dialogs_.erase(it); +} + bool MessagesManager::have_message_force(FullMessageId full_message_id, const char *source) { return get_message_force(full_message_id, source) != nullptr; } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 801d1631b..e0d2fe2e3 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -553,6 +553,14 @@ class MessagesManager : public Actor { std::pair> get_common_dialogs(UserId user_id, DialogId offset_dialog_id, int32 limit, bool force, Promise &&promise); + std::pair> get_blocked_dialogs(int32 offset, int32 limit, int64 &random_id, + Promise &&promise); + + void on_get_blocked_dialogs(int32 offset, int32 limit, int64 random_id, int32 total_count, + vector> &&blocked_peers); + + void on_failed_get_blocked_dialogs(int64 random_id); + bool can_get_message_statistics(FullMessageId full_message_id); bool have_message_force(FullMessageId full_message_id, const char *source); @@ -3002,6 +3010,9 @@ class MessagesManager : public Actor { }; std::unordered_map found_common_dialogs_; + std::unordered_map>> + found_blocked_dialogs_; // random_id -> [total_count, [dialog_id]...] + std::unordered_map get_dialog_message_by_date_results_; std::unordered_map>> diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 74c1f8d11..a48861a81 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -2079,23 +2079,24 @@ class GetChatEventLogRequest : public RequestOnceActor { } }; -class GetBlockedUsersRequest : public RequestOnceActor { +class GetBlockedChatsRequest : public RequestActor<> { int32 offset_; int32 limit_; - int64 random_id_; + std::pair> dialog_ids_; + void do_run(Promise &&promise) override { - random_id_ = td->contacts_manager_->get_blocked_users(offset_, limit_, std::move(promise)); + dialog_ids_ = td->messages_manager_->get_blocked_dialogs(offset_, limit_, random_id_, std::move(promise)); } void do_send_result() override { - send_result(td->contacts_manager_->get_blocked_users_object(random_id_)); + send_result(MessagesManager::get_chats_object(dialog_ids_)); } public: - GetBlockedUsersRequest(ActorShared td, uint64 request_id, int32 offset, int32 limit) - : RequestOnceActor(std::move(td), request_id), offset_(offset), limit_(limit), random_id_(0) { + GetBlockedChatsRequest(ActorShared td, uint64 request_id, int32 offset, int32 limit) + : RequestActor(std::move(td), request_id), offset_(offset), limit_(limit), random_id_(0) { } }; @@ -6378,9 +6379,9 @@ void Td::on_request(uint64 id, const td_api::deleteFile &request) { "td_api::deleteFile"); } -void Td::on_request(uint64 id, const td_api::getBlockedUsers &request) { +void Td::on_request(uint64 id, const td_api::getBlockedChats &request) { CHECK_IS_USER(); - CREATE_REQUEST(GetBlockedUsersRequest, request.offset_, request.limit_); + CREATE_REQUEST(GetBlockedChatsRequest, request.offset_, request.limit_); } void Td::on_request(uint64 id, td_api::addContact &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 68f033ba1..532e1aec6 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -784,7 +784,7 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::deleteFile &request); - void on_request(uint64 id, const td_api::getBlockedUsers &request); + void on_request(uint64 id, const td_api::getBlockedChats &request); void on_request(uint64 id, td_api::addContact &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 603e40547..85145d6f1 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2293,7 +2293,7 @@ class CliClient final : public Actor { send_request(td_api::make_object(args)); } else if (op == "tme") { send_request(td_api::make_object(args)); - } else if (op == "gbu") { + } else if (op == "gbc") { string offset; string limit; @@ -2304,7 +2304,7 @@ class CliClient final : public Actor { if (limit.empty()) { limit = "10"; } - send_request(td_api::make_object(to_integer(offset), to_integer(limit))); + send_request(td_api::make_object(to_integer(offset), to_integer(limit))); } else if (op == "gu") { send_request(td_api::make_object(as_user_id(args))); } else if (op == "gsu") {