diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index 8faaaaeb7..87ec50dc4 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -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)); })); } diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index 4c26f0eae..c1f5b7113 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -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 file_sources_; int64 query_generation_{0}; diff --git a/td/telegram/FileReferenceManager.hpp b/td/telegram/FileReferenceManager.hpp index 2cfa47fb9..34a02cec4 100644 --- a/td/telegram/FileReferenceManager.hpp +++ b/td/telegram/FileReferenceManager.hpp @@ -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 @@ -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(); diff --git a/td/telegram/StarManager.cpp b/td/telegram/StarManager.cpp index 0ffbebd00..c46b2862d 100644 --- a/td/telegram/StarManager.cpp +++ b/td/telegram/StarManager.cpp @@ -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> transactions; for (auto &transaction : result->history_) { + vector file_ids; td_api::object_ptr 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_->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(); @@ -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(1) << 51; if (amount < 0) { diff --git a/td/telegram/StarManager.h b/td/telegram/StarManager.h index 4b7a4f0c6..b15ddb978 100644 --- a/td/telegram/StarManager.h +++ b/td/telegram/StarManager.h @@ -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 &&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, DialogIdHash> star_transaction_file_source_ids_[2]; }; } // namespace td