diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 4f66a55e..a445de80 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -8832,10 +8832,10 @@ int32 MessagesManager::calc_new_unread_count(Dialog *d, MessageId max_message_id void MessagesManager::repair_server_unread_count(DialogId dialog_id, int32 unread_count) { LOG(INFO) << "Repair server unread count in " << dialog_id << " from " << unread_count; - create_actor("RepairServerUnreadCountSleepActor", 0.5, + create_actor("RepairServerUnreadCountSleepActor", 0.2, PromiseCreator::lambda([actor_id = actor_id(this), dialog_id](Result result) { - send_closure(actor_id, &MessagesManager::send_get_dialog_query, dialog_id, - Promise()); + send_closure(actor_id, &MessagesManager::send_get_dialog_query, dialog_id, Promise(), + 0); })) .release(); } @@ -19981,7 +19981,22 @@ void MessagesManager::on_get_dialog_notification_settings_query_finished(DialogI } } -void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise &&promise) { +class MessagesManager::GetDialogFromServerLogEvent { + public: + DialogId dialog_id_; + + template + void store(StorerT &storer) const { + td::store(dialog_id_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(dialog_id_, parser); + } +}; + +void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise &&promise, uint64 logevent_id) { if (td_->auth_manager_->is_bot() || dialog_id.get_type() == DialogType::SecretChat) { return promise.set_error(Status::Error(500, "Wrong getDialog query")); } @@ -19996,6 +20011,18 @@ void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise && return; } + if (logevent_id == 0 && G()->parameters().use_message_db) { + GetDialogFromServerLogEvent logevent; + logevent.dialog_id_ = dialog_id; + + auto storer = LogEventStorerImpl(logevent); + logevent_id = BinlogHelper::add(G()->td_db()->get_binlog(), LogEvent::HandlerType::GetDialogFromServer, storer); + } + if (logevent_id != 0) { + get_dialog_query_logevent_id_[dialog_id] = logevent_id; + } + + LOG(INFO) << "Send get " << dialog_id << " query"; td_->create_handler()->send(dialog_id); } @@ -20006,6 +20033,12 @@ void MessagesManager::on_get_dialog_query_finished(DialogId dialog_id, Status && auto promises = std::move(it->second); get_dialog_queries_.erase(it); + auto logevent_it = get_dialog_query_logevent_id_.find(dialog_id); + if (logevent_it != get_dialog_query_logevent_id_.end()) { + BinlogHelper::erase(G()->td_db()->get_binlog(), logevent_it->second); + get_dialog_query_logevent_id_.erase(logevent_it); + } + for (auto &promise : promises) { if (status.is_ok()) { promise.set_value(Unit()); @@ -25563,6 +25596,30 @@ void MessagesManager::on_binlog_events(vector &&events) { change_dialog_report_spam_state_on_server(dialog_id, log_event.is_spam_dialog_, event.id_, Promise()); break; } + case LogEvent::HandlerType::GetDialogFromServer: { + if (!G()->parameters().use_message_db) { + BinlogHelper::erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + GetDialogFromServerLogEvent log_event; + log_event_parse(log_event, event.data_).ensure(); + + auto dialog_id = log_event.dialog_id_; + Dependencies dependencies; + add_dialog_dependencies(dependencies, dialog_id); + resolve_dependencies_force(dependencies); + + get_dialog_force(dialog_id); // load it if exists + + if (!have_input_peer(dialog_id, AccessRights::Read)) { + BinlogHelper::erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + send_get_dialog_query(dialog_id, Promise(), event.id_); + break; + } case LogEvent::HandlerType::GetChannelDifference: { GetChannelDifferenceLogEvent log_event; log_event_parse(log_event, event.data_).ensure(); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 5487c3f7..b43d0a7b 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1857,6 +1857,7 @@ class MessagesManager : public Actor { class SendMessageLogEvent; class SendScreenshotTakenNotificationMessageLogEvent; class ToggleDialogIsPinnedOnServerLogEvent; + class GetDialogFromServerLogEvent; static constexpr size_t MAX_GROUPED_MESSAGES = 10; // server side limit static constexpr int32 MAX_GET_DIALOGS = 100; // server side limit @@ -2334,7 +2335,7 @@ class MessagesManager : public Actor { void on_get_dialogs_from_database(vector &&dialogs, Promise &&promise); - void send_get_dialog_query(DialogId dialog_id, Promise &&promise); + void send_get_dialog_query(DialogId dialog_id, Promise &&promise, uint64 logevent_id = 0); void send_search_public_dialogs_query(const string &query, Promise &&promise); @@ -2801,6 +2802,7 @@ class MessagesManager : public Actor { std::unordered_map>, DialogIdHash> get_dialog_notification_settings_queries_; std::unordered_map>, DialogIdHash> get_dialog_queries_; + std::unordered_map get_dialog_query_logevent_id_; std::unordered_map replied_by_yet_unsent_messages_; diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 1c11a45e..a6c6a19b 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -86,6 +86,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::UpdateScopeNotificationSettingsOnServer: case LogEvent::HandlerType::ResetAllNotificationSettingsOnServer: case LogEvent::HandlerType::ChangeDialogReportSpamStateOnServer: + case LogEvent::HandlerType::GetDialogFromServer: case LogEvent::HandlerType::GetChannelDifference: events.to_messages_manager.push_back(event.clone()); break; diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index fdefb24c..829b38fc 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -87,6 +87,7 @@ class LogEvent { UpdateScopeNotificationSettingsOnServer = 0x110, ResetAllNotificationSettingsOnServer = 0x111, ChangeDialogReportSpamStateOnServer = 0x112, + GetDialogFromServer = 0x113, GetChannelDifference = 0x140, ConfigPmcMagic = 0x1f18, BinlogPmcMagic = 0x4327