From 69760f891ab34cd98a6faf70e212911fae3b443e Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 6 Jan 2023 13:43:46 +0300 Subject: [PATCH] Make DialogParticipant flags 64-bit. --- td/telegram/DialogParticipant.cpp | 64 ++++++++--------- td/telegram/DialogParticipant.h | 114 ++++++++++++++++++------------ td/telegram/Version.h | 3 +- 3 files changed, 101 insertions(+), 80 deletions(-) diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index b1ecaf293..f78f1b6bb 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -65,18 +65,18 @@ AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dial case ChannelType::Unknown: break; } - flags_ = (static_cast(can_manage_dialog) * CAN_MANAGE_DIALOG) | - (static_cast(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS) | - (static_cast(can_post_messages) * CAN_POST_MESSAGES) | - (static_cast(can_edit_messages) * CAN_EDIT_MESSAGES) | - (static_cast(can_delete_messages) * CAN_DELETE_MESSAGES) | - (static_cast(can_invite_users) * CAN_INVITE_USERS) | - (static_cast(can_restrict_members) * CAN_RESTRICT_MEMBERS) | - (static_cast(can_pin_messages) * CAN_PIN_MESSAGES) | - (static_cast(can_manage_topics) * CAN_MANAGE_TOPICS) | - (static_cast(can_promote_members) * CAN_PROMOTE_MEMBERS) | - (static_cast(can_manage_calls) * CAN_MANAGE_CALLS) | - (static_cast(is_anonymous) * IS_ANONYMOUS); + flags_ = (static_cast(can_manage_dialog) * CAN_MANAGE_DIALOG) | + (static_cast(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS) | + (static_cast(can_post_messages) * CAN_POST_MESSAGES) | + (static_cast(can_edit_messages) * CAN_EDIT_MESSAGES) | + (static_cast(can_delete_messages) * CAN_DELETE_MESSAGES) | + (static_cast(can_invite_users) * CAN_INVITE_USERS) | + (static_cast(can_restrict_members) * CAN_RESTRICT_MEMBERS) | + (static_cast(can_pin_messages) * CAN_PIN_MESSAGES) | + (static_cast(can_manage_topics) * CAN_MANAGE_TOPICS) | + (static_cast(can_promote_members) * CAN_PROMOTE_MEMBERS) | + (static_cast(can_manage_calls) * CAN_MANAGE_CALLS) | + (static_cast(is_anonymous) * IS_ANONYMOUS); if (flags_ != 0) { flags_ |= CAN_MANAGE_DIALOG; if (channel_type == ChannelType::Broadcast) { @@ -225,18 +225,18 @@ RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media, bool can_add_web_page_previews, bool can_send_polls, bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages, bool can_manage_topics) { - flags_ = (static_cast(can_send_messages) * CAN_SEND_MESSAGES) | - (static_cast(can_send_media) * CAN_SEND_MEDIA) | - (static_cast(can_send_stickers) * CAN_SEND_STICKERS) | - (static_cast(can_send_animations) * CAN_SEND_ANIMATIONS) | - (static_cast(can_send_games) * CAN_SEND_GAMES) | - (static_cast(can_use_inline_bots) * CAN_USE_INLINE_BOTS) | - (static_cast(can_add_web_page_previews) * CAN_ADD_WEB_PAGE_PREVIEWS) | - (static_cast(can_send_polls) * CAN_SEND_POLLS) | - (static_cast(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS) | - (static_cast(can_invite_users) * CAN_INVITE_USERS) | - (static_cast(can_pin_messages) * CAN_PIN_MESSAGES) | - (static_cast(can_manage_topics) * CAN_MANAGE_TOPICS); + flags_ = (static_cast(can_send_messages) * CAN_SEND_MESSAGES) | + (static_cast(can_send_media) * CAN_SEND_MEDIA) | + (static_cast(can_send_stickers) * CAN_SEND_STICKERS) | + (static_cast(can_send_animations) * CAN_SEND_ANIMATIONS) | + (static_cast(can_send_games) * CAN_SEND_GAMES) | + (static_cast(can_use_inline_bots) * CAN_USE_INLINE_BOTS) | + (static_cast(can_add_web_page_previews) * CAN_ADD_WEB_PAGE_PREVIEWS) | + (static_cast(can_send_polls) * CAN_SEND_POLLS) | + (static_cast(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS) | + (static_cast(can_invite_users) * CAN_INVITE_USERS) | + (static_cast(can_pin_messages) * CAN_PIN_MESSAGES) | + (static_cast(can_manage_topics) * CAN_MANAGE_TOPICS); } td_api::object_ptr RestrictedRights::get_chat_permissions_object() const { @@ -343,8 +343,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights return string_builder; } -DialogParticipantStatus::DialogParticipantStatus(Type type, uint32 flags, int32 until_date, string rank) - : type_(type), flags_(flags), until_date_(until_date), rank_(strip_empty_characters(std::move(rank), 16)) { +DialogParticipantStatus::DialogParticipantStatus(Type type, uint64 flags, int32 until_date, string rank) + : type_(type), until_date_(until_date), flags_(flags), rank_(strip_empty_characters(std::move(rank), 16)) { } int32 DialogParticipantStatus::fix_until_date(int32 date) { @@ -364,11 +364,11 @@ DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is DialogParticipantStatus DialogParticipantStatus::Administrator(AdministratorRights administrator_rights, string &&rank, bool can_be_edited) { - uint32 flags = administrator_rights.flags_; + uint64 flags = administrator_rights.flags_; if (flags == 0) { return Member(); } - flags = flags | (static_cast(can_be_edited) * CAN_BE_EDITED); + flags = flags | (static_cast(can_be_edited) * CAN_BE_EDITED); return DialogParticipantStatus( Type::Administrator, IS_MEMBER | (RestrictedRights::ALL_RESTRICTED_RIGHTS & ~RestrictedRights::ALL_ADMIN_PERMISSION_RIGHTS) | flags, 0, @@ -381,11 +381,11 @@ DialogParticipantStatus DialogParticipantStatus::Member() { DialogParticipantStatus DialogParticipantStatus::Restricted(RestrictedRights restricted_rights, bool is_member, int32 restricted_until_date) { - uint32 flags = restricted_rights.flags_; + uint64 flags = restricted_rights.flags_; if (flags == RestrictedRights::ALL_RESTRICTED_RIGHTS) { return is_member ? Member() : Left(); } - flags |= (static_cast(is_member) * IS_MEMBER); + flags |= (static_cast(is_member) * IS_MEMBER); return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date), string()); } @@ -415,7 +415,7 @@ DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited, tl_object_ptr &&admin_rights, string rank, ChannelType channel_type) { CHECK(admin_rights != nullptr); - uint32 flags = AdministratorRights(admin_rights, channel_type).flags_ | AdministratorRights::CAN_MANAGE_DIALOG; + uint64 flags = AdministratorRights(admin_rights, channel_type).flags_ | AdministratorRights::CAN_MANAGE_DIALOG; if (can_be_edited) { flags |= CAN_BE_EDITED; } @@ -433,7 +433,7 @@ DialogParticipantStatus::DialogParticipantStatus(bool is_member, auto until_date = fix_until_date(banned_rights->until_date_); banned_rights->until_date_ = std::numeric_limits::max(); - uint32 flags = RestrictedRights(banned_rights).flags_ | (static_cast(is_member) * IS_MEMBER); + uint64 flags = RestrictedRights(banned_rights).flags_ | (static_cast(is_member) * IS_MEMBER); *this = DialogParticipantStatus(Type::Restricted, flags, until_date, string()); } diff --git a/td/telegram/DialogParticipant.h b/td/telegram/DialogParticipant.h index e517b502a..b3b46194f 100644 --- a/td/telegram/DialogParticipant.h +++ b/td/telegram/DialogParticipant.h @@ -22,30 +22,30 @@ namespace td { class Td; class AdministratorRights { - static constexpr uint32 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 0; - static constexpr uint32 CAN_POST_MESSAGES = 1 << 1; - static constexpr uint32 CAN_EDIT_MESSAGES = 1 << 2; - static constexpr uint32 CAN_DELETE_MESSAGES = 1 << 3; - static constexpr uint32 CAN_INVITE_USERS = 1 << 4; - // static constexpr uint32 CAN_EXPORT_DIALOG_INVITE_LINK = 1 << 5; - static constexpr uint32 CAN_RESTRICT_MEMBERS = 1 << 6; - static constexpr uint32 CAN_PIN_MESSAGES = 1 << 7; - static constexpr uint32 CAN_PROMOTE_MEMBERS = 1 << 8; - static constexpr uint32 CAN_MANAGE_CALLS = 1 << 9; - static constexpr uint32 CAN_MANAGE_DIALOG = 1 << 10; - static constexpr uint32 CAN_MANAGE_TOPICS = 1 << 11; - static constexpr uint32 IS_ANONYMOUS = 1 << 13; + static constexpr uint64 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 0; + static constexpr uint64 CAN_POST_MESSAGES = 1 << 1; + static constexpr uint64 CAN_EDIT_MESSAGES = 1 << 2; + static constexpr uint64 CAN_DELETE_MESSAGES = 1 << 3; + static constexpr uint64 CAN_INVITE_USERS = 1 << 4; + // static constexpr uint64 CAN_EXPORT_DIALOG_INVITE_LINK = 1 << 5; + static constexpr uint64 CAN_RESTRICT_MEMBERS = 1 << 6; + static constexpr uint64 CAN_PIN_MESSAGES = 1 << 7; + static constexpr uint64 CAN_PROMOTE_MEMBERS = 1 << 8; + static constexpr uint64 CAN_MANAGE_CALLS = 1 << 9; + static constexpr uint64 CAN_MANAGE_DIALOG = 1 << 10; + static constexpr uint64 CAN_MANAGE_TOPICS = 1 << 11; + static constexpr uint64 IS_ANONYMOUS = 1 << 13; - static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS = CAN_CHANGE_INFO_AND_SETTINGS | CAN_POST_MESSAGES | + static constexpr uint64 ALL_ADMINISTRATOR_RIGHTS = CAN_CHANGE_INFO_AND_SETTINGS | CAN_POST_MESSAGES | CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | CAN_INVITE_USERS | CAN_RESTRICT_MEMBERS | CAN_PIN_MESSAGES | CAN_MANAGE_TOPICS | CAN_PROMOTE_MEMBERS | CAN_MANAGE_CALLS | CAN_MANAGE_DIALOG; - uint32 flags_; + uint64 flags_; friend class DialogParticipantStatus; - explicit AdministratorRights(int32 flags) : flags_(flags & (ALL_ADMINISTRATOR_RIGHTS | IS_ANONYMOUS)) { + explicit AdministratorRights(uint64 flags) : flags_(flags & (ALL_ADMINISTRATOR_RIGHTS | IS_ANONYMOUS)) { } public: @@ -121,7 +121,13 @@ class AdministratorRights { template void parse(ParserT &parser) { - td::parse(flags_, parser); + if (parser.version() >= static_cast(Version::MakeParticipantFlags64Bit)) { + td::parse(flags_, parser); + } else { + uint32 legacy_flags; + td::parse(legacy_flags, parser); + flags_ = legacy_flags; + } } friend bool operator==(const AdministratorRights &lhs, const AdministratorRights &rhs); @@ -136,31 +142,31 @@ bool operator!=(const AdministratorRights &lhs, const AdministratorRights &rhs); StringBuilder &operator<<(StringBuilder &string_builder, const AdministratorRights &status); class RestrictedRights { - static constexpr uint32 CAN_SEND_MESSAGES = 1 << 16; - static constexpr uint32 CAN_SEND_MEDIA = 1 << 17; - static constexpr uint32 CAN_SEND_STICKERS = 1 << 18; - static constexpr uint32 CAN_SEND_ANIMATIONS = 1 << 19; - static constexpr uint32 CAN_SEND_GAMES = 1 << 20; - static constexpr uint32 CAN_USE_INLINE_BOTS = 1 << 21; - static constexpr uint32 CAN_ADD_WEB_PAGE_PREVIEWS = 1 << 22; - static constexpr uint32 CAN_SEND_POLLS = 1 << 23; - static constexpr uint32 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 24; - static constexpr uint32 CAN_INVITE_USERS = 1 << 25; - static constexpr uint32 CAN_PIN_MESSAGES = 1 << 26; - static constexpr uint32 CAN_MANAGE_TOPICS = 1 << 12; + static constexpr uint64 CAN_SEND_MESSAGES = 1 << 16; + static constexpr uint64 CAN_SEND_MEDIA = 1 << 17; + static constexpr uint64 CAN_SEND_STICKERS = 1 << 18; + static constexpr uint64 CAN_SEND_ANIMATIONS = 1 << 19; + static constexpr uint64 CAN_SEND_GAMES = 1 << 20; + static constexpr uint64 CAN_USE_INLINE_BOTS = 1 << 21; + static constexpr uint64 CAN_ADD_WEB_PAGE_PREVIEWS = 1 << 22; + static constexpr uint64 CAN_SEND_POLLS = 1 << 23; + static constexpr uint64 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 24; + static constexpr uint64 CAN_INVITE_USERS = 1 << 25; + static constexpr uint64 CAN_PIN_MESSAGES = 1 << 26; + static constexpr uint64 CAN_MANAGE_TOPICS = 1 << 12; - static constexpr uint32 ALL_ADMIN_PERMISSION_RIGHTS = + static constexpr uint64 ALL_ADMIN_PERMISSION_RIGHTS = CAN_CHANGE_INFO_AND_SETTINGS | CAN_INVITE_USERS | CAN_PIN_MESSAGES | CAN_MANAGE_TOPICS; - static constexpr uint32 ALL_RESTRICTED_RIGHTS = + static constexpr uint64 ALL_RESTRICTED_RIGHTS = CAN_SEND_MESSAGES | CAN_SEND_MEDIA | CAN_SEND_STICKERS | CAN_SEND_ANIMATIONS | CAN_SEND_GAMES | CAN_USE_INLINE_BOTS | CAN_ADD_WEB_PAGE_PREVIEWS | CAN_SEND_POLLS | ALL_ADMIN_PERMISSION_RIGHTS; - uint32 flags_; + uint64 flags_; friend class DialogParticipantStatus; - explicit RestrictedRights(int32 flags) : flags_(flags & ALL_RESTRICTED_RIGHTS) { + explicit RestrictedRights(uint64 flags) : flags_(flags & ALL_RESTRICTED_RIGHTS) { } public: @@ -232,7 +238,13 @@ class RestrictedRights { template void parse(ParserT &parser) { - td::parse(flags_, parser); + if (parser.version() >= static_cast(Version::MakeParticipantFlags64Bit)) { + td::parse(flags_, parser); + } else { + uint32 legacy_flags; + td::parse(legacy_flags, parser); + flags_ = legacy_flags; + } } friend bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs); @@ -247,26 +259,26 @@ bool operator!=(const RestrictedRights &lhs, const RestrictedRights &rhs); StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status); class DialogParticipantStatus { - // all flags are used - static constexpr uint32 HAS_RANK = 1 << 14; - static constexpr uint32 CAN_BE_EDITED = 1 << 15; + static constexpr uint64 HAS_RANK = 1 << 14; + static constexpr uint64 CAN_BE_EDITED = 1 << 15; - static constexpr uint32 IS_MEMBER = 1 << 27; + static constexpr uint64 IS_MEMBER = 1 << 27; // bits 28-30 reserved for Type static constexpr int TYPE_SHIFT = 28; - static constexpr uint32 HAS_UNTIL_DATE = 1u << 31; + static constexpr int TYPE_SIZE = 3; + static constexpr uint64 HAS_UNTIL_DATE = 1u << 31; enum class Type : int32 { Creator, Administrator, Member, Restricted, Left, Banned }; // all fields are logically const, but should be updated in update_restrictions() mutable Type type_; - mutable uint32 flags_; mutable int32 until_date_; // restricted and banned only - string rank_; // creator and administrator only + mutable uint64 flags_; + string rank_; // creator and administrator only static int32 fix_until_date(int32 date); - DialogParticipantStatus(Type type, uint32 flags, int32 until_date, string rank); + DialogParticipantStatus(Type type, uint64 flags, int32 until_date, string rank); AdministratorRights get_administrator_rights() const { return AdministratorRights(flags_); @@ -463,7 +475,7 @@ class DialogParticipantStatus { template void store(StorerT &storer) const { - uint32 stored_flags = flags_ | (static_cast(type_) << TYPE_SHIFT); + uint64 stored_flags = flags_ | (static_cast(static_cast(type_)) << TYPE_SHIFT); if (until_date_ > 0) { stored_flags |= HAS_UNTIL_DATE; } @@ -481,8 +493,14 @@ class DialogParticipantStatus { template void parse(ParserT &parser) { - uint32 stored_flags; - td::parse(stored_flags, parser); + uint64 stored_flags; + if (parser.version() >= static_cast(Version::MakeParticipantFlags64Bit)) { + td::parse(stored_flags, parser); + } else { + uint32 legacy_flags; + td::parse(legacy_flags, parser); + stored_flags = legacy_flags; + } if ((stored_flags & HAS_UNTIL_DATE) != 0) { td::parse(until_date_, parser); stored_flags &= ~HAS_UNTIL_DATE; @@ -491,8 +509,10 @@ class DialogParticipantStatus { td::parse(rank_, parser); stored_flags &= ~HAS_RANK; } - type_ = static_cast(stored_flags >> TYPE_SHIFT); - flags_ = stored_flags & ((1 << TYPE_SHIFT) - 1); + type_ = static_cast(static_cast((stored_flags >> TYPE_SHIFT) & ((1 << TYPE_SIZE) - 1))); + stored_flags -= static_cast(static_cast(type_)) << TYPE_SHIFT; + + flags_ = stored_flags; if (is_creator()) { flags_ |= AdministratorRights::ALL_ADMINISTRATOR_RIGHTS | RestrictedRights::ALL_RESTRICTED_RIGHTS; diff --git a/td/telegram/Version.h b/td/telegram/Version.h index 719d2e477..03ebd4373 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -58,7 +58,8 @@ enum class Version : int32 { AddInputInvoiceFlags, AddVideoNoteFlags, AddMessageChatSetTtlFlags, - AddMessageMediaSpoiler, + AddMessageMediaSpoiler, // 45 + MakeParticipantFlags64Bit, Next };