From 9ca42ec8da0e2f75d7f5fe3e3141a38df232a85f Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 25 Dec 2020 16:12:09 +0300 Subject: [PATCH] Check message pts before merging files. --- td/telegram/MessagesManager.cpp | 33 +++++++++++++++++++++++++-------- td/telegram/MessagesManager.h | 2 +- td/telegram/UpdatesManager.cpp | 31 +++++++++++++++++++++++++++++++ td/telegram/UpdatesManager.h | 2 ++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 223c98b73..c5611499e 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3034,11 +3034,20 @@ class SendScheduledMessageActor : public NetActorOnce { }; class EditMessageActor : public NetActorOnce { - Promise promise_; + Promise promise_; DialogId dialog_id_; public: - explicit EditMessageActor(Promise &&promise) : promise_(std::move(promise)) { + explicit EditMessageActor(Promise &&promise) { + promise_ = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(Unit()); + } + }); + } + explicit EditMessageActor(Promise &&promise) : promise_(std::move(promise)) { } void send(int32 flags, DialogId dialog_id, MessageId message_id, const string &text, @@ -3097,13 +3106,16 @@ class EditMessageActor : public NetActorOnce { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for EditMessageActor: " << to_string(ptr); - td->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + auto pts = td->updates_manager_->get_update_edit_message_pts(ptr.get()); + auto promise = PromiseCreator::lambda( + [promise = std::move(promise_), pts](Result result) mutable { promise.set_value(std::move(pts)); }); + td->updates_manager_->on_get_updates(std::move(ptr), std::move(promise)); } void on_error(uint64 id, Status status) override { LOG(INFO) << "Receive error for EditMessageQuery: " << status; if (!td->auth_manager_->is_bot() && status.message() == "MESSAGE_NOT_MODIFIED") { - return promise_.set_value(Unit()); + return promise_.set_value(0); } td->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditMessageActor"); promise_.set_error(std::move(status)); @@ -23257,7 +23269,7 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Messag auto promise = PromiseCreator::lambda( [actor_id = actor_id(this), dialog_id, message_id, file_id, thumbnail_file_id, schedule_date, generation = m->edit_generation, was_uploaded, was_thumbnail_uploaded, - file_reference = FileManager::extract_file_reference(input_media)](Result result) mutable { + file_reference = FileManager::extract_file_reference(input_media)](Result result) mutable { send_closure(actor_id, &MessagesManager::on_message_media_edited, dialog_id, message_id, file_id, thumbnail_file_id, was_uploaded, was_thumbnail_uploaded, std::move(file_reference), schedule_date, generation, std::move(result)); @@ -24412,7 +24424,7 @@ void MessagesManager::cancel_edit_message_media(DialogId dialog_id, Message *m, void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId message_id, FileId file_id, FileId thumbnail_file_id, bool was_uploaded, bool was_thumbnail_uploaded, string file_reference, int32 schedule_date, uint64 generation, - Result &&result) { + Result &&result) { // must not run getDifference CHECK(message_id.is_any_server()); @@ -24425,15 +24437,20 @@ void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId mess CHECK(m->edited_content != nullptr); if (result.is_ok()) { // message content has already been replaced from updateEdit{Channel,}Message - // TODO check that it really was replaced // need only merge files from edited_content with their uploaded counterparts // updateMessageContent was already sent and needs to be sent again, // only if 'i' and 't' sizes from edited_content was added to the photo + auto pts = result.ok(); + LOG(INFO) << "Successfully edited " << message_id << " in " << dialog_id << " with pts = " << pts + << " and last edit pts = " << m->last_edit_pts; std::swap(m->content, m->edited_content); bool need_send_update_message_content = m->edited_content->get_type() == MessageContentType::Photo && m->content->get_type() == MessageContentType::Photo; - update_message_content(dialog_id, m, std::move(m->edited_content), need_send_update_message_content, true, true); + bool need_merge_files = pts != 0 && pts == m->last_edit_pts; + update_message_content(dialog_id, m, std::move(m->edited_content), need_send_update_message_content, + need_merge_files, true); } else { + LOG(INFO) << "Failed to edit " << message_id << " in " << dialog_id << ": " << result.error(); if (was_uploaded) { if (was_thumbnail_uploaded) { CHECK(thumbnail_file_id.is_valid()); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index bded8144d..508061ba1 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1811,7 +1811,7 @@ class MessagesManager : public Actor { void on_message_media_edited(DialogId dialog_id, MessageId message_id, FileId file_id, FileId thumbnail_file_id, bool was_uploaded, bool was_thumbnail_uploaded, string file_reference, - int32 scheduled_date, uint64 generation, Result &&result); + int32 scheduled_date, uint64 generation, Result &&result); MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index b8bdbd003..536ae1a6f 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1008,6 +1008,37 @@ vector UpdatesManager::get_chat_dialog_ids(const telegram_api::Updates return dialog_ids; } +int32 UpdatesManager::get_update_edit_message_pts(const telegram_api::Updates *updates_ptr) { + int32 pts = 0; + auto updates = get_updates(updates_ptr); + if (updates != nullptr) { + for (auto &update : *updates) { + int32 update_pts = [&] { + switch (update->get_id()) { + case telegram_api::updateEditMessage::ID: + return static_cast(update.get())->pts_; + case telegram_api::updateEditChannelMessage::ID: + return static_cast(update.get())->pts_; + default: + return 0; + } + }(); + if (update_pts != 0) { + if (pts == 0) { + pts = update_pts; + } else { + pts = -1; + } + } + } + } + if (pts == -1) { + LOG(ERROR) << "Receive multiple edit message updates in " << to_string(*updates_ptr); + pts = 0; + } + return pts; +} + void UpdatesManager::init_state() { if (!td_->auth_manager_->is_authorized()) { return; diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index c98a6737f..92f5a2cea 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -51,6 +51,8 @@ class UpdatesManager : public Actor { static vector get_chat_dialog_ids(const telegram_api::Updates *updates_ptr); + static int32 get_update_edit_message_pts(const telegram_api::Updates *updates_ptr); + void get_difference(const char *source); void schedule_get_difference(const char *source);