From f1519230c97003c245493724208a199687bfdbb9 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 26 Feb 2019 18:24:46 +0300 Subject: [PATCH] Update member online count from time to time. GitOrigin-RevId: 8b9e0f4d922a17c0f14755289a25e91b1ab4c6fc --- td/generate/scheme/td_api.tl | 2 +- td/telegram/ContactsManager.cpp | 18 ++++++- td/telegram/ContactsManager.h | 4 +- td/telegram/MessagesManager.cpp | 84 +++++++++++++++++++++++++++++++-- td/telegram/MessagesManager.h | 7 ++- 5 files changed, 105 insertions(+), 10 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 722c779a..6a828204 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2380,7 +2380,7 @@ updateChatReplyMarkup chat_id:int53 reply_markup_message_id:int53 = Update; //@description A chat draft has changed. Be aware that the update may come in the currently opened chat but with old content of the draft. If the user has changed the content of the draft, this update shouldn't be applied @chat_id Chat identifier @draft_message The new draft message; may be null @order New value of the chat order updateChatDraftMessage chat_id:int53 draft_message:draftMessage order:int64 = Update; -//@description The number of online group members has changed. This update is sent only for currently open chats. There is no guarantee that it will be sent just after the count has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat +//@description The number of online group members has changed. This update is sent only for currently open chats. There is no guarantee that it will be sent just after the count has changed @chat_id Identifier of the chat @online_member_count New number of online members in the chat, or 0 if unknown updateChatOnlineMemberCount chat_id:int53 online_member_count:int32 = Update; //@description A notification was changed @notification_group_id Unique notification group identifier @notification Changed notification diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index f118c6e6..343ca5cf 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -6640,6 +6640,22 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c td_->messages_manager_->on_update_dialog_notify_settings(DialogId(chat_id), std::move(chat_full->notify_settings_), "on_get_chat_full"); + int32 online_member_count = 0; + int32 time = G()->unix_time(); + for (auto &participant : chat->participants) { + auto u = get_user(participant.user_id); + if (u != nullptr) { + int32 was_online = u->was_online; + if (participant.user_id == get_my_id() && my_was_online_local_ != 0) { + was_online = my_was_online_local_; + } + if (was_online > time) { + online_member_count++; + } + } + } + td_->messages_manager_->on_update_dialog_online_member_count(DialogId(chat_id), online_member_count); + update_chat_full(chat, chat_id); } else { CHECK(chat_full_ptr->get_id() == telegram_api::channelFull::ID); @@ -6727,7 +6743,7 @@ void ContactsManager::on_get_chat_full(tl_object_ptr &&c if ((channel_full->flags_ & CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT) != 0) { online_member_count = channel_full->online_count_; } - td_->messages_manager_->on_update_channel_online_member_count(channel_id, online_member_count); + td_->messages_manager_->on_update_dialog_online_member_count(DialogId(channel_id), online_member_count); for (auto &bot_info : channel_full->bot_info_) { on_update_bot_info(std::move(bot_info)); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index c1f1597d..8d88cc57 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -438,6 +438,8 @@ class ContactsManager : public Actor { UserId get_support_user(Promise &&promise); + void repair_chat_participants(ChatId chat_id); + void after_get_difference(); void get_current_state(vector> &updates) const; @@ -839,8 +841,6 @@ class ContactsManager : public Actor { static LinkState get_link_state(tl_object_ptr &&link); - void repair_chat_participants(ChatId chat_id); - static bool is_valid_username(const string &username); bool on_update_bot_info(tl_object_ptr &&bot_info); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index f4df68ff..3f2f4194 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -83,6 +83,38 @@ void dummyUpdate::store(TlStorerToString &s, const char *field_name) const { s.store_class_end(); } +class GetOnlinesQuery : public Td::ResultHandler { + DialogId dialog_id_; + + public: + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + CHECK(dialog_id.get_type() == DialogType::Channel); + auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(0, Status::Error(400, "Can't access the chat")); + } + + send_query( + G()->net_query_creator().create(create_storer(telegram_api::messages_getOnlines(std::move(input_peer))))); + } + + 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 result = result_ptr.move_as_ok(); + td->messages_manager_->on_update_dialog_online_member_count(dialog_id_, result->onlines_); + } + + void on_error(uint64 id, Status status) override { + td->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetOnlinesQuery"); + td->messages_manager_->on_update_dialog_online_member_count(dialog_id_, 0); + } +}; + class GetDialogQuery : public Td::ResultHandler { DialogId dialog_id_; @@ -4087,6 +4119,9 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent) : td_(td), parent active_dialog_action_timeout_.set_callback(on_active_dialog_action_timeout_callback); active_dialog_action_timeout_.set_callback_data(static_cast(this)); + update_dialog_online_member_count_timeout_.set_callback(on_update_dialog_online_member_count_timeout_callback); + update_dialog_online_member_count_timeout_.set_callback_data(static_cast(this)); + sequence_dispatcher_ = create_actor("multi sequence dispatcher"); } @@ -4205,6 +4240,17 @@ void MessagesManager::on_active_dialog_action_timeout_callback(void *messages_ma DialogId(dialog_id_int)); } +void MessagesManager::on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr, + int64 dialog_id_int) { + if (G()->close_flag()) { + return; + } + + auto messages_manager = static_cast(messages_manager_ptr); + send_closure_later(messages_manager->actor_id(messages_manager), + &MessagesManager::on_update_dialog_online_member_count_timeout, DialogId(dialog_id_int)); +} + BufferSlice MessagesManager::get_dialog_database_value(const Dialog *d) { // can't use log_event_store, because it tries to parse stored Dialog LogEventStorerCalcLength storer_calc_length; @@ -5096,15 +5142,20 @@ void MessagesManager::on_update_channel_max_unavailable_message_id(ChannelId cha "on_update_channel_max_unavailable_message_id"); } -void MessagesManager::on_update_channel_online_member_count(ChannelId channel_id, int32 online_member_count) { - if (!channel_id.is_valid()) { - LOG(ERROR) << "Receive online member count in invalid " << channel_id; +void MessagesManager::on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count) { + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive online member count in invalid " << dialog_id; return; } - DialogId dialog_id(channel_id); if (is_broadcast_channel(dialog_id)) { - LOG_IF(ERROR, online_member_count != 0) << "Receive online member count in broadcast " << channel_id; + LOG_IF(ERROR, online_member_count != 0) + << "Receive online member count " << online_member_count << " in a broadcast " << dialog_id; + return; + } + + if (online_member_count < 0) { + LOG(ERROR) << "Receive online member count " << online_member_count << " in a " << dialog_id; return; } @@ -8474,6 +8525,7 @@ void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 o return; } + LOG(INFO) << "Set online member count to " << online_member_count << " in " << dialog_id << " from " << source; auto &info = dialog_online_member_counts_[dialog_id]; bool need_update = d->is_opened && (!info.is_update_sent || info.online_member_count != online_member_count); info.online_member_count = online_member_count; @@ -8483,6 +8535,27 @@ void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 o info.is_update_sent = true; send_update_chat_online_member_count(dialog_id, online_member_count); } + if (d->is_opened) { + update_dialog_online_member_count_timeout_.set_timeout_in(dialog_id.get(), ONLINE_MEMBER_COUNT_UPDATE_TIME); + } +} + +void MessagesManager::on_update_dialog_online_member_count_timeout(DialogId dialog_id) { + LOG(INFO) << "Expired timeout for online member count for " << dialog_id; + Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); + if (!d->is_opened) { + return; + } + + if (dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(dialog_id)) { + td_->create_handler()->send(dialog_id); + return; + } + if (dialog_id.get_type() == DialogType::Chat) { + td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id()); + return; + } } MessageId MessagesManager::get_message_id(const tl_object_ptr &message_ptr) { @@ -12902,6 +12975,7 @@ void MessagesManager::close_dialog(Dialog *d) { auto &info = online_count_it->second; info.is_update_sent = false; } + update_dialog_online_member_count_timeout_.cancel_timeout(d->dialog_id.get()); } } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index b18bd262..95660617 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -303,7 +303,7 @@ class MessagesManager : public Actor { void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id); - void on_update_channel_online_member_count(ChannelId channel_id, int32 online_member_count); + void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count); void on_update_include_sponsored_dialog_to_unread_count(); @@ -1461,6 +1461,8 @@ class MessagesManager : public Actor { void set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, const char *source); + void on_update_dialog_online_member_count_timeout(DialogId dialog_id); + void preload_newer_messages(const Dialog *d, MessageId max_message_id); void preload_older_messages(const Dialog *d, MessageId min_message_id); @@ -1985,6 +1987,8 @@ class MessagesManager : public Actor { static void on_active_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); + static void on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); + void load_secret_thumbnail(FileId thumbnail_file_id); static tl_object_ptr get_channel_admin_log_events_filter( @@ -2298,6 +2302,7 @@ class MessagesManager : public Actor { MultiTimeout dialog_unmute_timeout_{"DialogUnmuteTimeout"}; MultiTimeout pending_send_dialog_action_timeout_{"PendingSendDialogActionTimeout"}; MultiTimeout active_dialog_action_timeout_{"ActiveDialogActionTimeout"}; + MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"}; Hints dialogs_hints_; // search dialogs by title and username