From e77a6d839745df7768c3b7768ce5828c1b6db28d Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 12 Mar 2019 22:05:33 +0300 Subject: [PATCH] Repair online member count in small supergroups by getting they member list. GitOrigin-RevId: bf52347560b19668c302767498b63b55800f3779 --- td/telegram/ContactsManager.cpp | 49 +++++++++++++++++++++++---------- td/telegram/ContactsManager.h | 4 +++ td/telegram/MessagesManager.cpp | 9 +++++- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 31ee49f9e..b13b08763 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -6757,11 +6757,13 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c } td_->messages_manager_->on_update_dialog_pinned_message_id(DialogId(channel_id), pinned_message_id); - int32 online_member_count = 0; - if ((channel_full->flags_ & CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT) != 0) { - online_member_count = channel_full->online_count_; + if (participant_count >= 190) { + int32 online_member_count = 0; + if ((channel_full->flags_ & CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT) != 0) { + online_member_count = channel_full->online_count_; + } + td_->messages_manager_->on_update_dialog_online_member_count(DialogId(channel_id), online_member_count, true); } - td_->messages_manager_->on_update_dialog_online_member_count(DialogId(channel_id), online_member_count, true); for (auto &bot_info : channel_full->bot_info_) { on_update_bot_info(std::move(bot_info)); @@ -7442,10 +7444,8 @@ void ContactsManager::on_get_channel_participants_success( ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, int64 random_id, int32 total_count, vector> &&participants) { LOG(INFO) << "Receive " << participants.size() << " members in " << channel_id; - auto it = received_channel_participants_.find(random_id); - CHECK(it != received_channel_participants_.end()); - auto &result = it->second.second; + vector result; CHECK(result.empty()); for (auto &participant_ptr : participants) { result.push_back(get_dialog_participant(channel_id, std::move(participant_ptr))); @@ -7459,12 +7459,12 @@ void ContactsManager::on_get_channel_participants_success( total_count--; } } + if (total_count < narrow_cast(result.size())) { LOG(ERROR) << "Receive total_count = " << total_count << ", but have at least " << result.size() << " members in " << channel_id; total_count = static_cast(result.size()); } - it->second.first = total_count; auto participant_count = filter.is_recent() && total_count != 0 && total_count < 10000 ? total_count : -1; int32 administrator_count = filter.is_administrators() ? total_count : -1; @@ -7525,12 +7525,18 @@ void ContactsManager::on_get_channel_participants_success( } } } + + if (random_id != 0) { + received_channel_participants_[random_id] = {total_count, std::move(result)}; + } } void ContactsManager::on_get_channel_participants_fail(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, int32 limit, int64 random_id) { - // clean up - received_channel_participants_.erase(random_id); + if (random_id != 0) { + // clean up + received_channel_participants_.erase(random_id); + } } bool ContactsManager::speculative_add_count(int32 &count, int32 new_count) { @@ -8999,6 +9005,14 @@ DialogParticipantStatus ContactsManager::get_channel_status(const Channel *c) { return c->status; } +int32 ContactsManager::get_channel_participant_count(ChannelId channel_id) const { + auto c = get_channel(channel_id); + if (c == nullptr) { + return 0; + } + return c->participant_count; +} + bool ContactsManager::get_channel_sign_messages(ChannelId channel_id) const { auto c = get_channel(channel_id); if (c == nullptr) { @@ -9488,13 +9502,20 @@ std::pair> ContactsManager::get_channel_partici } while (random_id == 0 || received_channel_participants_.find(random_id) != received_channel_participants_.end()); received_channel_participants_[random_id]; // reserve place for result - LOG(DEBUG) << "Get members of the " << channel_id << " with offset = " << offset << " and limit = " << limit; - - td_->create_handler(std::move(promise)) - ->send(channel_id, ChannelParticipantsFilter(filter), offset, limit, random_id); + send_get_channel_participants_query(channel_id, ChannelParticipantsFilter(filter), offset, limit, random_id, + std::move(promise)); return result; } +void ContactsManager::send_get_channel_participants_query(ChannelId channel_id, ChannelParticipantsFilter filter, + int32 offset, int32 limit, int64 random_id, + Promise &&promise) { + LOG(DEBUG) << "Get members of the " << channel_id << " with filter " << filter << ", offset = " << offset + << " and limit = " << limit; + td_->create_handler(std::move(promise)) + ->send(channel_id, std::move(filter), offset, limit, random_id); +} + vector ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries, Promise &&promise) { auto it = dialog_administrators_.find(dialog_id); if (it != dialog_administrators_.end()) { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 8b93ddd49..c2d0bda44 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -375,6 +375,7 @@ class ContactsManager : public Actor { ChannelType get_channel_type(ChannelId channel_id) const; int32 get_channel_date(ChannelId channel_id) const; DialogParticipantStatus get_channel_status(ChannelId channel_id) const; + int32 get_channel_participant_count(ChannelId channel_id) const; bool get_channel_sign_messages(ChannelId channel_id) const; FileSourceId get_channel_photo_file_source_id(ChannelId channel_id); @@ -394,6 +395,9 @@ class ContactsManager : public Actor { const string &additional_query, int32 offset, int32 limit, int32 additional_limit, int64 &random_id, bool force, Promise &&promise); + void send_get_channel_participants_query(ChannelId channel_id, ChannelParticipantsFilter filter, int32 offset, + int32 limit, int64 random_id, Promise &&promise); + DialogParticipant get_dialog_participant(ChannelId channel_id, tl_object_ptr &&participant_ptr) const; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index fde29f20b..1f68b0c74 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -8614,7 +8614,14 @@ void MessagesManager::on_update_dialog_online_member_count_timeout(DialogId dial } if (dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(dialog_id)) { - td_->create_handler()->send(dialog_id); + auto participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id()); + if (participant_count == 0 || participant_count >= 195) { + td_->create_handler()->send(dialog_id); + } else { + td_->contacts_manager_->send_get_channel_participants_query( + dialog_id.get_channel_id(), + ChannelParticipantsFilter(td_api::make_object()), 0, 200, 0, Auto()); + } return; } if (dialog_id.get_type() == DialogType::Chat) {