Resolve custom animated emoji stickers.

This commit is contained in:
levlam 2022-08-05 20:49:24 +03:00
parent 3c863517ba
commit cb0daf0bef
3 changed files with 64 additions and 8 deletions

View File

@ -328,10 +328,10 @@ videoNote duration:int32 length:int32 minithumbnail:minithumbnail thumbnail:thum
//@mime_type MIME type of the file; as defined by the sender @speech_recognition_result Result of speech recognition in the voice note; may be null @voice File containing the voice note
voiceNote duration:int32 waveform:bytes mime_type:string speech_recognition_result:SpeechRecognitionResult voice:file = VoiceNote;
//@description Describes an animated representation of an emoji
//@sticker Animated sticker for the emoji; may be null if yet unknown for a custom emoji
//@description Describes an animated or custom representation of an emoji
//@sticker Sticker for the emoji; may be null if yet unknown for a custom emoji. If the sticker is a custom emoji, it can have arbitrary format different from stickerFormatTgs
//@fitzpatrick_type Emoji modifier fitzpatrick type; 0-6; 0 if none
//@sound File containing the sound to be played when the animated emoji is clicked; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container
//@sound File containing the sound to be played when the sticker is clicked; may be null. The sound is encoded with the Opus codec, and stored inside an OGG container
animatedEmoji sticker:sticker fitzpatrick_type:int32 sound:file = AnimatedEmoji;
//@description Describes a user contact @phone_number Phone number of the user @first_name First name of the user; 1-255 characters in length @last_name Last name of the user @vcard Additional data about the user in a form of vCard; 0-2048 bytes in length @user_id Identifier of the user, if known; otherwise 0

View File

