Add and use SavedReactionTags::calc_hash().

This commit is contained in:
levlam 2024-01-24 00:25:02 +03:00
parent 839969e255
commit 1b15b2825c
6 changed files with 43 additions and 0 deletions

View File

@ -12,6 +12,7 @@
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/logevent/LogEvent.h" #include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/MessagesManager.h" #include "td/telegram/MessagesManager.h"
#include "td/telegram/misc.h"
#include "td/telegram/OptionManager.h" #include "td/telegram/OptionManager.h"
#include "td/telegram/ReactionManager.hpp" #include "td/telegram/ReactionManager.hpp"
#include "td/telegram/StickerFormat.h" #include "td/telegram/StickerFormat.h"
@ -307,9 +308,22 @@ void ReactionManager::SavedReactionTags::update_saved_messages_tags(const vector
} }
if (is_changed) { if (is_changed) {
std::sort(tags_.begin(), tags_.end()); std::sort(tags_.begin(), tags_.end());
hash_ = calc_hash();
} }
} }
int64 ReactionManager::SavedReactionTags::calc_hash() const {
vector<uint64> numbers;
for (const auto &tag : tags_) {
numbers.push_back(tag.reaction_type_.get_hash());
if (!tag.title_.empty()) {
numbers.push_back(get_md5_string_hash(tag.title_));
}
numbers.push_back(tag.count_);
}
return get_vector_hash(numbers);
}
ReactionManager::ReactionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { ReactionManager::ReactionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
} }
@ -859,6 +873,9 @@ void ReactionManager::on_get_saved_messages_tags(
tags_.tags_ = std::move(saved_reaction_tags); tags_.tags_ = std::move(saved_reaction_tags);
need_send_update = true; need_send_update = true;
} }
if (tags_.hash_ != tags_.calc_hash()) {
LOG(ERROR) << "Receive unexpected Saved Messages tag hash";
}
tags_.is_inited_ = true; tags_.is_inited_ = true;
break; break;
} }

View File

@ -163,6 +163,8 @@ class ReactionManager final : public Actor {
void update_saved_messages_tags(const vector<ReactionType> &old_tags, const vector<ReactionType> &new_tags, void update_saved_messages_tags(const vector<ReactionType> &old_tags, const vector<ReactionType> &new_tags,
bool &is_changed, bool &need_reload_title); bool &is_changed, bool &need_reload_title);
int64 calc_hash() const;
}; };
td_api::object_ptr<td_api::emojiReaction> get_emoji_reaction_object(const string &emoji) const; td_api::object_ptr<td_api::emojiReaction> get_emoji_reaction_object(const string &emoji) const;

View File

@ -134,6 +134,14 @@ td_api::object_ptr<td_api::updateDefaultReactionType> ReactionType::get_update_d
return td_api::make_object<td_api::updateDefaultReactionType>(get_reaction_type_object()); return td_api::make_object<td_api::updateDefaultReactionType>(get_reaction_type_object());
} }
uint64 ReactionType::get_hash() const {
if (is_custom_reaction()) {
return static_cast<uint64>(get_custom_emoji_id(reaction_));
} else {
return get_md5_string_hash(remove_emoji_selectors(reaction_));
}
}
bool ReactionType::is_custom_reaction() const { bool ReactionType::is_custom_reaction() const {
return reaction_[0] == '#'; return reaction_[0] == '#';
} }

View File

@ -55,6 +55,8 @@ class ReactionType {
td_api::object_ptr<td_api::updateDefaultReactionType> get_update_default_reaction_type() const; td_api::object_ptr<td_api::updateDefaultReactionType> get_update_default_reaction_type() const;
uint64 get_hash() const;
bool is_custom_reaction() const; bool is_custom_reaction() const;
bool is_active_reaction(const FlatHashMap<ReactionType, size_t, ReactionTypeHash> &active_reaction_pos) const; bool is_active_reaction(const FlatHashMap<ReactionType, size_t, ReactionTypeHash> &active_reaction_pos) const;

View File

@ -8,6 +8,7 @@
#include "td/utils/algorithm.h" #include "td/utils/algorithm.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/crypto.h"
#include "td/utils/Hints.h" #include "td/utils/Hints.h"
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include "td/utils/Slice.h" #include "td/utils/Slice.h"
@ -285,6 +286,16 @@ bool is_allowed_username(Slice username) {
return true; return true;
} }
uint64 get_md5_string_hash(const string &str) {
unsigned char hash[16];
md5(str, {hash, sizeof(hash)});
uint64 result = 0;
for (int i = 0; i <= 7; i++) {
result += static_cast<uint64>(hash[i]) << (56 - 8 * i);
}
return result;
}
int64 get_vector_hash(const vector<uint64> &numbers) { int64 get_vector_hash(const vector<uint64> &numbers) {
uint64 acc = 0; uint64 acc = 0;
for (auto number : numbers) { for (auto number : numbers) {

View File

@ -39,6 +39,9 @@ bool is_valid_username(Slice username);
// checks whether a string can be set as a username // checks whether a string can be set as a username
bool is_allowed_username(Slice username); bool is_allowed_username(Slice username);
// calculates truncated MD5 hash of a string
uint64 get_md5_string_hash(const string &str) TD_WARN_UNUSED_RESULT;
// calculates hash of list of uint64 // calculates hash of list of uint64
int64 get_vector_hash(const vector<uint64> &numbers) TD_WARN_UNUSED_RESULT; int64 get_vector_hash(const vector<uint64> &numbers) TD_WARN_UNUSED_RESULT;