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/MessagesManager.h"
#include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/QuickReplyManager.h" #include "td/telegram/QuickReplyManager.h"
#include "td/telegram/StarManager.h"
#include "td/telegram/StickerSetId.h" #include "td/telegram/StickerSetId.h"
#include "td/telegram/StickersManager.h" #include "td/telegram/StickersManager.h"
#include "td/telegram/StoryManager.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 fileSourceMessage chat_id:int53 message_id:int53 = FileSource; // get_message_from_server
fileSourceUserProfilePhoto user_id:int53 photo_id:int64 = FileSource; // repaired with photos.getUserPhotos fileSourceUserProfilePhoto user_id:int53 photo_id:int64 = FileSource; // photos.getUserPhotos
fileSourceBasicGroupPhoto basic_group_id:int53 = FileSource; // no need to repair fileSourceBasicGroupPhoto basic_group_id:int53 = FileSource; // no need to repair
fileSourceSupergroupPhoto supergroup_id:int53 = FileSource; // no need to repair fileSourceSupergroupPhoto supergroup_id:int53 = FileSource; // no need to repair
fileSourceWebPage url:string = FileSource; // repaired with messages.getWebPage fileSourceWebPage url:string = FileSource; // messages.getWebPage
fileSourceWallpapers = FileSource; // can't be repaired fileSourceWallpapers = FileSource; // can't be repaired
fileSourceSavedAnimations = FileSource; // repaired with messages.getSavedGifs fileSourceSavedAnimations = FileSource; // messages.getSavedGifs
fileSourceRecentStickers is_attached:Bool = FileSource; // repaired with messages.getRecentStickers, not reliable fileSourceRecentStickers is_attached:Bool = FileSource; // messages.getRecentStickers, not reliable
fileSourceFavoriteStickers = FileSource; // repaired with messages.getFavedStickers, not reliable fileSourceFavoriteStickers = FileSource; // messages.getFavedStickers, not reliable
fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repaired with account.getWallPaper fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // account.getWallPaper
fileSourceBasicGroupFull basic_group_id:int53 = FileSource; // repaired with messages.getFullChat fileSourceBasicGroupFull basic_group_id:int53 = FileSource; // messages.getFullChat
fileSourceSupergroupFull supergroup_id:int53 = FileSource; // repaired with messages.getFullChannel fileSourceSupergroupFull supergroup_id:int53 = FileSource; // messages.getFullChannel
fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable fileSourceAppConfig = FileSource; // help.getAppConfig, not reliable
fileSourceSavedRingtones = FileSource; // repaired with account.getSavedRingtones fileSourceSavedRingtones = FileSource; // account.getSavedRingtones
fileSourceUserFull = FileSource; // repaired with users.getFullUser fileSourceUserFull = FileSource; // users.getFullUser
fileSourceAttachmentMenuBot user_id:int53 = FileSource; // repaired with messages.getAttachMenuBot fileSourceAttachmentMenuBot user_id:int53 = FileSource; // messages.getAttachMenuBot
fileSourceWebApp user_id:int53 short_name:string = FileSource; // repaired with messages.getAttachMenuBot fileSourceWebApp user_id:int53 short_name:string = FileSource; // messages.getAttachMenuBot
fileSourceStory chat_id:int53 story_id:int32 = FileSource; // repaired with stories.getStoriesByID fileSourceStory chat_id:int53 story_id:int32 = FileSource; // stories.getStoriesByID
fileSourceQuickReplyMessage shortcut_id:int32 message_id:int53 = FileSource; // repaired with messages.getQuickReplyMessages 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 { 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); 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) { FileReferenceManager::Node &FileReferenceManager::add_node(NodeId node_id) {
CHECK(node_id.is_valid()); CHECK(node_id.is_valid());
auto &node = nodes_[node_id]; 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, 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_quick_reply_shortcut_id(),
source.message_full_id.get_message_id(), std::move(promise)); 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_web_app_file_source(UserId user_id, const string &short_name);
FileSourceId create_story_file_source(StoryFullId story_full_id); FileSourceId create_story_file_source(StoryFullId story_full_id);
FileSourceId create_quick_reply_message_file_source(QuickReplyMessageFullId message_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; using NodeId = FileId;
void repair_file_reference(NodeId node_id, Promise<> promise); void repair_file_reference(NodeId node_id, Promise<> promise);
@ -179,6 +180,11 @@ class FileReferenceManager final : public Actor {
struct FileSourceQuickReplyMessage { struct FileSourceQuickReplyMessage {
QuickReplyMessageFullId message_full_id; QuickReplyMessageFullId message_full_id;
}; };
struct FileSourceStarTransaction {
DialogId dialog_id;
string transaction_id;
bool is_refund;
};
// append only // append only
using FileSource = using FileSource =
@ -186,7 +192,7 @@ class FileReferenceManager final : public Actor {
FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers, FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers,
FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig, FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig,
FileSourceSavedRingtones, FileSourceUserFull, FileSourceAttachMenuBot, FileSourceWebApp, FileSourceStory, FileSourceSavedRingtones, FileSourceUserFull, FileSourceAttachMenuBot, FileSourceWebApp, FileSourceStory,
FileSourceQuickReplyMessage>; FileSourceQuickReplyMessage, FileSourceStarTransaction>;
WaitFreeVector<FileSource> file_sources_; WaitFreeVector<FileSource> file_sources_;
int64 query_generation_{0}; int64 query_generation_{0};

View File

@ -19,6 +19,7 @@
#include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationSettingsManager.h"
#include "td/telegram/QuickReplyManager.h" #include "td/telegram/QuickReplyManager.h"
#include "td/telegram/QuickReplyMessageFullId.h" #include "td/telegram/QuickReplyMessageFullId.h"
#include "td/telegram/StarManager.h"
#include "td/telegram/StickersManager.h" #include "td/telegram/StickersManager.h"
#include "td/telegram/StoryFullId.h" #include "td/telegram/StoryFullId.h"
#include "td/telegram/StoryManager.h" #include "td/telegram/StoryManager.h"
@ -39,8 +40,7 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer
CHECK(index < file_sources_.size()); CHECK(index < file_sources_.size());
auto &source = file_sources_[index]; auto &source = file_sources_[index];
td::store(source.get_offset(), storer); td::store(source.get_offset(), storer);
source.visit( source.visit(overloaded([&](const FileSourceMessage &source) { td::store(source.message_full_id, storer); },
overloaded([&](const FileSourceMessage &source) { td::store(source.message_full_id, storer); },
[&](const FileSourceUserPhoto &source) { [&](const FileSourceUserPhoto &source) {
td::store(source.user_id, storer); td::store(source.user_id, storer);
td::store(source.photo_id, storer); td::store(source.photo_id, storer);
@ -66,7 +66,12 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer
td::store(source.short_name, storer); td::store(source.short_name, storer);
}, },
[&](const FileSourceStory &source) { td::store(source.story_full_id, storer); }, [&](const FileSourceStory &source) { td::store(source.story_full_id, storer); },
[&](const FileSourceQuickReplyMessage &source) { td::store(source.message_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> template <class ParserT>
@ -159,6 +164,15 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) {
td::parse(message_full_id, parser); td::parse(message_full_id, parser);
return td->quick_reply_manager_->get_quick_reply_message_file_source_id(message_full_id); 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: default:
parser.set_error("Invalid type in FileSource"); parser.set_error("Invalid type in FileSource");
return FileSourceId(); return FileSourceId();

View File

@ -11,6 +11,8 @@
#include "td/telegram/ChatManager.h" #include "td/telegram/ChatManager.h"
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/DialogManager.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/Global.h"
#include "td/telegram/InputInvoice.h" #include "td/telegram/InputInvoice.h"
#include "td/telegram/MessageExtendedMedia.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; vector<td_api::object_ptr<td_api::starTransaction>> transactions;
for (auto &transaction : result->history_) { for (auto &transaction : result->history_) {
vector<FileId> file_ids;
td_api::object_ptr<td_api::productInfo> product_info; td_api::object_ptr<td_api::productInfo> product_info;
string bot_payload; string bot_payload;
if (!transaction->title_.empty() || !transaction->description_.empty() || transaction->photo_ != nullptr) { 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()); 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); product_info = get_product_info_object(td_, transaction->title_, transaction->description_, photo);
} }
if (!transaction->bot_payload_.empty()) { if (!transaction->bot_payload_.empty()) {
@ -216,11 +220,17 @@ class GetStarsTransactionsQuery final : public Td::ResultHandler {
} }
auto extended_media = auto extended_media =
transform(std::move(transaction->extended_media_), [td = td_, dialog_id](auto &&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>( return td_api::make_object<td_api::starTransactionPartnerChannel>(
td_->dialog_manager_->get_chat_id_object(dialog_id, "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; LOG(ERROR) << "Receive star transaction with " << dialog_id;
return td_api::make_object<td_api::starTransactionPartnerUnsupported>(); 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); 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)); 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_)))); 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) { int64 StarManager::get_star_count(int64 amount, bool allow_negative) {
auto max_amount = static_cast<int64>(1) << 51; auto max_amount = static_cast<int64>(1) << 51;
if (amount < 0) { if (amount < 0) {

View File

@ -7,6 +7,7 @@
#pragma once #pragma once
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.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); 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); static int64 get_star_count(int64 amount, bool allow_negative = false);
private: private:
@ -59,6 +62,8 @@ class StarManager final : public Actor {
Td *td_; Td *td_;
ActorShared<> parent_; ActorShared<> parent_;
FlatHashMap<DialogId, FlatHashMap<string, FileSourceId>, DialogIdHash> star_transaction_file_source_ids_[2];
}; };
} // namespace td } // namespace td