Remove all emoji modifiers, including modifiers in the middle.

This commit is contained in:
levlam 2022-05-12 18:02:27 +03:00
parent f1f6e61cd1
commit de5f047dba
8 changed files with 45 additions and 36 deletions

View File

@ -667,7 +667,7 @@ class MessageDice final : public MessageContent {
MessageDice() = default;
MessageDice(const string &emoji, int32 dice_value)
: emoji(emoji.empty() ? string(DEFAULT_EMOJI) : remove_emoji_modifiers(emoji).str()), dice_value(dice_value) {
: emoji(emoji.empty() ? string(DEFAULT_EMOJI) : remove_emoji_modifiers(emoji)), dice_value(dice_value) {
}
MessageContentType get_type() const final {
@ -5502,17 +5502,17 @@ void get_message_content_animated_emoji_click_sticker(const MessageContent *cont
}
void on_message_content_animated_emoji_clicked(const MessageContent *content, FullMessageId full_message_id, Td *td,
Slice emoji, string data) {
string &&emoji, string &&data) {
if (content->get_type() != MessageContentType::Text) {
return;
}
emoji = remove_emoji_modifiers(emoji);
remove_emoji_modifiers_in_place(emoji);
auto &text = static_cast<const MessageText *>(content)->text;
if (!text.entities.empty() || remove_emoji_modifiers(text.text) != emoji) {
return;
}
auto error = td->stickers_manager_->on_animated_emoji_message_clicked(emoji, full_message_id, data);
auto error = td->stickers_manager_->on_animated_emoji_message_clicked(std::move(emoji), full_message_id, data);
if (error.is_error()) {
LOG(WARNING) << "Failed to process animated emoji click with data \"" << data << "\": " << error;
}

View File

@ -232,7 +232,7 @@ void get_message_content_animated_emoji_click_sticker(const MessageContent *cont
Td *td, Promise<td_api::object_ptr<td_api::sticker>> &&promise);
void on_message_content_animated_emoji_clicked(const MessageContent *content, FullMessageId full_message_id, Td *td,
Slice emoji, string data);
string &&emoji, string &&data);
bool need_reget_message_content(const MessageContent *content);

View File

@ -7369,8 +7369,8 @@ void MessagesManager::on_dialog_action(DialogId dialog_id, MessageId top_thread_
FullMessageId full_message_id{dialog_id, MessageId(ServerMessageId(clicking_info.message_id))};
auto *m = get_message_force(full_message_id, "on_dialog_action");
if (m != nullptr) {
on_message_content_animated_emoji_clicked(m->content.get(), full_message_id, td_, clicking_info.emoji,
std::move(clicking_info.data));
on_message_content_animated_emoji_clicked(m->content.get(), full_message_id, td_,
std::move(clicking_info.emoji), std::move(clicking_info.data));
}
}
return;

View File

@ -1538,8 +1538,9 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t
auto pending_get_requests = std::move(pending_get_animated_emoji_click_stickers_);
reset_to_empty(pending_get_animated_emoji_click_stickers_);
for (auto &pending_request : pending_get_requests) {
choose_animated_emoji_click_sticker(sticker_set, pending_request.message_text_, pending_request.full_message_id_,
pending_request.start_time_, std::move(pending_request.promise_));
choose_animated_emoji_click_sticker(sticker_set, std::move(pending_request.message_text_),
pending_request.full_message_id_, pending_request.start_time_,
std::move(pending_request.promise_));
}
auto pending_click_requests = std::move(pending_on_animated_emoji_message_clicked_);
reset_to_empty(pending_on_animated_emoji_message_clicked_);
@ -2083,7 +2084,7 @@ std::pair<FileId, int> StickersManager::get_animated_emoji_sticker(const Sticker
return {};
}
auto emoji_without_modifiers = remove_emoji_modifiers(emoji).str();
auto emoji_without_modifiers = remove_emoji_modifiers(emoji);
auto it = sticker_set->emoji_stickers_map_.find(emoji_without_modifiers);
if (it == sticker_set->emoji_stickers_map_.end()) {
return {};
@ -3088,7 +3089,7 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s
s->emoji_stickers_map_.clear();
s->sticker_emojis_map_.clear();
for (auto &pack : packs) {
auto cleaned_emoji = remove_emoji_modifiers(pack->emoticon_).str();
auto cleaned_emoji = remove_emoji_modifiers(pack->emoticon_);
if (cleaned_emoji.empty()) {
LOG(ERROR) << "Receive empty emoji in " << set_id << "/" << s->short_name << " from " << source;
continue;
@ -4644,11 +4645,11 @@ vector<FileId> StickersManager::get_animated_emoji_click_stickers(const StickerS
return result;
}
void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *sticker_set, Slice message_text,
void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *sticker_set, string message_text,
FullMessageId full_message_id, double start_time,
Promise<td_api::object_ptr<td_api::sticker>> &&promise) {
CHECK(sticker_set->was_loaded);
message_text = remove_emoji_modifiers(message_text);
remove_emoji_modifiers_in_place(message_text);
if (message_text.empty()) {
return promise.set_error(Status::Error(400, "Message is not an animated emoji message"));
}
@ -4686,7 +4687,7 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic
}
if (last_clicked_animated_emoji_ != message_text) {
pending_animated_emoji_clicks_.clear();
last_clicked_animated_emoji_ = message_text.str();
last_clicked_animated_emoji_ = std::move(message_text);
}
if (!pending_animated_emoji_clicks_.empty() && found_stickers.size() >= 2) {
@ -4802,7 +4803,7 @@ void StickersManager::flush_sent_animated_emoji_clicks() {
sent_animated_emoji_clicks_.erase(sent_animated_emoji_clicks_.begin(), it);
}
bool StickersManager::is_sent_animated_emoji_click(DialogId dialog_id, Slice emoji) {
bool StickersManager::is_sent_animated_emoji_click(DialogId dialog_id, const string &emoji) {
flush_sent_animated_emoji_clicks();
for (const auto &click : sent_animated_emoji_clicks_) {
if (click.dialog_id == dialog_id && click.emoji == emoji) {
@ -4812,7 +4813,7 @@ bool StickersManager::is_sent_animated_emoji_click(DialogId dialog_id, Slice emo
return false;
}
Status StickersManager::on_animated_emoji_message_clicked(Slice emoji, FullMessageId full_message_id, string data) {
Status StickersManager::on_animated_emoji_message_clicked(string &&emoji, FullMessageId full_message_id, string data) {
if (td_->auth_manager_->is_bot() || disable_animated_emojis_) {
return Status::OK();
}
@ -4875,7 +4876,7 @@ Status StickersManager::on_animated_emoji_message_clicked(Slice emoji, FullMessa
load_special_sticker_set(special_sticker_set);
PendingOnAnimatedEmojiClicked pending_request;
pending_request.emoji_ = emoji.str();
pending_request.emoji_ = std::move(emoji);
pending_request.full_message_id_ = full_message_id;
pending_request.clicks_ = std::move(clicks);
pending_on_animated_emoji_message_clicked_.push_back(std::move(pending_request));

View File

@ -87,9 +87,9 @@ class StickersManager final : public Actor {
void on_send_animated_emoji_clicks(DialogId dialog_id, const string &emoji);
bool is_sent_animated_emoji_click(DialogId dialog_id, Slice emoji);
bool is_sent_animated_emoji_click(DialogId dialog_id, const string &emoji);
Status on_animated_emoji_message_clicked(Slice emoji, FullMessageId full_message_id, string data);
Status on_animated_emoji_message_clicked(string &&emoji, FullMessageId full_message_id, string data);
bool is_active_reaction(const string &reaction) const;
@ -676,7 +676,7 @@ class StickersManager final : public Actor {
vector<FileId> get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const;
void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, Slice message_text,
void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, string message_text,
FullMessageId full_message_id, double start_time,
Promise<td_api::object_ptr<td_api::sticker>> &&promise);

View File

@ -341,7 +341,7 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser
vector<string> emojis;
parse(emojis, parser);
for (auto &emoji : emojis) {
auto cleaned_emoji = remove_emoji_modifiers(emoji).str();
auto cleaned_emoji = remove_emoji_modifiers(emoji);
if (!cleaned_emoji.empty()) {
auto &sticker_ids = sticker_set->emoji_stickers_map_[cleaned_emoji];
if (sticker_ids.empty() || sticker_ids.back() != sticker_id) {

View File

@ -243,7 +243,13 @@ Slice remove_fitzpatrick_modifier(Slice emoji) {
return emoji;
}
Slice remove_emoji_modifiers(Slice emoji) {
string remove_emoji_modifiers(Slice emoji) {
string result = emoji.str();
remove_emoji_modifiers_in_place(result);
return result;
}
void remove_emoji_modifiers_in_place(string &emoji) {
static const Slice modifiers[] = {u8"\uFE0F" /* variation selector-16 */,
u8"\u200D\u2640" /* zero width joiner + female sign */,
u8"\u200D\u2642" /* zero width joiner + male sign */,
@ -252,21 +258,23 @@ Slice remove_emoji_modifiers(Slice emoji) {
u8"\U0001F3FD" /* emoji modifier fitzpatrick type-4 */,
u8"\U0001F3FE" /* emoji modifier fitzpatrick type-5 */,
u8"\U0001F3FF" /* emoji modifier fitzpatrick type-6 */};
bool found = true;
while (found) {
found = false;
size_t j = 0;
for (size_t i = 0; i < emoji.size();) {
bool is_found = false;
for (auto &modifier : modifiers) {
if (ends_with(emoji, modifier) && emoji.size() > modifier.size()) {
emoji.remove_suffix(modifier.size());
found = true;
auto length = modifier.size();
if (i + length <= emoji.size() && Slice(&emoji[i], length) == modifier) {
// skip modifier
i += length;
is_found = true;
break;
}
}
if (!is_found) {
emoji[j++] = emoji[i++];
}
}
return emoji;
}
void remove_emoji_modifiers_in_place(string &emoji) {
emoji.resize(remove_emoji_modifiers(emoji).size());
emoji.resize(j);
}
string remove_emoji_selectors(Slice emoji) {

View File

@ -20,10 +20,10 @@ int get_fitzpatrick_modifier(Slice emoji);
// removes all Fitzpatrick modifier from the end of the string
Slice remove_fitzpatrick_modifier(Slice emoji);
// removes all emoji modifiers from the end of the string
Slice remove_emoji_modifiers(Slice emoji);
// removes all emoji modifiers from the string
string remove_emoji_modifiers(Slice emoji);
// removes all emoji modifiers from the end of the string in place
// removes all emoji modifiers from the string in-place
void remove_emoji_modifiers_in_place(string &emoji);
// removes all emoji selectors from the string if it is an emoji