diff --git a/td/telegram/MessageReaction.cpp b/td/telegram/MessageReaction.cpp index d2da580a5..ce47f6333 100644 --- a/td/telegram/MessageReaction.cpp +++ b/td/telegram/MessageReaction.cpp @@ -633,6 +633,7 @@ unique_ptr MessageReactions::get_message_reactions( } result->top_reactors_.push_back(std::move(reactor)); } + MessageReactor::fix_message_reactors(result->top_reactors_, true); return result; } @@ -677,9 +678,10 @@ void MessageReactions::update_from(const MessageReactions &old_reactions) { // self paid reaction was known, keep it for (auto &reactor : old_reactions.top_reactors_) { if (reactor.is_me()) { - top_reactors_.push_back(reactor); + // top_reactors_.push_back(reactor); } } + MessageReactor::fix_message_reactors(top_reactors_, false); } for (const auto &old_reaction : old_reactions.reactions_) { if (old_reaction.is_chosen() && diff --git a/td/telegram/MessageReactor.cpp b/td/telegram/MessageReactor.cpp index 4dfd426f9..9093a8d68 100644 --- a/td/telegram/MessageReactor.cpp +++ b/td/telegram/MessageReactor.cpp @@ -9,6 +9,8 @@ #include "td/telegram/Dependencies.h" #include "td/telegram/MessageSender.h" +#include + namespace td { MessageReactor::MessageReactor(telegram_api::object_ptr &&reactor) @@ -29,6 +31,54 @@ void MessageReactor::add_dependencies(Dependencies &dependencies) const { dependencies.add_message_sender_dependencies(dialog_id_); } +void MessageReactor::fix_message_reactors(vector &reactors, bool need_warning) { + size_t TOP_REACTOR_COUNT = 3u; + if (reactors.size() > TOP_REACTOR_COUNT + 1) { + LOG(ERROR) << "Have too many " << reactors; + reactors.resize(TOP_REACTOR_COUNT + 1); + } + if (reactors.size() > TOP_REACTOR_COUNT && !reactors[TOP_REACTOR_COUNT].is_me()) { + LOG(ERROR) << "Receive unexpected " << reactors; + reactors.resize(TOP_REACTOR_COUNT); + } + if (need_warning) { + for (size_t i = 0; i < reactors.size(); i++) { + if (reactors[i].is_top_ != (i < TOP_REACTOR_COUNT)) { + LOG(ERROR) << "Receive incorrect top " << reactors; + break; + } + } + for (size_t i = 0; i + 1 < reactors.size(); i++) { + if (reactors[i].count_ < reactors[i + 1].count_) { + LOG(ERROR) << "Receive unordered " << reactors; + break; + } + } + } + bool was_me = false; + for (const auto &reactor : reactors) { + CHECK(reactor.is_valid()); + if (reactor.is_me()) { + CHECK(!was_me); + was_me = true; + } + } + std::sort(reactors.begin(), reactors.end()); + if (reactors.size() > TOP_REACTOR_COUNT && !reactors[TOP_REACTOR_COUNT].is_me()) { + reactors.resize(TOP_REACTOR_COUNT); + } + for (size_t i = 0; i < reactors.size(); i++) { + reactors[i].is_top_ = (i < TOP_REACTOR_COUNT); + } +} + +bool operator<(const MessageReactor &lhs, const MessageReactor &rhs) { + if (lhs.count_ != rhs.count_) { + return lhs.count_ < rhs.count_; + } + return lhs.dialog_id_.get() < rhs.dialog_id_.get(); +} + bool operator==(const MessageReactor &lhs, const MessageReactor &rhs) { return lhs.dialog_id_ == rhs.dialog_id_ && lhs.count_ == rhs.count_ && lhs.is_top_ == rhs.is_top_ && lhs.is_me_ == rhs.is_me_ && lhs.is_anonymous_ == rhs.is_anonymous_; diff --git a/td/telegram/MessageReactor.h b/td/telegram/MessageReactor.h index 4018c5b18..c0f60ce90 100644 --- a/td/telegram/MessageReactor.h +++ b/td/telegram/MessageReactor.h @@ -26,6 +26,8 @@ class MessageReactor { bool is_me_ = false; bool is_anonymous_ = false; + friend bool operator<(const MessageReactor &lhs, const MessageReactor &rhs); + friend bool operator==(const MessageReactor &lhs, const MessageReactor &rhs); friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactor &reactor); @@ -35,6 +37,9 @@ class MessageReactor { explicit MessageReactor(telegram_api::object_ptr &&reactor); + MessageReactor(DialogId dialog_id, int32 count) : dialog_id_(dialog_id), count_(count), is_me_(true) { + } + bool is_valid() const { return (dialog_id_.is_valid() || (!is_me_ && !is_anonymous_)) && count_ > 0 && (is_top_ || is_me_); } @@ -47,6 +52,8 @@ class MessageReactor { void add_dependencies(Dependencies &dependencies) const; + static void fix_message_reactors(vector &reactors, bool need_warning); + template void store(StorerT &storer) const; @@ -54,6 +61,8 @@ class MessageReactor { void parse(ParserT &parser); }; +bool operator<(const MessageReactor &lhs, const MessageReactor &rhs); + bool operator==(const MessageReactor &lhs, const MessageReactor &rhs); inline bool operator!=(const MessageReactor &lhs, const MessageReactor &rhs) {