Support file reference repair for media from star transactions.

This commit is contained in:
levlam 2024-06-28 14:05:25 +03:00
parent 02bd5a2498
commit fc7cf76a5f
5 changed files with 119 additions and 50 deletions

View File

@ -17,6 +17,7 @@
#include "td/telegram/MessagesManager.h"
#include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/QuickReplyManager.h"
#include "td/telegram/StarManager.h"
#include "td/telegram/StickerSetId.h"
#include "td/telegram/StickersManager.h"
#include "td/telegram/StoryManager.h"
@ -64,25 +65,26 @@ size_t FileReferenceManager::get_file_reference_error_pos(const Status &error) {
}
/*
fileSourceMessage chat_id:int53 message_id:int53 = FileSource; // repaired with get_message_from_server
fileSourceUserProfilePhoto user_id:int53 photo_id:int64 = FileSource; // repaired with photos.getUserPhotos
fileSourceBasicGroupPhoto basic_group_id:int53 = FileSource; // no need to repair
fileSourceSupergroupPhoto supergroup_id:int53 = FileSource; // no need to repair
fileSourceWebPage url:string = FileSource; // repaired with messages.getWebPage
fileSourceWallpapers = FileSource; // can't be repaired
fileSourceSavedAnimations = FileSource; // repaired with messages.getSavedGifs
fileSourceRecentStickers is_attached:Bool = FileSource; // repaired with messages.getRecentStickers, not reliable
fileSourceFavoriteStickers = FileSource; // repaired with messages.getFavedStickers, not reliable
fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repaired with account.getWallPaper
fileSourceBasicGroupFull basic_group_id:int53 = FileSource; // repaired with messages.getFullChat
fileSourceSupergroupFull supergroup_id:int53 = FileSource; // repaired with messages.getFullChannel
fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable
fileSourceSavedRingtones = FileSource; // repaired with account.getSavedRingtones
fileSourceUserFull = FileSource; // repaired with users.getFullUser
fileSourceAttachmentMenuBot user_id:int53 = FileSource; // repaired with messages.getAttachMenuBot
fileSourceWebApp user_id:int53 short_name:string = FileSource; // repaired with messages.getAttachMenuBot
fileSourceStory chat_id:int53 story_id:int32 = FileSource; // repaired with stories.getStoriesByID
fileSourceQuickReplyMessage shortcut_id:int32 message_id:int53 = FileSource; // repaired with messages.getQuickReplyMessages
fileSourceMessage chat_id:int53 message_id:int53 = FileSource; // get_message_from_server
fileSourceUserProfilePhoto user_id:int53 photo_id:int64 = FileSource; // photos.getUserPhotos
fileSourceBasicGroupPhoto basic_group_id:int53 = FileSource; // no need to repair
fileSourceSupergroupPhoto supergroup_id:int53 = FileSource; // no need to repair
fileSourceWebPage url:string = FileSource; // messages.getWebPage
fileSourceWallpapers = FileSource; // can't be repaired
fileSourceSavedAnimations = FileSource; // messages.getSavedGifs
fileSourceRecentStickers is_attached:Bool = FileSource; // messages.getRecentStickers, not reliable
fileSourceFavoriteStickers = FileSource; // messages.getFavedStickers, not reliable
fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // account.getWallPaper
fileSourceBasicGroupFull basic_group_id:int53 = FileSource; // messages.getFullChat
fileSourceSupergroupFull supergroup_id:int53 = FileSource; // messages.getFullChannel
fileSourceAppConfig = FileSource; // help.getAppConfig, not reliable
fileSourceSavedRingtones = FileSource; // account.getSavedRingtones
fileSourceUserFull = FileSource; // users.getFullUser
fileSourceAttachmentMenuBot user_id:int53 = FileSource; // messages.getAttachMenuBot
fileSourceWebApp user_id:int53 short_name:string = FileSource; // messages.getAttachMenuBot
fileSourceStory chat_id:int53 story_id:int32 = FileSource; // stories.getStoriesByID
fileSourceQuickReplyMessage shortcut_id:int32 message_id:int53 = FileSource; // messages.getQuickReplyMessages
fileSourceStarTransaction chat_id:int53 transaction_id:string is_refund:Bool = FileSource; // payments.getStarsTransactionsByID
*/
FileSourceId FileReferenceManager::get_current_file_source_id() const {
@ -177,6 +179,12 @@ FileSourceId FileReferenceManager::create_quick_reply_message_file_source(QuickR
return add_file_source_id(source, PSLICE() << "quick reply " << message_full_id);
}
FileSourceId FileReferenceManager::create_star_transaction_file_source(DialogId dialog_id, const string &transaction_id,
bool is_refund) {
FileSourceStarTransaction source{dialog_id, transaction_id, is_refund};
return add_file_source_id(source, PSLICE() << "star transaction " << transaction_id << " in " << dialog_id);
}
FileReferenceManager::Node &FileReferenceManager::add_node(NodeId node_id) {
CHECK(node_id.is_valid());
auto &node = nodes_[node_id];
@ -396,6 +404,10 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source
send_closure_later(G()->quick_reply_manager(), &QuickReplyManager::reload_quick_reply_message,
source.message_full_id.get_quick_reply_shortcut_id(),
source.message_full_id.get_message_id(), std::move(promise));
},
[&](const FileSourceStarTransaction &source) {
send_closure_later(G()->star_manager(), &StarManager::reload_star_transaction, source.dialog_id,
source.transaction_id, source.is_refund, std::move(promise));
}));
}