@ -1372,7 +1372,7 @@ StickersManager::~StickersManager() {
G()->get_gc_scheduler_id(), stickers_, sticker_sets_, 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_, premium_gift_messages_, dice_messages_,
emoji_messages_, custom_emoji_to_sticker_id_);
emoji_messages_, custom_emoji_messages_, custom_emoji_to_sticker_id_);
}
void StickersManager::start_up() {
@ -1995,7 +1995,7 @@ tl_object_ptr<td_api::sticker> StickersManager::get_sticker_object(FileId file_i
if ((is_sticker_format_vector(sticker->format) || sticker->type == StickerType::CustomEmoji) &&
(for_animated_emoji || for_clicked_animated_emoji)) {
zoom = for_clicked_animated_emoji ? 3 * animated_emoji_zoom_ : animated_emoji_zoom_;
if (sticker->type == StickerType::CustomEmoji) {
if (sticker->type == StickerType::CustomEmoji && max(width, height) <= 100) {
zoom *= 5.12;
}
width = static_cast<int32>(width * zoom + 0.5);
@ -2385,7 +2385,9 @@ FileId StickersManager::get_animated_emoji_sound_file_id(const string &emoji) co
td_api::object_ptr<td_api::animatedEmoji> StickersManager::get_animated_emoji_object(const string &emoji,
int64 custom_emoji_id) {
if (custom_emoji_id != 0) {
auto sticker_id = custom_emoji_to_sticker_id_.get(custom_emoji_id);
auto it = custom_emoji_messages_.find(custom_emoji_id);
auto sticker_id =
it == custom_emoji_messages_.end() ? custom_emoji_to_sticker_id_.get(custom_emoji_id) : it->second->sticker_id;
return td_api::make_object<td_api::animatedEmoji>(get_sticker_object(sticker_id, true), 0, nullptr);
}
@ -2449,6 +2451,7 @@ string StickersManager::get_custom_emoji_database_key(int64 custom_emoji_id) {
FileId StickersManager::on_get_sticker(unique_ptr<Sticker> new_sticker, bool replace) {
auto file_id = new_sticker->file_id;
CHECK(file_id.is_valid());
int64 updated_custom_emoji_id = 0;
auto *s = get_sticker(file_id);
if (s == nullptr) {
s = new_sticker.get();
@ -2460,6 +2463,7 @@ FileId StickersManager::on_get_sticker(unique_ptr<Sticker> new_sticker, bool rep
auto custom_emoji_id = get_custom_emoji_id(file_id);
if (custom_emoji_id != 0 && custom_emoji_to_sticker_id_.get(custom_emoji_id) == file_id) {
custom_emoji_to_sticker_id_.erase(custom_emoji_id);
updated_custom_emoji_id = custom_emoji_id;
}
}
@ -2528,7 +2532,9 @@ FileId StickersManager::on_get_sticker(unique_ptr<Sticker> new_sticker, bool rep
s->is_being_reloaded = false;
auto custom_emoji_id = get_custom_emoji_id(file_id);
if (custom_emoji_id != 0) {
custom_emoji_to_sticker_id_[custom_emoji_id] = file_id;
custom_emoji_to_sticker_id_.set(custom_emoji_id, file_id);
CHECK(updated_custom_emoji_id == custom_emoji_id || updated_custom_emoji_id == 0);
updated_custom_emoji_id = custom_emoji_id;
if (!s->is_from_database && G()->parameters().use_file_db && !G()->close_flag()) {
LOG(INFO) << "Save custom emoji " << custom_emoji_id << " to database";
s->is_from_database = true;
@ -2539,6 +2545,9 @@ FileId StickersManager::on_get_sticker(unique_ptr<Sticker> new_sticker, bool rep
}
}
}
if (updated_custom_emoji_id != 0) {
try_update_custom_emoji_messages(updated_custom_emoji_id);
}
return file_id;
}
@ -4937,6 +4946,25 @@ void StickersManager::try_update_animated_emoji_messages() {
}
}
void StickersManager::try_update_custom_emoji_messages(int64 custom_emoji_id) {
auto it = custom_emoji_messages_.find(custom_emoji_id);
if (it == custom_emoji_messages_.end()) {
return;
}
vector<FullMessageId> full_message_ids;
auto new_sticker_id = custom_emoji_to_sticker_id_.get(custom_emoji_id);
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::try_update_premium_gift_messages() {
auto sticker_set = get_premium_gift_sticker_set();
vector<FullMessageId> full_message_ids;
@ -5059,6 +5087,17 @@ void StickersManager::register_emoji(const string &emoji, int64 custom_emoji_id,
LOG(INFO) << "Register emoji " << emoji << " with custom emoji " << custom_emoji_id << " from " << full_message_id
<< " from " << source;
if (custom_emoji_id != 0) {
auto &emoji_messages_ptr = custom_emoji_messages_[custom_emoji_id];
if (emoji_messages_ptr == nullptr) {
emoji_messages_ptr = make_unique<CustomEmojiMessages>();
}
auto &emoji_messages = *emoji_messages_ptr;
if (emoji_messages.full_message_ids.empty()) {
emoji_messages.sticker_id = custom_emoji_to_sticker_id_.get(custom_emoji_id);
get_custom_emoji_stickers({custom_emoji_id}, true, Promise<td_api::object_ptr<td_api::stickers>>());
}
bool is_inserted = emoji_messages.full_message_ids.insert(full_message_id).second;
LOG_CHECK(is_inserted) << source << ' ' << custom_emoji_id << ' ' << full_message_id;
return;
}
@ -5085,6 +5124,15 @@ void StickersManager::unregister_emoji(const string &emoji, int64 custom_emoji_i
LOG(INFO) << "Unregister emoji " << emoji << " with custom emoji " << custom_emoji_id << " from " << full_message_id
<< " from " << source;
if (custom_emoji_id != 0) {
auto it = custom_emoji_messages_.find(custom_emoji_id);
CHECK(it != custom_emoji_messages_.end());
auto &full_message_ids = it->second->full_message_ids;
auto is_deleted = full_message_ids.erase(full_message_id) > 0;
LOG_CHECK(is_deleted) << source << ' ' << custom_emoji_id << ' ' << full_message_id;
if (full_message_ids.empty()) {
custom_emoji_messages_.erase(it);
}
return;
}
@ -5242,7 +5290,7 @@ void StickersManager::get_custom_emoji_stickers(vector<int64> &&document_ids, bo
vector<int64> unknown_document_ids;
for (auto document_id : document_ids) {
if (custom_emoji_to_sticker_id_.get(document_id).is_valid()) {
if (custom_emoji_to_sticker_id_.count(document_id) == 0) {
unknown_document_ids.push_back(document_id);
}
}

View File

@ -748,6 +748,8 @@ class StickersManager final : public Actor {
void try_update_animated_emoji_messages();
void try_update_custom_emoji_messages(int64 custom_emoji_id);
static int get_emoji_number(Slice emoji);
vector<FileId> get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const;
@ -986,6 +988,12 @@ class StickersManager final : public Actor {
};
FlatHashMap<string, unique_ptr<EmojiMessages>> emoji_messages_;
struct CustomEmojiMessages {
FlatHashSet<FullMessageId, FullMessageIdHash> full_message_ids;
FileId sticker_id;
};
FlatHashMap<int64, unique_ptr<CustomEmojiMessages>> custom_emoji_messages_;
string dice_emojis_str_;
vector<string> dice_emojis_;