From 69f03d83761714215c86bc00fd5c7ab79aa74f35 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 2 Nov 2022 06:28:35 +0300 Subject: [PATCH] Improve message reply header handling. --- CMakeLists.txt | 2 + td/generate/scheme/td_api.tl | 2 +- td/telegram/MessageReplyHeader.cpp | 60 +++++++++++++++++++++ td/telegram/MessageReplyHeader.h | 29 ++++++++++ td/telegram/MessagesManager.cpp | 86 +++++++----------------------- td/telegram/MessagesManager.h | 4 +- 6 files changed, 114 insertions(+), 69 deletions(-) create mode 100644 td/telegram/MessageReplyHeader.cpp create mode 100644 td/telegram/MessageReplyHeader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6203418a4..97b39382c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -382,6 +382,7 @@ set(TDLIB_SOURCE td/telegram/MessageExtendedMedia.cpp td/telegram/MessageId.cpp td/telegram/MessageReaction.cpp + td/telegram/MessageReplyHeader.cpp td/telegram/MessageReplyInfo.cpp td/telegram/MessagesDb.cpp td/telegram/MessageSearchFilter.cpp @@ -623,6 +624,7 @@ set(TDLIB_SOURCE td/telegram/MessageId.h td/telegram/MessageLinkInfo.h td/telegram/MessageReaction.h + td/telegram/MessageReplyHeader.h td/telegram/MessageReplyInfo.h td/telegram/MessageThreadInfo.h td/telegram/MessagesDb.h diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index f5de69564..c0d716c43 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2108,7 +2108,7 @@ messageCustomServiceAction text:string = MessageContent; //@description A new high score was achieved in a game @game_message_id Identifier of the message with the game, can be an identifier of a deleted message @game_id Identifier of the game; may be different from the games presented in the message with the game @score New score messageGameScore game_message_id:int53 game_id:int64 score:int32 = MessageContent; -//@description A payment has been completed @invoice_chat_id Identifier of the chat, containing the corresponding invoice message; 0 if unknown @invoice_message_id Identifier of the message with the corresponding invoice; can be 0 or an identifier of a deleted message +//@description A payment has been completed @invoice_chat_id Identifier of the chat, containing the corresponding invoice message @invoice_message_id Identifier of the message with the corresponding invoice; can be 0 or an identifier of a deleted message //@currency Currency for the price of the product @total_amount Total price for the product, in the smallest units of the currency //@is_recurring True, if this is a recurring payment @is_first_recurring True, if this is the first recurring payment @invoice_name Name of the invoice; may be empty if unknown messagePaymentSuccessful invoice_chat_id:int53 invoice_message_id:int53 currency:string total_amount:int53 is_recurring:Bool is_first_recurring:Bool invoice_name:string = MessageContent; diff --git a/td/telegram/MessageReplyHeader.cpp b/td/telegram/MessageReplyHeader.cpp new file mode 100644 index 000000000..9d6b8ff79 --- /dev/null +++ b/td/telegram/MessageReplyHeader.cpp @@ -0,0 +1,60 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageReplyHeader.h" + +#include "td/telegram/FullMessageId.h" +#include "td/telegram/ScheduledServerMessageId.h" +#include "td/telegram/ServerMessageId.h" + +#include "td/utils/logging.h" + +namespace td { + +MessageReplyHeader::MessageReplyHeader(tl_object_ptr &&reply_header, + DialogId dialog_id, MessageId message_id, int32 date) { + if (reply_header == nullptr) { + return; + } + if (reply_header->reply_to_scheduled_) { + reply_to_message_id = MessageId(ScheduledServerMessageId(reply_header->reply_to_msg_id_), date); + if (message_id.is_scheduled()) { + auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_); + if (reply_to_peer_id != nullptr) { + reply_in_dialog_id = DialogId(reply_to_peer_id); + LOG(ERROR) << "Receive reply to " << FullMessageId{reply_in_dialog_id, reply_to_message_id} << " in " + << FullMessageId{dialog_id, message_id}; + reply_to_message_id = MessageId(); + reply_in_dialog_id = DialogId(); + } + } else { + LOG(ERROR) << "Receive reply to " << reply_to_message_id << " in " << FullMessageId{dialog_id, message_id}; + reply_to_message_id = MessageId(); + } + } else { + reply_to_message_id = MessageId(ServerMessageId(reply_header->reply_to_msg_id_)); + auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_); + if (reply_to_peer_id != nullptr) { + reply_in_dialog_id = DialogId(reply_to_peer_id); + if (!reply_in_dialog_id.is_valid()) { + LOG(ERROR) << "Receive reply in invalid " << to_string(reply_to_peer_id); + reply_to_message_id = MessageId(); + reply_in_dialog_id = DialogId(); + } + if (reply_in_dialog_id == dialog_id) { + reply_in_dialog_id = DialogId(); // just in case + } + } + if (reply_to_message_id.is_valid() && !message_id.is_scheduled() && !reply_in_dialog_id.is_valid()) { + if ((reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) { + top_thread_message_id = MessageId(ServerMessageId(reply_header->reply_to_top_id_)); + } + is_topic_message = reply_header->forum_topic_; + } + } +} + +} // namespace td diff --git a/td/telegram/MessageReplyHeader.h b/td/telegram/MessageReplyHeader.h new file mode 100644 index 000000000..cae3d946c --- /dev/null +++ b/td/telegram/MessageReplyHeader.h @@ -0,0 +1,29 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" + +namespace td { + +struct MessageReplyHeader { + MessageId reply_to_message_id; + DialogId reply_in_dialog_id; + MessageId top_thread_message_id; + bool is_topic_message = false; + + MessageReplyHeader() = default; + + MessageReplyHeader(tl_object_ptr &&reply_header, DialogId dialog_id, + MessageId message_id, int32 date); +}; + +} // namespace td diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 0bc9966eb..78ceed9df 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -14397,14 +14397,14 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId int32 flags = MESSAGE_FLAG_HAS_UNREAD_CONTENT | MESSAGE_FLAG_HAS_FROM_ID; if ((message->flags_ & secret_api::decryptedMessage::REPLY_TO_RANDOM_ID_MASK) != 0) { - message_info.reply_to_message_id = + message_info.reply_header.reply_to_message_id = get_message_id_by_random_id(d, message->reply_to_random_id_, "on_get_secret_message"); - if (!message_info.reply_to_message_id.is_valid()) { + if (!message_info.reply_header.reply_to_message_id.is_valid()) { auto dialog_it = pending_secret_message_ids_.find(message_info.dialog_id); if (dialog_it != pending_secret_message_ids_.end()) { auto message_it = dialog_it->second.find(message->reply_to_random_id_); if (message_it != dialog_it->second.end()) { - message_info.reply_to_message_id = message_it->second; + message_info.reply_header.reply_to_message_id = message_it->second; } } } @@ -14628,7 +14628,8 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( } message_info.date = message->date_; message_info.forward_header = std::move(message->fwd_from_); - message_info.reply_header = std::move(message->reply_to_); + message_info.reply_header = MessageReplyHeader(std::move(message->reply_to_), message_info.dialog_id, + message_info.message_id, message_info.date); if (message->flags_ & MESSAGE_FLAG_IS_SENT_VIA_BOT) { message_info.via_bot_user_id = UserId(message->via_bot_id_); if (!message_info.via_bot_user_id.is_valid()) { @@ -14693,25 +14694,13 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( message_info.ttl_period = message->ttl_period_; } message_info.flags = message->flags_; - - DialogId reply_in_dialog_id; - MessageId reply_to_message_id; - if (message->reply_to_ != nullptr && !message->reply_to_->reply_to_scheduled_) { - reply_to_message_id = MessageId(ServerMessageId(message->reply_to_->reply_to_msg_id_)); - if (message->reply_to_->reply_to_peer_id_ != nullptr) { - reply_in_dialog_id = DialogId(message->reply_to_->reply_to_peer_id_); - if (!reply_in_dialog_id.is_valid()) { - LOG(ERROR) << "Receive reply in invalid " << to_string(message->reply_to_->reply_to_peer_id_); - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } - } - if (message->reply_to_->forum_topic_ || message->reply_to_->reply_to_top_id_ != 0) { - message_info.reply_header = std::move(message->reply_to_); - } - } + message_info.reply_header = MessageReplyHeader(std::move(message->reply_to_), message_info.dialog_id, + message_info.message_id, message_info.date); message_info.content = get_action_message_content(td_, std::move(message->action_), message_info.dialog_id, - reply_in_dialog_id, reply_to_message_id); + message_info.reply_header.reply_in_dialog_id, + message_info.reply_header.reply_to_message_id); + message_info.reply_header.reply_in_dialog_id = DialogId(); + message_info.reply_header.reply_to_message_id = MessageId(); break; } default: @@ -14824,50 +14813,10 @@ std::pair> MessagesManager::creat date = 1; } - MessageId reply_to_message_id = message_info.reply_to_message_id; // for secret messages - DialogId reply_in_dialog_id; - MessageId top_thread_message_id; - bool is_topic_message = false; - if (message_info.reply_header != nullptr) { - if (message_info.reply_header->reply_to_scheduled_) { - reply_to_message_id = MessageId(ScheduledServerMessageId(message_info.reply_header->reply_to_msg_id_), date); - if (message_id.is_scheduled()) { - auto reply_to_peer_id = std::move(message_info.reply_header->reply_to_peer_id_); - if (reply_to_peer_id != nullptr) { - reply_in_dialog_id = DialogId(reply_to_peer_id); - LOG(ERROR) << "Receive reply to " << FullMessageId{reply_in_dialog_id, reply_to_message_id} << " in " - << FullMessageId{dialog_id, message_id}; - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } - } else { - LOG(ERROR) << "Receive reply to " << reply_to_message_id << " in " << FullMessageId{dialog_id, message_id}; - reply_to_message_id = MessageId(); - } - } else { - reply_to_message_id = MessageId(ServerMessageId(message_info.reply_header->reply_to_msg_id_)); - auto reply_to_peer_id = std::move(message_info.reply_header->reply_to_peer_id_); - if (reply_to_peer_id != nullptr) { - reply_in_dialog_id = DialogId(reply_to_peer_id); - if (!reply_in_dialog_id.is_valid()) { - LOG(ERROR) << "Receive reply in invalid " << to_string(reply_to_peer_id); - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } - if (reply_in_dialog_id == dialog_id) { - reply_in_dialog_id = DialogId(); // just in case - } - } - if (reply_to_message_id.is_valid() && !message_id.is_scheduled() && !reply_in_dialog_id.is_valid()) { - if ((message_info.reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) { - top_thread_message_id = MessageId(ServerMessageId(message_info.reply_header->reply_to_top_id_)); - } else if (!is_broadcast_channel(dialog_id)) { - top_thread_message_id = reply_to_message_id; - } - is_topic_message = message_info.reply_header->forum_topic_; - } - } - } + MessageId reply_to_message_id = message_info.reply_header.reply_to_message_id; + DialogId reply_in_dialog_id = message_info.reply_header.reply_in_dialog_id; + MessageId top_thread_message_id = message_info.reply_header.top_thread_message_id; + bool is_topic_message = message_info.reply_header.is_topic_message; fix_server_reply_to_message_id(dialog_id, message_id, reply_in_dialog_id, reply_to_message_id); fix_server_reply_to_message_id(dialog_id, message_id, reply_in_dialog_id, top_thread_message_id); @@ -14933,6 +14882,11 @@ std::pair> MessagesManager::creat forward_count = 0; } MessageReplyInfo reply_info(td_, std::move(message_info.reply_info), td_->auth_manager_->is_bot()); + if (reply_to_message_id.is_valid() && !reply_in_dialog_id.is_valid() && message_id.is_valid() && + message_id.is_server() && !top_thread_message_id.is_valid() && dialog_type == DialogType::Channel && + !is_broadcast_channel(dialog_id)) { + top_thread_message_id = reply_to_message_id; + } if (!top_thread_message_id.is_valid() && is_thread_message(dialog_id, message_id, reply_info, content_type)) { top_thread_message_id = message_id; is_topic_message = (content_type == MessageContentType::TopicCreate); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 90d654bac..4d3e0a29d 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -33,6 +33,7 @@ #include "td/telegram/MessageCopyOptions.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageLinkInfo.h" +#include "td/telegram/MessageReplyHeader.h" #include "td/telegram/MessageReplyInfo.h" #include "td/telegram/MessagesDb.h" #include "td/telegram/MessageSearchFilter.h" @@ -1043,8 +1044,7 @@ class MessagesManager final : public Actor { bool disable_web_page_preview = false; int64 random_id = 0; tl_object_ptr forward_header; - MessageId reply_to_message_id; - tl_object_ptr reply_header; + MessageReplyHeader reply_header; UserId via_bot_user_id; int32 view_count = 0; int32 forward_count = 0;