View File

@ -68,6 +68,7 @@ class FileReferenceManager final : public Actor {
FileSourceId create_web_app_file_source(UserId user_id, const string &short_name);
FileSourceId create_story_file_source(StoryFullId story_full_id);
FileSourceId create_quick_reply_message_file_source(QuickReplyMessageFullId message_full_id);
FileSourceId create_star_transaction_file_source(DialogId dialog_id, const string &transaction_id, bool is_refund);
using NodeId = FileId;
void repair_file_reference(NodeId node_id, Promise<> promise);
@ -179,6 +180,11 @@ class FileReferenceManager final : public Actor {
struct FileSourceQuickReplyMessage {
QuickReplyMessageFullId message_full_id;
};
struct FileSourceStarTransaction {
DialogId dialog_id;
string transaction_id;
bool is_refund;
};
// append only
using FileSource =
@ -186,7 +192,7 @@ class FileReferenceManager final : public Actor {
FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers,
FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig,
FileSourceSavedRingtones, FileSourceUserFull, FileSourceAttachMenuBot, FileSourceWebApp, FileSourceStory,
FileSourceQuickReplyMessage>;
FileSourceQuickReplyMessage, FileSourceStarTransaction>;
WaitFreeVector<FileSource> file_sources_;
int64 query_generation_{0};

View File

@ -19,6 +19,7 @@
#include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/QuickReplyManager.h"
#include "td/telegram/QuickReplyMessageFullId.h"
#include "td/telegram/StarManager.h"
#include "td/telegram/StickersManager.h"
#include "td/telegram/StoryFullId.h"
#include "td/telegram/StoryManager.h"
@ -39,34 +40,38 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer
CHECK(index < file_sources_.size());
auto &source = file_sources_[index];
td::store(source.get_offset(), storer);
source.visit(
overloaded([&](const FileSourceMessage &source) { td::store(source.message_full_id, storer); },
[&](const FileSourceUserPhoto &source) {
td::store(source.user_id, storer);
td::store(source.photo_id, storer);
},
[&](const FileSourceChatPhoto &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelPhoto &source) { td::store(source.channel_id, storer); },
[&](const FileSourceWallpapers &source) {},
[&](const FileSourceWebPage &source) { td::store(source.url, storer); },
[&](const FileSourceSavedAnimations &source) {},
[&](const FileSourceRecentStickers &source) { td::store(source.is_attached, storer); },
[&](const FileSourceFavoriteStickers &source) {},
[&](const FileSourceBackground &source) {
td::store(source.background_id, storer);
td::store(source.access_hash, storer);
},
[&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); },
[&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {},
[&](const FileSourceUserFull &source) { td::store(source.user_id, storer); },
[&](const FileSourceAttachMenuBot &source) { td::store(source.user_id, storer); },
[&](const FileSourceWebApp &source) {
td::store(source.user_id, storer);
td::store(source.short_name, storer);
},
[&](const FileSourceStory &source) { td::store(source.story_full_id, storer); },
[&](const FileSourceQuickReplyMessage &source) { td::store(source.message_full_id, storer); }));
source.visit(overloaded([&](const FileSourceMessage &source) { td::store(source.message_full_id, storer); },
[&](const FileSourceUserPhoto &source) {
td::store(source.user_id, storer);
td::store(source.photo_id, storer);
},
[&](const FileSourceChatPhoto &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelPhoto &source) { td::store(source.channel_id, storer); },
[&](const FileSourceWallpapers &source) {},
[&](const FileSourceWebPage &source) { td::store(source.url, storer); },
[&](const FileSourceSavedAnimations &source) {},
[&](const FileSourceRecentStickers &source) { td::store(source.is_attached, storer); },
[&](const FileSourceFavoriteStickers &source) {},
[&](const FileSourceBackground &source) {
td::store(source.background_id, storer);
td::store(source.access_hash, storer);
},
[&](const FileSourceChatFull &source) { td::store(source.chat_id, storer); },
[&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); },
[&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {},
[&](const FileSourceUserFull &source) { td::store(source.user_id, storer); },
[&](const FileSourceAttachMenuBot &source) { td::store(source.user_id, storer); },
[&](const FileSourceWebApp &source) {
td::store(source.user_id, storer);
td::store(source.short_name, storer);
},
[&](const FileSourceStory &source) { td::store(source.story_full_id, storer); },
[&](const FileSourceQuickReplyMessage &source) { td::store(source.message_full_id, storer); },
[&](const FileSourceStarTransaction &source) {
td::store(source.dialog_id, storer);
td::store(source.transaction_id, storer);
td::store(source.is_refund, storer);
}));
}
template <class ParserT>
@ -159,6 +164,15 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) {
td::parse(message_full_id, parser);
return td->quick_reply_manager_->get_quick_reply_message_file_source_id(message_full_id);
}
case 19: {
DialogId dialog_id;
string transaction_id;
bool is_refund;
td::parse(dialog_id, parser);
td::parse(transaction_id, parser);
td::parse(is_refund, parser);
return td->star_manager_->get_star_transaction_file_source_id(dialog_id, transaction_id, is_refund);
}
default:
parser.set_error("Invalid type in FileSource");
return FileSourceId();

View File

@ -11,6 +11,8 @@
#include "td/telegram/ChatManager.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/DialogManager.h"
#include "td/telegram/FileReferenceManager.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/InputInvoice.h"
#include "td/telegram/MessageExtendedMedia.h"
@ -135,10 +137,12 @@ class GetStarsTransactionsQuery final : public Td::ResultHandler {
vector<td_api::object_ptr<td_api::starTransaction>> transactions;
for (auto &transaction : result->history_) {
vector<FileId> file_ids;
td_api::object_ptr<td_api::productInfo> product_info;
string bot_payload;
if (!transaction->title_.empty() || !transaction->description_.empty() || transaction->photo_ != nullptr) {
auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(transaction->photo_), DialogId());
append(file_ids, photo_get_file_ids(photo));
product_info = get_product_info_object(td_, transaction->title_, transaction->description_, photo);
}
if (!transaction->bot_payload_.empty()) {
@ -216,11 +220,17 @@ class GetStarsTransactionsQuery final : public Td::ResultHandler {
}
auto extended_media =
transform(std::move(transaction->extended_media_), [td = td_, dialog_id](auto &&media) {
return MessageExtendedMedia(td, std::move(media), dialog_id).get_message_extended_media_object(td);
return MessageExtendedMedia(td, std::move(media), dialog_id);
});
for (auto &media : extended_media) {
media.append_file_ids(td_, file_ids);
}
auto extended_media_objects = transform(std::move(extended_media), [td = td_, dialog_id](auto &&media) {
return media.get_message_extended_media_object(td);
});
return td_api::make_object<td_api::starTransactionPartnerChannel>(
td_->dialog_manager_->get_chat_id_object(dialog_id, "starTransactionPartnerChannel"),
message_id.get(), std::move(extended_media));
message_id.get(), std::move(extended_media_objects));
}
LOG(ERROR) << "Receive star transaction with " << dialog_id;
return td_api::make_object<td_api::starTransactionPartnerUnsupported>();
@ -249,6 +259,13 @@ class GetStarsTransactionsQuery final : public Td::ResultHandler {
LOG(ERROR) << "Receive message identifier with " << to_string(star_transaction);
}
}
if (!file_ids.empty()) {
auto file_source_id =
td_->star_manager_->get_star_transaction_file_source_id(dialog_id_, transaction->id_, transaction->refund_);
for (auto file_id : file_ids) {
td_->file_manager_->add_file_source(file_id, file_source_id);
}
}
transactions.push_back(std::move(star_transaction));
}
@ -546,6 +563,21 @@ void StarManager::on_update_stars_revenue_status(
convert_stars_revenue_status(std::move(update->status_))));
}
FileSourceId StarManager::get_star_transaction_file_source_id(DialogId dialog_id, const string &transaction_id,
bool is_refund) {
if (!dialog_id.is_valid() || transaction_id.empty()) {
return FileSourceId();
}
auto &source_id = star_transaction_file_source_ids_[is_refund][dialog_id][transaction_id];
if (!source_id.is_valid()) {
source_id = td_->file_reference_manager_->create_star_transaction_file_source(dialog_id, transaction_id, is_refund);
}
VLOG(file_references) << "Return " << source_id << " for " << (is_refund ? "refund " : "") << "transaction "
<< transaction_id << " in " << dialog_id;
return source_id;
}
int64 StarManager::get_star_count(int64 amount, bool allow_negative) {
auto max_amount = static_cast<int64>(1) << 51;
if (amount < 0) {

View File

@ -7,6 +7,7 @@
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
@ -46,6 +47,8 @@ class StarManager final : public Actor {
void on_update_stars_revenue_status(telegram_api::object_ptr<telegram_api::updateStarsRevenueStatus> &&update);
FileSourceId get_star_transaction_file_source_id(DialogId dialog_id, const string &transaction_id, bool is_refund);
static int64 get_star_count(int64 amount, bool allow_negative = false);
private:
@ -59,6 +62,8 @@ class StarManager final : public Actor {
Td *td_;
ActorShared<> parent_;
FlatHashMap<DialogId, FlatHashMap<string, FileSourceId>, DialogIdHash> star_transaction_file_source_ids_[2];
};
} // namespace td