diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 7bce47daf..906a444ed 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -2009,7 +2009,8 @@ messagePaymentSuccessful invoice_chat_id:int53 invoice_message_id:int53 currency messagePaymentSuccessfulBot currency:string total_amount:int53 is_recurring:Bool is_first_recurring:Bool invoice_payload:bytes shipping_option_id:string order_info:orderInfo telegram_payment_charge_id:string provider_payment_charge_id:string = MessageContent; //@description Telegram Premium was gifted to the user @currency Currency for the paid amount @amount The paid amount, in the smallest units of the currency @month_count Number of month the Telegram Premium subscription will be active -messageGiftedPremium currency:string amount:int53 month_count:int32 = MessageContent; +//@sticker A sticker to be shown in the message; may be null if unknown +messageGiftedPremium currency:string amount:int53 month_count:int32 sticker:sticker = MessageContent; //@description A contact has registered with Telegram messageContactRegistered = MessageContent; @@ -6446,9 +6447,6 @@ getPremiumFeatures source:PremiumSource = PremiumFeatures; //@description Returns examples of premium stickers for demonstration purposes getPremiumStickers = Stickers; -//@description Returns a Premium gift option sticker by its position among Premium options @month_count Number of month the Telegram Premium subscription will be active -getPremiumGiftOptionSticker month_count:int32 = Sticker; - //@description Informs TDLib that the user viewed detailed information about a Premium feature on the Premium features screen @feature The viewed premium feature viewPremiumFeature feature:PremiumFeature = Ok; diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index b04afeecd..fe77b5d72 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -3818,7 +3818,7 @@ void register_message_content(Td *td, const MessageContent *content, FullMessage return td->stickers_manager_->register_dice(dice->emoji, dice->dice_value, full_message_id, source); } case MessageContentType::GiftPremium: - return td->stickers_manager_->register_gift_premium(static_cast(content)->months, + return td->stickers_manager_->register_premium_gift(static_cast(content)->months, full_message_id, source); default: return; @@ -3898,7 +3898,7 @@ void unregister_message_content(Td *td, const MessageContent *content, FullMessa return td->stickers_manager_->unregister_dice(dice->emoji, dice->dice_value, full_message_id, source); } case MessageContentType::GiftPremium: - return td->stickers_manager_->unregister_gift_premium(static_cast(content)->months, + return td->stickers_manager_->unregister_premium_gift(static_cast(content)->months, full_message_id, source); default: return; @@ -5284,7 +5284,8 @@ tl_object_ptr get_message_content_object(const MessageCo } case MessageContentType::GiftPremium: { const auto *m = static_cast(content); - return make_tl_object(m->currency, m->amount, m->months); + return make_tl_object( + m->currency, m->amount, m->months, td->stickers_manager_->get_premium_gift_sticker_object(m->months)); } default: UNREACHABLE(); diff --git a/td/telegram/StickersManager.cpp b/td/telegram/StickersManager.cpp index 2604a009f..c5379b34c 100644 --- a/td/telegram/StickersManager.cpp +++ b/td/telegram/StickersManager.cpp @@ -1371,7 +1371,7 @@ StickersManager::~StickersManager() { short_name_to_sticker_set_id_, attached_sticker_sets_, found_stickers_, found_sticker_sets_, emoji_language_codes_, emoji_language_code_versions_, emoji_language_code_last_difference_times_, reloaded_emoji_keywords_, - gift_premium_messages_, dice_messages_, emoji_messages_); + premium_gift_messages_, dice_messages_, emoji_messages_); } void StickersManager::start_up() { @@ -2217,6 +2217,35 @@ tl_object_ptr StickersManager::get_sticker_set_info_obje std::move(stickers)); } +td_api::object_ptr StickersManager::get_premium_gift_sticker_object(int32 month_count) { + auto it = premium_gift_messages_.find(month_count); + if (it == premium_gift_messages_.end()) { + return get_sticker_object(get_premium_gift_option_sticker_id(month_count)); + } else { + return get_sticker_object(it->second->sticker_id); + } +} + +const StickersManager::StickerSet *StickersManager::get_premium_gift_sticker_set() { + if (td_->auth_manager_->is_bot()) { + return nullptr; + } + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::premium_gifts()); + if (!special_sticker_set.id_.is_valid()) { + load_special_sticker_set(special_sticker_set); + return nullptr; + } + + auto sticker_set = get_sticker_set(special_sticker_set.id_); + CHECK(sticker_set != nullptr); + if (!sticker_set->was_loaded) { + load_special_sticker_set(special_sticker_set); + return nullptr; + } + + return sticker_set; +} + FileId StickersManager::get_premium_gift_option_sticker_id(const StickerSet *sticker_set, int32 month_count) { if (sticker_set == nullptr || sticker_set->sticker_ids.empty() || month_count <= 0) { return {}; @@ -2254,6 +2283,10 @@ FileId StickersManager::get_premium_gift_option_sticker_id(const StickerSet *sti return sticker_set->sticker_ids[0]; } +FileId StickersManager::get_premium_gift_option_sticker_id(int32 month_count) { + return get_premium_gift_option_sticker_id(get_premium_gift_sticker_set(), month_count); +} + const StickersManager::StickerSet *StickersManager::get_animated_emoji_sticker_set() { if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { return nullptr; @@ -3395,6 +3428,9 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s if (set_id == add_special_sticker_set(SpecialStickerSetType::animated_emoji()).id_) { try_update_animated_emoji_messages(); } + if (set_id == add_special_sticker_set(SpecialStickerSetType::premium_gifts()).id_) { + try_update_premium_gift_messages(); + } return set_id; } @@ -3471,6 +3507,8 @@ void StickersManager::on_get_special_sticker_set(const SpecialStickerSetType &ty << ' ' << sticker_set.short_name_); if (type == SpecialStickerSetType::animated_emoji()) { try_update_animated_emoji_messages(); + } else if (type == SpecialStickerSetType::premium_gifts()) { + try_update_premium_gift_messages(); } else if (!type.get_dice_emoji().empty()) { sticker_set.is_being_loaded_ = true; } @@ -4800,47 +4838,57 @@ void StickersManager::try_update_animated_emoji_messages() { } } -void StickersManager::register_gift_premium(int32 months, FullMessageId full_message_id, const char *source) { +void StickersManager::try_update_premium_gift_messages() { + auto sticker_set = get_premium_gift_sticker_set(); + vector full_message_ids; + for (auto &it : premium_gift_messages_) { + auto new_sticker_id = get_premium_gift_option_sticker_id(sticker_set, it.first); + if (new_sticker_id != it.second->sticker_id) { + it.second->sticker_id = new_sticker_id; + for (const auto &full_message_id : it.second->full_message_ids) { + full_message_ids.push_back(full_message_id); + } + } + } + for (const auto &full_message_id : full_message_ids) { + td_->messages_manager_->on_external_update_message_content(full_message_id); + } +} + +void StickersManager::register_premium_gift(int32 months, FullMessageId full_message_id, const char *source) { if (td_->auth_manager_->is_bot() || months == 0) { return; } LOG(INFO) << "Register premium gift for " << months << " months from " << full_message_id << " from " << source; - bool is_inserted = gift_premium_messages_[months].insert(full_message_id).second; + auto &premium_gift_messages_ptr = premium_gift_messages_[months]; + if (premium_gift_messages_ptr == nullptr) { + premium_gift_messages_ptr = make_unique(); + } + auto &premium_gift_messages = *premium_gift_messages_ptr; + + if (premium_gift_messages.full_message_ids.empty()) { + premium_gift_messages.sticker_id = get_premium_gift_option_sticker_id(months); + } + + bool is_inserted = premium_gift_messages.full_message_ids.insert(full_message_id).second; LOG_CHECK(is_inserted) << source << " " << months << " " << full_message_id; - - auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::premium_gifts()); - bool need_load = false; - StickerSet *sticker_set = nullptr; - if (!special_sticker_set.id_.is_valid()) { - need_load = true; - } else { - sticker_set = get_sticker_set(special_sticker_set.id_); - CHECK(sticker_set != nullptr); - need_load = !sticker_set->was_loaded; - } - - if (need_load) { - LOG(INFO) << "Waiting for a premium gifts sticker set needed in " << full_message_id; - load_special_sticker_set(special_sticker_set); - } else { - // TODO reload once in a while - // reload_special_sticker_set(special_sticker_set, sticker_set->is_loaded ? sticker_set->hash : 0); - } } -void StickersManager::unregister_gift_premium(int32 months, FullMessageId full_message_id, const char *source) { +void StickersManager::unregister_premium_gift(int32 months, FullMessageId full_message_id, const char *source) { if (td_->auth_manager_->is_bot() || months == 0) { return; } LOG(INFO) << "Unregister premium gift for " << months << " months from " << full_message_id << " from " << source; - auto &message_ids = gift_premium_messages_[months]; + auto it = premium_gift_messages_.find(months); + CHECK(it != premium_gift_messages_.end()); + auto &message_ids = it->second->full_message_ids; auto is_deleted = message_ids.erase(full_message_id) > 0; LOG_CHECK(is_deleted) << source << " " << months << " " << full_message_id; if (message_ids.empty()) { - gift_premium_messages_.erase(months); + premium_gift_messages_.erase(it); } } diff --git a/td/telegram/StickersManager.h b/td/telegram/StickersManager.h index ada72e7c2..a2387b19d 100644 --- a/td/telegram/StickersManager.h +++ b/td/telegram/StickersManager.h @@ -76,13 +76,15 @@ class StickersManager final : public Actor { const vector &sticker_set_ids, size_t covers_limit) const; + td_api::object_ptr get_premium_gift_sticker_object(int32 month_count); + td_api::object_ptr get_animated_emoji_object(const string &emoji); tl_object_ptr get_input_sticker_set(StickerSetId sticker_set_id) const; - void register_gift_premium(int32 months, FullMessageId full_message_id, const char *source); + void register_premium_gift(int32 months, FullMessageId full_message_id, const char *source); - void unregister_gift_premium(int32 months, FullMessageId full_message_id, const char *source); + void unregister_premium_gift(int32 months, FullMessageId full_message_id, const char *source); void register_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source); @@ -708,7 +710,13 @@ class StickersManager final : public Actor { bool update_sticker_set_cache(const StickerSet *sticker_set, Promise &promise); - static FileId get_premium_gift_option_sticker_id(const StickerSet *sticker_set, int32 position); + const StickerSet *get_premium_gift_sticker_set(); + + static FileId get_premium_gift_option_sticker_id(const StickerSet *sticker_set, int32 month_count); + + FileId get_premium_gift_option_sticker_id(int32 month_count); + + void try_update_premium_gift_messages(); const StickerSet *get_animated_emoji_sticker_set(); @@ -941,7 +949,11 @@ class StickersManager final : public Actor { FlatHashMap>> load_language_codes_queries_; FlatHashMap emoji_suggestions_urls_; - FlatHashMap> gift_premium_messages_; + struct GiftPremiumMessages { + FlatHashSet full_message_ids; + FileId sticker_id; + }; + FlatHashMap> premium_gift_messages_; FlatHashMap> dice_messages_; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index c42435106..620d23c07 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7906,12 +7906,6 @@ void Td::on_request(uint64 id, const td_api::getPremiumStickers &request) { CREATE_REQUEST(SearchStickersRequest, "⭐️⭐️", 100); } -void Td::on_request(uint64 id, const td_api::getPremiumGiftOptionSticker &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_premium_gift_option_sticker(request.month_count_, false, std::move(promise)); -} - void Td::on_request(uint64 id, const td_api::viewPremiumFeature &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index f27b5bec2..0ce717d6f 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -1301,8 +1301,6 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getPremiumStickers &request); - void on_request(uint64 id, const td_api::getPremiumGiftOptionSticker &request); - void on_request(uint64 id, const td_api::viewPremiumFeature &request); void on_request(uint64 id, const td_api::clickPremiumSubscriptionButton &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index ab1c659dd..322525291 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2793,8 +2793,6 @@ class CliClient final : public Actor { send_request(td_api::make_object(args)); } else if (op == "gces") { send_request(td_api::make_object(to_integers(args))); - } else if (op == "gpgos") { - send_request(td_api::make_object(to_integer(args))); } else if (op == "gsan") { send_request(td_api::make_object()); } else if (op == "asan") {