Use server-side forward as copy.
This commit is contained in:
parent
995b06b317
commit
3d796860d2
@ -2100,10 +2100,10 @@ Result<InputMessageContent> get_input_message_content(
|
||||
std::move(thumbnail), std::move(sticker_file_ids));
|
||||
}
|
||||
|
||||
bool can_have_input_media(const Td *td, const MessageContent *content) {
|
||||
bool can_have_input_media(const Td *td, const MessageContent *content, bool is_server) {
|
||||
switch (content->get_type()) {
|
||||
case MessageContentType::Game:
|
||||
return static_cast<const MessageGame *>(content)->game.has_input_media();
|
||||
return is_server || static_cast<const MessageGame *>(content)->game.has_input_media();
|
||||
case MessageContentType::Poll:
|
||||
return td->poll_manager_->has_input_media(static_cast<const MessagePoll *>(content)->poll_id);
|
||||
case MessageContentType::Unsupported:
|
||||
@ -2264,7 +2264,7 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td,
|
||||
static tl_object_ptr<telegram_api::InputMedia> get_input_media_impl(
|
||||
const MessageContent *content, Td *td, tl_object_ptr<telegram_api::InputFile> input_file,
|
||||
tl_object_ptr<telegram_api::InputFile> input_thumbnail, int32 ttl, const string &emoji) {
|
||||
if (!can_have_input_media(td, content)) {
|
||||
if (!can_have_input_media(td, content, false)) {
|
||||
return nullptr;
|
||||
}
|
||||
switch (content->get_type()) {
|
||||
@ -4356,10 +4356,10 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
|
||||
MessageContentDupType type, MessageCopyOptions &©_options) {
|
||||
CHECK(content != nullptr);
|
||||
if (copy_options.send_copy) {
|
||||
CHECK(type == MessageContentDupType::Copy);
|
||||
CHECK(type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy);
|
||||
}
|
||||
if (type != MessageContentDupType::Forward && type != MessageContentDupType::SendViaBot &&
|
||||
!can_have_input_media(td, content)) {
|
||||
!can_have_input_media(td, content, type == MessageContentDupType::ServerCopy)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -4380,7 +4380,8 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
|
||||
if (to_secret) {
|
||||
thumbnail_file_id = get_message_content_thumbnail_file_id(content, td);
|
||||
}
|
||||
auto replace_caption = type == MessageContentDupType::Copy && copy_options.replace_caption;
|
||||
auto replace_caption = (type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy) &&
|
||||
copy_options.replace_caption;
|
||||
switch (content->get_type()) {
|
||||
case MessageContentType::Animation: {
|
||||
auto result = make_unique<MessageAnimation>(*static_cast<const MessageAnimation *>(content));
|
||||
@ -4510,7 +4511,7 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
|
||||
return std::move(result);
|
||||
}
|
||||
case MessageContentType::Poll:
|
||||
if (type == MessageContentDupType::Copy) {
|
||||
if (type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy) {
|
||||
return make_unique<MessagePoll>(
|
||||
td->poll_manager_->dup_poll(static_cast<const MessagePoll *>(content)->poll_id));
|
||||
} else {
|
||||
|
@ -105,7 +105,7 @@ unique_ptr<MessageContent> create_chat_set_ttl_message_content(int32 ttl);
|
||||
Result<InputMessageContent> get_input_message_content(
|
||||
DialogId dialog_id, tl_object_ptr<td_api::InputMessageContent> &&input_message_content, Td *td);
|
||||
|
||||
bool can_have_input_media(const Td *td, const MessageContent *content);
|
||||
bool can_have_input_media(const Td *td, const MessageContent *content, bool is_server);
|
||||
|
||||
SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td,
|
||||
tl_object_ptr<telegram_api::InputEncryptedFile> input_file,
|
||||
@ -192,7 +192,7 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message_tex
|
||||
DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id,
|
||||
int32 *ttl, bool *disable_web_page_preview);
|
||||
|
||||
enum class MessageContentDupType : int32 { Send, SendViaBot, Forward, Copy };
|
||||
enum class MessageContentDupType : int32 { Send, SendViaBot, Forward, Copy, ServerCopy };
|
||||
|
||||
unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content,
|
||||
MessageContentDupType type, MessageCopyOptions &©_options);
|
||||
|
@ -26,6 +26,17 @@ struct MessageCopyOptions {
|
||||
MessageCopyOptions() = default;
|
||||
MessageCopyOptions(bool send_copy, bool remove_caption) : send_copy(send_copy), replace_caption(remove_caption) {
|
||||
}
|
||||
|
||||
bool is_supported_server_side() const {
|
||||
if (!send_copy) {
|
||||
return true;
|
||||
}
|
||||
if ((replace_caption && !new_caption.text.empty()) || top_thread_message_id.is_valid() ||
|
||||
reply_to_message_id.is_valid() || reply_markup != nullptr) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
inline StringBuilder &operator<<(StringBuilder &string_builder, MessageCopyOptions copy_options) {
|
||||
|
@ -26474,7 +26474,7 @@ bool MessagesManager::can_resend_message(const Message *m) const {
|
||||
auto content_type = m->content->get_type();
|
||||
if (m->via_bot_user_id.is_valid() || m->hide_via_bot) {
|
||||
// via bot message
|
||||
if (!can_have_input_media(td_, m->content.get())) {
|
||||
if (!can_have_input_media(td_, m->content.get(), false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -27644,10 +27644,16 @@ class MessagesManager::ForwardMessagesLogEvent {
|
||||
DialogId from_dialog_id;
|
||||
vector<MessageId> message_ids;
|
||||
vector<Message *> messages_in;
|
||||
bool drop_author;
|
||||
bool drop_media_captions;
|
||||
vector<unique_ptr<Message>> messages_out;
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(drop_author);
|
||||
STORE_FLAG(drop_media_captions);
|
||||
END_STORE_FLAGS();
|
||||
td::store(to_dialog_id, storer);
|
||||
td::store(from_dialog_id, storer);
|
||||
td::store(message_ids, storer);
|
||||
@ -27656,6 +27662,12 @@ class MessagesManager::ForwardMessagesLogEvent {
|
||||
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser) {
|
||||
if (parser.version() >= static_cast<int32>(Version::UseServerForwardAsCopy)) {
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(drop_author);
|
||||
PARSE_FLAG(drop_media_captions);
|
||||
END_PARSE_FLAGS();
|
||||
}
|
||||
td::parse(to_dialog_id, parser);
|
||||
td::parse(from_dialog_id, parser);
|
||||
td::parse(message_ids, parser);
|
||||
@ -27665,15 +27677,17 @@ class MessagesManager::ForwardMessagesLogEvent {
|
||||
|
||||
uint64 MessagesManager::save_forward_messages_log_event(DialogId to_dialog_id, DialogId from_dialog_id,
|
||||
const vector<Message *> &messages,
|
||||
const vector<MessageId> &message_ids) {
|
||||
ForwardMessagesLogEvent log_event{to_dialog_id, from_dialog_id, message_ids, messages, Auto()};
|
||||
const vector<MessageId> &message_ids, bool drop_author,
|
||||
bool drop_media_captions) {
|
||||
ForwardMessagesLogEvent log_event{to_dialog_id, from_dialog_id, message_ids, messages,
|
||||
drop_author, drop_media_captions, Auto()};
|
||||
return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::ForwardMessages,
|
||||
get_log_event_storer(log_event));
|
||||
}
|
||||
|
||||
void MessagesManager::do_forward_messages(DialogId to_dialog_id, DialogId from_dialog_id,
|
||||
const vector<Message *> &messages, const vector<MessageId> &message_ids,
|
||||
uint64 log_event_id) {
|
||||
bool drop_author, bool drop_media_captions, uint64 log_event_id) {
|
||||
CHECK(messages.size() == message_ids.size());
|
||||
if (messages.empty()) {
|
||||
return;
|
||||
@ -27683,7 +27697,8 @@ void MessagesManager::do_forward_messages(DialogId to_dialog_id, DialogId from_d
|
||||
}
|
||||
|
||||
if (log_event_id == 0 && G()->parameters().use_message_db) {
|
||||
log_event_id = save_forward_messages_log_event(to_dialog_id, from_dialog_id, messages, message_ids);
|
||||
log_event_id = save_forward_messages_log_event(to_dialog_id, from_dialog_id, messages, message_ids, drop_author,
|
||||
drop_media_captions);
|
||||
}
|
||||
|
||||
auto schedule_date = get_message_schedule_date(messages[0]);
|
||||
@ -27708,6 +27723,12 @@ void MessagesManager::do_forward_messages(DialogId to_dialog_id, DialogId from_d
|
||||
if (messages[0]->noforwards) {
|
||||
flags |= SEND_MESSAGE_FLAG_NOFORWARDS;
|
||||
}
|
||||
if (drop_author) {
|
||||
flags |= telegram_api::messages_forwardMessages::DROP_AUTHOR_MASK;
|
||||
}
|
||||
if (drop_media_captions) {
|
||||
flags |= telegram_api::messages_forwardMessages::DROP_MEDIA_CAPTIONS_MASK;
|
||||
}
|
||||
|
||||
vector<int64> random_ids =
|
||||
transform(messages, [this, to_dialog_id](const Message *m) { return begin_send_message(to_dialog_id, m); });
|
||||
@ -27780,10 +27801,13 @@ unique_ptr<MessagesManager::MessageForwardInfo> MessagesManager::create_message_
|
||||
}
|
||||
|
||||
void MessagesManager::fix_forwarded_message(Message *m, DialogId to_dialog_id, const Message *forwarded_message,
|
||||
int64 media_album_id) const {
|
||||
int64 media_album_id, bool drop_author) const {
|
||||
bool is_game = m->content->get_type() == MessageContentType::Game;
|
||||
if (!drop_author || is_game) {
|
||||
m->via_bot_user_id = forwarded_message->via_bot_user_id;
|
||||
}
|
||||
m->media_album_id = media_album_id;
|
||||
if (forwarded_message->view_count > 0 && m->forward_info != nullptr && m->view_count == 0 &&
|
||||
if (!drop_author && forwarded_message->view_count > 0 && m->forward_info != nullptr && m->view_count == 0 &&
|
||||
!(m->message_id.is_scheduled() && is_broadcast_channel(to_dialog_id))) {
|
||||
m->view_count = forwarded_message->view_count;
|
||||
m->forward_count = forwarded_message->forward_count;
|
||||
@ -27894,12 +27918,23 @@ Result<MessagesManager::ForwardedMessages> MessagesManager::get_forwarded_messag
|
||||
|
||||
bool to_secret = to_dialog_id.get_type() == DialogType::SecretChat;
|
||||
|
||||
bool can_use_server_forward = !to_secret;
|
||||
for (auto ©_option : copy_options) {
|
||||
if (!copy_option.is_supported_server_side()) {
|
||||
can_use_server_forward = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CHECK(can_use_server_forward || copy_options.size() == 1);
|
||||
|
||||
ForwardedMessages result;
|
||||
result.to_dialog = to_dialog;
|
||||
result.from_dialog = from_dialog;
|
||||
result.message_send_options = message_send_options;
|
||||
auto &copied_messages = result.copied_messages;
|
||||
auto &forwarded_message_contents = result.forwarded_message_contents;
|
||||
result.drop_author = can_use_server_forward && copy_options[0].send_copy;
|
||||
result.drop_media_captions = can_use_server_forward && copy_options[0].replace_caption;
|
||||
|
||||
std::unordered_map<int64, std::pair<int64, int32>> new_copied_media_album_ids;
|
||||
std::unordered_map<int64, std::pair<int64, int32>> new_forwarded_media_album_ids;
|
||||
@ -27921,25 +27956,28 @@ Result<MessagesManager::ForwardedMessages> MessagesManager::get_forwarded_messag
|
||||
}
|
||||
|
||||
bool need_copy = !message_id.is_server() || to_secret || copy_options[i].send_copy;
|
||||
bool is_local_copy = need_copy && !(message_id.is_server() && can_use_server_forward &&
|
||||
forwarded_message->content->get_type() != MessageContentType::Dice);
|
||||
if (!(need_copy && td_->auth_manager_->is_bot()) && !can_save_message(from_dialog_id, forwarded_message)) {
|
||||
LOG(INFO) << "Forward of " << message_id << " is restricted";
|
||||
continue;
|
||||
}
|
||||
|
||||
auto type = need_copy ? MessageContentDupType::Copy : MessageContentDupType::Forward;
|
||||
auto type = need_copy ? (is_local_copy ? MessageContentDupType::Copy : MessageContentDupType::ServerCopy)
|
||||
: MessageContentDupType::Forward;
|
||||
auto top_thread_message_id = copy_options[i].top_thread_message_id;
|
||||
auto reply_to_message_id = copy_options[i].reply_to_message_id;
|
||||
auto reply_markup = std::move(copy_options[i].reply_markup);
|
||||
unique_ptr<MessageContent> content =
|
||||
dup_message_content(td_, to_dialog_id, forwarded_message->content.get(), type, std::move(copy_options[i]));
|
||||
if (content == nullptr) {
|
||||
LOG(INFO) << "Can't forward " << message_id;
|
||||
LOG(INFO) << "Can't forward content of " << message_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
reply_to_message_id = get_reply_to_message_id(to_dialog, top_thread_message_id, reply_to_message_id, false);
|
||||
|
||||
auto can_send_status = can_send_message_content(to_dialog_id, content.get(), !need_copy, td_);
|
||||
auto can_send_status = can_send_message_content(to_dialog_id, content.get(), !is_local_copy, td_);
|
||||
if (can_send_status.is_error()) {
|
||||
LOG(INFO) << "Can't forward " << message_id << ": " << can_send_status.message();
|
||||
continue;
|
||||
@ -27957,7 +27995,7 @@ Result<MessagesManager::ForwardedMessages> MessagesManager::get_forwarded_messag
|
||||
}
|
||||
|
||||
if (forwarded_message->media_album_id != 0) {
|
||||
auto &new_media_album_id = need_copy ? new_copied_media_album_ids[forwarded_message->media_album_id]
|
||||
auto &new_media_album_id = is_local_copy ? new_copied_media_album_ids[forwarded_message->media_album_id]
|
||||
: new_forwarded_media_album_ids[forwarded_message->media_album_id];
|
||||
new_media_album_id.second++;
|
||||
if (new_media_album_id.second == 2) { // have at least 2 messages in the new album
|
||||
@ -27970,7 +28008,7 @@ Result<MessagesManager::ForwardedMessages> MessagesManager::get_forwarded_messag
|
||||
}
|
||||
}
|
||||
|
||||
if (need_copy) {
|
||||
if (is_local_copy) {
|
||||
copied_messages.push_back({std::move(content), top_thread_message_id, reply_to_message_id,
|
||||
std::move(reply_markup), forwarded_message->media_album_id,
|
||||
get_message_disable_web_page_preview(forwarded_message), i});
|
||||
@ -28030,6 +28068,8 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
auto message_send_options = forwarded_messages_info.message_send_options;
|
||||
auto &copied_messages = forwarded_messages_info.copied_messages;
|
||||
auto &forwarded_message_contents = forwarded_messages_info.forwarded_message_contents;
|
||||
auto drop_author = forwarded_messages_info.drop_author;
|
||||
auto drop_media_captions = forwarded_messages_info.drop_media_captions;
|
||||
|
||||
vector<td_api::object_ptr<td_api::message>> result(message_ids.size());
|
||||
vector<Message *> forwarded_messages;
|
||||
@ -28041,7 +28081,8 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
CHECK(forwarded_message != nullptr);
|
||||
|
||||
auto content = std::move(forwarded_message_contents[j].content);
|
||||
auto forward_info = create_message_forward_info(from_dialog_id, to_dialog_id, forwarded_message);
|
||||
auto forward_info =
|
||||
drop_author ? nullptr : create_message_forward_info(from_dialog_id, to_dialog_id, forwarded_message);
|
||||
if (forward_info != nullptr && !forward_info->is_imported && !is_forward_info_sender_hidden(forward_info.get()) &&
|
||||
!forward_info->message_id.is_valid() && !forward_info->sender_dialog_id.is_valid() &&
|
||||
forward_info->sender_user_id.is_valid()) {
|
||||
@ -28069,7 +28110,8 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
&need_update_dialog_pos, j + 1 != forwarded_message_contents.size(),
|
||||
std::move(forward_info));
|
||||
}
|
||||
fix_forwarded_message(m, to_dialog_id, forwarded_message, forwarded_message_contents[j].media_album_id);
|
||||
fix_forwarded_message(m, to_dialog_id, forwarded_message, forwarded_message_contents[j].media_album_id,
|
||||
drop_author);
|
||||
m->in_game_share = in_game_share;
|
||||
m->real_forward_from_dialog_id = from_dialog_id;
|
||||
m->real_forward_from_message_id = message_id;
|
||||
@ -28085,7 +28127,8 @@ Result<td_api::object_ptr<td_api::messages>> MessagesManager::forward_messages(
|
||||
|
||||
if (!forwarded_messages.empty()) {
|
||||
CHECK(!only_preview);
|
||||
do_forward_messages(to_dialog_id, from_dialog_id, forwarded_messages, forwarded_message_ids, 0);
|
||||
do_forward_messages(to_dialog_id, from_dialog_id, forwarded_messages, forwarded_message_ids, drop_author,
|
||||
drop_media_captions, 0);
|
||||
}
|
||||
|
||||
for (auto &copied_message : copied_messages) {
|
||||
@ -38653,7 +38696,8 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||
send_update_chat_last_message(to_dialog, "on_reforward_message");
|
||||
}
|
||||
|
||||
do_forward_messages(to_dialog_id, from_dialog_id, forwarded_messages, log_event.message_ids, event.id_);
|
||||
do_forward_messages(to_dialog_id, from_dialog_id, forwarded_messages, log_event.message_ids,
|
||||
log_event.drop_author, log_event.drop_media_captions, event.id_);
|
||||
break;
|
||||
}
|
||||
case LogEvent::HandlerType::DeleteMessage: {
|
||||
|
@ -1932,7 +1932,8 @@ class MessagesManager final : public Actor {
|
||||
bool update_message_is_pinned(Dialog *d, Message *m, bool is_pin, const char *source);
|
||||
|
||||
void do_forward_messages(DialogId to_dialog_id, DialogId from_dialog_id, const vector<Message *> &messages,
|
||||
const vector<MessageId> &message_ids, uint64 log_event_id);
|
||||
const vector<MessageId> &message_ids, bool drop_author, bool drop_media_captions,
|
||||
uint64 log_event_id);
|
||||
|
||||
Result<td_api::object_ptr<td_api::message>> forward_message(DialogId to_dialog_id, DialogId from_dialog_id,
|
||||
MessageId message_id,
|
||||
@ -1943,8 +1944,8 @@ class MessagesManager final : public Actor {
|
||||
unique_ptr<MessageForwardInfo> create_message_forward_info(DialogId from_dialog_id, DialogId to_dialog_id,
|
||||
const Message *forwarded_message) const;
|
||||
|
||||
void fix_forwarded_message(Message *m, DialogId to_dialog_id, const Message *forwarded_message,
|
||||
int64 media_album_id) const;
|
||||
void fix_forwarded_message(Message *m, DialogId to_dialog_id, const Message *forwarded_message, int64 media_album_id,
|
||||
bool drop_author) const;
|
||||
|
||||
struct ForwardedMessages {
|
||||
struct CopiedMessage {
|
||||
@ -1964,6 +1965,8 @@ class MessagesManager final : public Actor {
|
||||
size_t index;
|
||||
};
|
||||
vector<ForwardedMessageContent> forwarded_message_contents;
|
||||
bool drop_author = false;
|
||||
bool drop_media_captions = false;
|
||||
|
||||
Dialog *from_dialog;
|
||||
Dialog *to_dialog;
|
||||
@ -3249,8 +3252,8 @@ class MessagesManager final : public Actor {
|
||||
static uint64 save_reget_dialog_log_event(DialogId dialog_id);
|
||||
|
||||
static uint64 save_forward_messages_log_event(DialogId to_dialog_id, DialogId from_dialog_id,
|
||||
const vector<Message *> &messages,
|
||||
const vector<MessageId> &message_ids);
|
||||
const vector<Message *> &messages, const vector<MessageId> &message_ids,
|
||||
bool drop_author, bool drop_media_captions);
|
||||
|
||||
static uint64 save_unpin_all_dialog_messages_on_server_log_event(DialogId dialog_id);
|
||||
|
||||
|
@ -50,6 +50,7 @@ enum class Version : int32 {
|
||||
AddInviteLinksRequiringApproval,
|
||||
AddKeyboardButtonFlags, // 35
|
||||
AddAudioFlags,
|
||||
UseServerForwardAsCopy,
|
||||
Next
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user