Merge remote-tracking branch 'td/master'
This commit is contained in:
commit
86159c5a7d
@ -18,10 +18,10 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
AdministratorRights::AdministratorRights(bool can_manage_dialog, bool can_change_info, bool can_post_messages,
|
||||
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
|
||||
bool can_restrict_members, bool can_pin_messages, bool can_promote_members,
|
||||
bool can_manage_calls) {
|
||||
AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info,
|
||||
bool can_post_messages, bool can_edit_messages, bool can_delete_messages,
|
||||
bool can_invite_users, bool can_restrict_members, bool can_pin_messages,
|
||||
bool can_promote_members, bool can_manage_calls) {
|
||||
flags_ = (static_cast<uint32>(can_manage_dialog) * CAN_MANAGE_DIALOG) |
|
||||
(static_cast<uint32>(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS) |
|
||||
(static_cast<uint32>(can_post_messages) * CAN_POST_MESSAGES) |
|
||||
@ -31,14 +31,14 @@ AdministratorRights::AdministratorRights(bool can_manage_dialog, bool can_change
|
||||
(static_cast<uint32>(can_restrict_members) * CAN_RESTRICT_MEMBERS) |
|
||||
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES) |
|
||||
(static_cast<uint32>(can_promote_members) * CAN_PROMOTE_MEMBERS) |
|
||||
(static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS);
|
||||
(static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS) |
|
||||
(static_cast<uint32>(is_anonymous) * IS_ANONYMOUS);
|
||||
if (flags_ != 0) {
|
||||
flags_ |= CAN_MANAGE_DIALOG;
|
||||
}
|
||||
}
|
||||
|
||||
telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get_chat_admin_rights(
|
||||
bool is_anonymous) const {
|
||||
telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get_chat_admin_rights() const {
|
||||
int32 flags = 0;
|
||||
if ((flags_ & CAN_CHANGE_INFO_AND_SETTINGS) != 0) {
|
||||
flags |= telegram_api::chatAdminRights::CHANGE_INFO_MASK;
|
||||
@ -70,8 +70,7 @@ telegram_api::object_ptr<telegram_api::chatAdminRights> AdministratorRights::get
|
||||
if (can_manage_dialog()) {
|
||||
flags |= telegram_api::chatAdminRights::OTHER_MASK;
|
||||
}
|
||||
|
||||
if (is_anonymous) {
|
||||
if (is_anonymous()) {
|
||||
flags |= telegram_api::chatAdminRights::ANONYMOUS_MASK;
|
||||
}
|
||||
|
||||
@ -120,6 +119,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const AdministratorRigh
|
||||
if (status.can_manage_calls()) {
|
||||
string_builder << "(voice chat)";
|
||||
}
|
||||
if (status.is_anonymous()) {
|
||||
string_builder << "(anonymous)";
|
||||
}
|
||||
return string_builder;
|
||||
}
|
||||
|
||||
@ -247,27 +249,17 @@ int32 DialogParticipantStatus::fix_until_date(int32 date) {
|
||||
return date;
|
||||
}
|
||||
|
||||
DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is_anonymous, string rank) {
|
||||
DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is_anonymous, string &&rank) {
|
||||
return DialogParticipantStatus(Type::Creator,
|
||||
AdministratorRights::ALL_ADMINISTRATOR_RIGHTS |
|
||||
RestrictedRights::ALL_RESTRICTED_RIGHTS | (is_member ? IS_MEMBER : 0) |
|
||||
(is_anonymous ? IS_ANONYMOUS : 0),
|
||||
(is_anonymous ? AdministratorRights::IS_ANONYMOUS : 0),
|
||||
0, std::move(rank));
|
||||
}
|
||||
|
||||
DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous, string rank, bool can_be_edited,
|
||||
bool can_manage_dialog, bool can_change_info,
|
||||
bool can_post_messages, bool can_edit_messages,
|
||||
bool can_delete_messages, bool can_invite_users,
|
||||
bool can_restrict_members, bool can_pin_messages,
|
||||
bool can_promote_members, bool can_manage_calls) {
|
||||
uint32 flags = AdministratorRights(can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
|
||||
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
|
||||
can_promote_members, can_manage_calls)
|
||||
.flags_;
|
||||
if (is_anonymous) {
|
||||
flags |= IS_ANONYMOUS | AdministratorRights::CAN_MANAGE_DIALOG;
|
||||
}
|
||||
DialogParticipantStatus DialogParticipantStatus::Administrator(AdministratorRights administrator_rights, string &&rank,
|
||||
bool can_be_edited) {
|
||||
uint32 flags = administrator_rights.flags_;
|
||||
if (flags == 0) {
|
||||
return Member();
|
||||
}
|
||||
@ -278,22 +270,29 @@ DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous
|
||||
std::move(rank));
|
||||
}
|
||||
|
||||
DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous, string &&rank, bool can_be_edited,
|
||||
bool can_manage_dialog, bool can_change_info,
|
||||
bool can_post_messages, bool can_edit_messages,
|
||||
bool can_delete_messages, bool can_invite_users,
|
||||
bool can_restrict_members, bool can_pin_messages,
|
||||
bool can_promote_members, bool can_manage_calls) {
|
||||
auto administrator_rights = AdministratorRights(
|
||||
is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages, can_delete_messages,
|
||||
can_invite_users, can_restrict_members, can_pin_messages, can_promote_members, can_manage_calls);
|
||||
return Administrator(administrator_rights, std::move(rank), can_be_edited);
|
||||
}
|
||||
|
||||
DialogParticipantStatus DialogParticipantStatus::Member() {
|
||||
return DialogParticipantStatus(Type::Member, IS_MEMBER | RestrictedRights::ALL_RESTRICTED_RIGHTS, 0, string());
|
||||
}
|
||||
|
||||
DialogParticipantStatus DialogParticipantStatus::Restricted(
|
||||
bool is_member, int32 restricted_until_date, bool can_send_messages, bool can_send_media, bool can_send_stickers,
|
||||
bool can_send_animations, bool can_send_games, bool can_use_inline_bots, bool can_add_web_page_previews,
|
||||
bool can_send_polls, bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages) {
|
||||
uint32 flags = RestrictedRights(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,
|
||||
can_change_info_and_settings, can_invite_users, can_pin_messages)
|
||||
.flags_ |
|
||||
(static_cast<uint32>(is_member) * IS_MEMBER);
|
||||
if (flags == (IS_MEMBER | RestrictedRights::ALL_RESTRICTED_RIGHTS)) {
|
||||
return Member();
|
||||
DialogParticipantStatus DialogParticipantStatus::Restricted(RestrictedRights restricted_rights, bool is_member,
|
||||
int32 restricted_until_date) {
|
||||
uint32 flags = restricted_rights.flags_;
|
||||
if (flags == RestrictedRights::ALL_RESTRICTED_RIGHTS) {
|
||||
return is_member ? Member() : Left();
|
||||
}
|
||||
flags |= (static_cast<uint32>(is_member) * IS_MEMBER);
|
||||
return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date), string());
|
||||
}
|
||||
|
||||
@ -321,14 +320,8 @@ DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited,
|
||||
tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights,
|
||||
string rank) {
|
||||
CHECK(admin_rights != nullptr);
|
||||
bool is_anonymous = admin_rights->anonymous_;
|
||||
admin_rights->anonymous_ = false;
|
||||
|
||||
uint32 flags =
|
||||
::td::get_administrator_rights(std::move(admin_rights)).flags_ | AdministratorRights::CAN_MANAGE_DIALOG;
|
||||
if (is_anonymous) {
|
||||
flags |= IS_ANONYMOUS;
|
||||
}
|
||||
if (can_be_edited) {
|
||||
flags |= CAN_BE_EDITED;
|
||||
}
|
||||
@ -339,8 +332,7 @@ DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited,
|
||||
DialogParticipantStatus::DialogParticipantStatus(bool is_member,
|
||||
tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights) {
|
||||
CHECK(banned_rights != nullptr);
|
||||
bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
|
||||
if (!can_view_messages) {
|
||||
if (banned_rights->view_messages_) {
|
||||
*this = DialogParticipantStatus::Banned(banned_rights->until_date_);
|
||||
return;
|
||||
}
|
||||
@ -383,7 +375,7 @@ tl_object_ptr<td_api::ChatMemberStatus> DialogParticipantStatus::get_chat_member
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::chatAdminRights> DialogParticipantStatus::get_chat_admin_rights() const {
|
||||
return get_administrator_rights().get_chat_admin_rights(is_anonymous());
|
||||
return get_administrator_rights().get_chat_admin_rights();
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::chatBannedRights> DialogParticipantStatus::get_chat_banned_rights() const {
|
||||
@ -475,9 +467,6 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant
|
||||
if (!status.rank_.empty()) {
|
||||
string_builder << " [" << status.rank_ << "]";
|
||||
}
|
||||
if (status.is_anonymous()) {
|
||||
string_builder << "-anonymous";
|
||||
}
|
||||
return string_builder;
|
||||
case DialogParticipantStatus::Type::Member:
|
||||
return string_builder << "Member";
|
||||
@ -518,7 +507,7 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
|
||||
if (!clean_input_string(custom_title)) {
|
||||
custom_title.clear();
|
||||
}
|
||||
return DialogParticipantStatus::Creator(st->is_member_, st->is_anonymous_, custom_title);
|
||||
return DialogParticipantStatus::Creator(st->is_member_, st->is_anonymous_, std::move(custom_title));
|
||||
}
|
||||
case td_api::chatMemberStatusAdministrator::ID: {
|
||||
auto st = static_cast<const td_api::chatMemberStatusAdministrator *>(status.get());
|
||||
@ -526,30 +515,19 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
|
||||
if (!clean_input_string(custom_title)) {
|
||||
custom_title.clear();
|
||||
}
|
||||
return DialogParticipantStatus::Administrator(
|
||||
st->is_anonymous_, custom_title, true /*st->can_be_edited_*/, st->can_manage_chat_, st->can_change_info_,
|
||||
st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_, st->can_invite_users_,
|
||||
st->can_restrict_members_, st->can_pin_messages_, st->can_promote_members_, st->can_manage_video_chats_);
|
||||
AdministratorRights administrator_rights(st->is_anonymous_, st->can_manage_chat_, st->can_change_info_,
|
||||
st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_,
|
||||
st->can_invite_users_, st->can_restrict_members_, st->can_pin_messages_,
|
||||
st->can_promote_members_, st->can_manage_video_chats_);
|
||||
return DialogParticipantStatus::Administrator(administrator_rights, std::move(custom_title),
|
||||
true /*st->can_be_edited_*/);
|
||||
}
|
||||
case td_api::chatMemberStatusMember::ID:
|
||||
return DialogParticipantStatus::Member();
|
||||
case td_api::chatMemberStatusRestricted::ID: {
|
||||
auto st = static_cast<const td_api::chatMemberStatusRestricted *>(status.get());
|
||||
auto permissions = st->permissions_.get();
|
||||
if (permissions == nullptr) {
|
||||
return DialogParticipantStatus::Restricted(st->is_member_, st->restricted_until_date_, false, false, false,
|
||||
false, false, false, false, false, false, false, false);
|
||||
}
|
||||
bool can_send_polls = permissions->can_send_polls_;
|
||||
bool can_send_media = permissions->can_send_media_messages_;
|
||||
bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls ||
|
||||
permissions->can_send_other_messages_ || permissions->can_add_web_page_previews_;
|
||||
return DialogParticipantStatus::Restricted(
|
||||
st->is_member_, st->restricted_until_date_, can_send_messages, can_send_media,
|
||||
permissions->can_send_other_messages_, permissions->can_send_other_messages_,
|
||||
permissions->can_send_other_messages_, permissions->can_send_other_messages_,
|
||||
permissions->can_add_web_page_previews_, permissions->can_send_polls_, permissions->can_change_info_,
|
||||
permissions->can_invite_users_, permissions->can_pin_messages_);
|
||||
return DialogParticipantStatus::Restricted(::td::get_restricted_rights(st->permissions_), st->is_member_,
|
||||
st->restricted_until_date_);
|
||||
}
|
||||
case td_api::chatMemberStatusLeft::ID:
|
||||
return DialogParticipantStatus::Left();
|
||||
@ -565,58 +543,39 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
|
||||
|
||||
AdministratorRights get_administrator_rights(tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights) {
|
||||
if (admin_rights == nullptr) {
|
||||
return AdministratorRights(false, false, false, false, false, false, false, false, false, false);
|
||||
}
|
||||
if (admin_rights->anonymous_) {
|
||||
LOG(ERROR) << "Receive is_anonymous = true in AdministratorRights";
|
||||
return AdministratorRights(false, false, false, false, false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
bool can_change_info = (admin_rights->flags_ & telegram_api::chatAdminRights::CHANGE_INFO_MASK) != 0;
|
||||
bool can_post_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::POST_MESSAGES_MASK) != 0;
|
||||
bool can_edit_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::EDIT_MESSAGES_MASK) != 0;
|
||||
bool can_delete_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::DELETE_MESSAGES_MASK) != 0;
|
||||
bool can_invite_users = (admin_rights->flags_ & telegram_api::chatAdminRights::INVITE_USERS_MASK) != 0;
|
||||
bool can_restrict_members = (admin_rights->flags_ & telegram_api::chatAdminRights::BAN_USERS_MASK) != 0;
|
||||
bool can_pin_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::PIN_MESSAGES_MASK) != 0;
|
||||
bool can_promote_members = (admin_rights->flags_ & telegram_api::chatAdminRights::ADD_ADMINS_MASK) != 0;
|
||||
bool can_manage_calls = (admin_rights->flags_ & telegram_api::chatAdminRights::MANAGE_CALL_MASK) != 0;
|
||||
bool can_manage_dialog = (admin_rights->flags_ & telegram_api::chatAdminRights::OTHER_MASK) != 0;
|
||||
if (!can_manage_dialog) {
|
||||
if (!admin_rights->other_) {
|
||||
LOG(ERROR) << "Receive wrong other flag in " << to_string(admin_rights);
|
||||
}
|
||||
return AdministratorRights(can_manage_dialog, can_change_info, can_post_messages, can_edit_messages,
|
||||
can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
|
||||
can_promote_members, can_manage_calls);
|
||||
return AdministratorRights(admin_rights->anonymous_, admin_rights->other_, admin_rights->change_info_,
|
||||
admin_rights->post_messages_, admin_rights->edit_messages_, admin_rights->delete_messages_,
|
||||
admin_rights->invite_users_, admin_rights->ban_users_, admin_rights->pin_messages_,
|
||||
admin_rights->add_admins_, admin_rights->manage_call_);
|
||||
}
|
||||
|
||||
RestrictedRights get_restricted_rights(tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights) {
|
||||
if (banned_rights == nullptr) {
|
||||
return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false);
|
||||
}
|
||||
bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
|
||||
if (!can_view_messages) {
|
||||
LOG(ERROR) << "Can't view messages in restricted rights " << to_string(banned_rights);
|
||||
if (banned_rights->view_messages_) {
|
||||
LOG(ERROR) << "Can't view messages in banned rights " << to_string(banned_rights);
|
||||
}
|
||||
LOG_IF(ERROR, banned_rights->until_date_ != std::numeric_limits<int32>::max())
|
||||
<< "Have until date " << banned_rights->until_date_ << " in restricted rights";
|
||||
|
||||
bool can_send_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MESSAGES_MASK) == 0;
|
||||
bool can_send_media_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MEDIA_MASK) == 0;
|
||||
bool can_send_stickers = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_STICKERS_MASK) == 0;
|
||||
bool can_send_animations = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GIFS_MASK) == 0;
|
||||
bool can_send_games = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GAMES_MASK) == 0;
|
||||
bool can_use_inline_bots = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_INLINE_MASK) == 0;
|
||||
bool can_add_web_page_previews = (banned_rights->flags_ & telegram_api::chatBannedRights::EMBED_LINKS_MASK) == 0;
|
||||
bool can_send_polls = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_POLLS_MASK) == 0;
|
||||
bool can_change_info_and_settings = (banned_rights->flags_ & telegram_api::chatBannedRights::CHANGE_INFO_MASK) == 0;
|
||||
bool can_invite_users = (banned_rights->flags_ & telegram_api::chatBannedRights::INVITE_USERS_MASK) == 0;
|
||||
bool can_pin_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::PIN_MESSAGES_MASK) == 0;
|
||||
return RestrictedRights(can_send_messages, can_send_media_messages, can_send_stickers, can_send_animations,
|
||||
can_send_games, can_use_inline_bots, can_add_web_page_previews, can_send_polls,
|
||||
can_change_info_and_settings, can_invite_users, can_pin_messages);
|
||||
return RestrictedRights(!banned_rights->send_messages_, !banned_rights->send_media_, !banned_rights->send_stickers_,
|
||||
!banned_rights->send_gifs_, !banned_rights->send_games_, !banned_rights->send_inline_,
|
||||
!banned_rights->embed_links_, !banned_rights->send_polls_, !banned_rights->change_info_,
|
||||
!banned_rights->invite_users_, !banned_rights->pin_messages_);
|
||||
}
|
||||
|
||||
RestrictedRights get_restricted_rights(const td_api::object_ptr<td_api::chatPermissions> &permissions) {
|
||||
if (permissions == nullptr) {
|
||||
return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
bool can_send_polls = permissions->can_send_polls_;
|
||||
bool can_send_media = permissions->can_send_media_messages_;
|
||||
bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls ||
|
||||
@ -624,7 +583,7 @@ RestrictedRights get_restricted_rights(const td_api::object_ptr<td_api::chatPerm
|
||||
return RestrictedRights(can_send_messages, can_send_media, permissions->can_send_other_messages_,
|
||||
permissions->can_send_other_messages_, permissions->can_send_other_messages_,
|
||||
permissions->can_send_other_messages_, permissions->can_add_web_page_previews_,
|
||||
permissions->can_send_polls_, permissions->can_change_info_, permissions->can_invite_users_,
|
||||
can_send_polls, permissions->can_change_info_, permissions->can_invite_users_,
|
||||
permissions->can_pin_messages_);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ class AdministratorRights {
|
||||
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 IS_ANONYMOUS = 1 << 13;
|
||||
|
||||
static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS =
|
||||
CAN_CHANGE_INFO_AND_SETTINGS | CAN_POST_MESSAGES | CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | CAN_INVITE_USERS |
|
||||
@ -46,11 +47,12 @@ class AdministratorRights {
|
||||
}
|
||||
|
||||
public:
|
||||
AdministratorRights(bool can_manage_dialog, bool can_change_info, bool can_post_messages, bool can_edit_messages,
|
||||
bool can_delete_messages, bool can_invite_users, bool can_restrict_members, bool can_pin_messages,
|
||||
bool can_promote_members, bool can_manage_calls);
|
||||
AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info, bool can_post_messages,
|
||||
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
|
||||
bool can_restrict_members, bool can_pin_messages, bool can_promote_members,
|
||||
bool can_manage_calls);
|
||||
|
||||
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights(bool is_anonymous) const;
|
||||
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights() const;
|
||||
|
||||
bool can_manage_dialog() const {
|
||||
return (flags_ & CAN_MANAGE_DIALOG) != 0;
|
||||
@ -97,6 +99,10 @@ class AdministratorRights {
|
||||
return (flags_ & CAN_MANAGE_CALLS) != 0;
|
||||
}
|
||||
|
||||
bool is_anonymous() const {
|
||||
return (flags_ & IS_ANONYMOUS) != 0;
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const {
|
||||
td::store(flags_, storer);
|
||||
@ -221,7 +227,6 @@ StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights
|
||||
|
||||
class DialogParticipantStatus {
|
||||
// only flags 11 and 12 are unused
|
||||
static constexpr uint32 IS_ANONYMOUS = 1 << 13;
|
||||
static constexpr uint32 HAS_RANK = 1 << 14;
|
||||
static constexpr uint32 CAN_BE_EDITED = 1 << 15;
|
||||
|
||||
@ -251,9 +256,12 @@ class DialogParticipantStatus {
|
||||
}
|
||||
|
||||
public:
|
||||
static DialogParticipantStatus Creator(bool is_member, bool is_anonymous, string rank);
|
||||
static DialogParticipantStatus Creator(bool is_member, bool is_anonymous, string &&rank);
|
||||
|
||||
static DialogParticipantStatus Administrator(bool is_anonymous, string rank, bool can_be_edited,
|
||||
static DialogParticipantStatus Administrator(AdministratorRights administrator_rights, string &&rank,
|
||||
bool can_be_edited);
|
||||
|
||||
static DialogParticipantStatus Administrator(bool is_anonymous, string &&rank, bool can_be_edited,
|
||||
bool can_manage_dialog, bool can_change_info, bool can_post_messages,
|
||||
bool can_edit_messages, bool can_delete_messages, bool can_invite_users,
|
||||
bool can_restrict_members, bool can_pin_messages,
|
||||
@ -261,12 +269,8 @@ class DialogParticipantStatus {
|
||||
|
||||
static DialogParticipantStatus Member();
|
||||
|
||||
static DialogParticipantStatus Restricted(bool is_member, int32 restricted_until_date, bool can_send_messages,
|
||||
bool can_send_media, bool can_send_stickers, bool can_send_animations,
|
||||
bool can_send_games, bool can_use_inline_bots,
|
||||
bool can_add_web_page_previews, bool can_send_polls,
|
||||
bool can_change_info_and_settings, bool can_invite_users,
|
||||
bool can_pin_messages);
|
||||
static DialogParticipantStatus Restricted(RestrictedRights restricted_rights, bool is_member,
|
||||
int32 restricted_until_date);
|
||||
|
||||
static DialogParticipantStatus Left();
|
||||
|
||||
@ -414,7 +418,7 @@ class DialogParticipantStatus {
|
||||
}
|
||||
|
||||
bool is_anonymous() const {
|
||||
return (flags_ & IS_ANONYMOUS) != 0;
|
||||
return get_administrator_rights().is_anonymous();
|
||||
}
|
||||
|
||||
const string &get_rank() const {
|
||||
|
@ -430,6 +430,10 @@ class GetDiscussionMessageQuery final : public Td::ResultHandler {
|
||||
if (expected_dialog_id_ == dialog_id_) {
|
||||
td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDiscussionMessageQuery");
|
||||
}
|
||||
if (status.message() == "MSG_ID_INVALID") {
|
||||
td_->messages_manager_->get_message_from_server({dialog_id_, message_id_}, Promise<Unit>(),
|
||||
"GetDiscussionMessageQuery");
|
||||
}
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
@ -10117,8 +10121,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
|
||||
for (const auto &debug_message : messages) {
|
||||
error += to_string(debug_message);
|
||||
}
|
||||
// TODO move to ERROR
|
||||
LOG(FATAL) << error;
|
||||
LOG(ERROR) << error;
|
||||
promise.set_value(Unit());
|
||||
return;
|
||||
}
|
||||
@ -10143,6 +10146,26 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
|
||||
}
|
||||
}
|
||||
|
||||
if (d->last_new_message_id.is_valid()) {
|
||||
// remove too new messages from response
|
||||
while (!messages.empty()) {
|
||||
if (get_message_dialog_id(messages[0]) == dialog_id &&
|
||||
get_message_id(messages[0], false) <= d->last_new_message_id) {
|
||||
// the message is old enough
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Ignore too new " << get_message_id(messages[0], false);
|
||||
messages.erase(messages.begin());
|
||||
if (messages.empty()) {
|
||||
// received no suitable messages; try again
|
||||
return promise.set_value(Unit());
|
||||
} else {
|
||||
last_received_message_id = get_message_id(messages[0], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool prev_have_full_history = d->have_full_history;
|
||||
MessageId prev_last_new_message_id = d->last_new_message_id;
|
||||
MessageId prev_first_database_message_id = d->first_database_message_id;
|
||||
@ -24161,8 +24184,7 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
||||
break;
|
||||
}
|
||||
if (message->message_id >= last_received_message_id) {
|
||||
// TODO move to ERROR
|
||||
LOG(FATAL) << "Receive " << message->message_id << " after " << last_received_message_id
|
||||
LOG(ERROR) << "Receive " << message->message_id << " after " << last_received_message_id
|
||||
<< " from database in the history of " << dialog_id << " from " << from_message_id << " with offset "
|
||||
<< offset << ", limit " << limit << ", from_the_end = " << from_the_end;
|
||||
break;
|
||||
@ -30580,7 +30602,7 @@ void MessagesManager::remove_message_dialog_notifications(Dialog *d, MessageId m
|
||||
set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(),
|
||||
"remove_message_dialog_notifications 2");
|
||||
} else {
|
||||
LOG(FATAL) << "TODO support notification deletion up to " << max_message_id << " if will be ever needed";
|
||||
LOG(FATAL) << "TODO support notification deletion up to " << max_message_id << " if it would be ever needed";
|
||||
}
|
||||
|
||||
send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, group_info.group_id,
|
||||
@ -38601,8 +38623,7 @@ void MessagesManager::on_get_channel_difference(
|
||||
for (const auto &message : difference->new_messages_) {
|
||||
auto message_id = get_message_id(message, false);
|
||||
if (message_id <= cur_message_id) {
|
||||
// TODO move to ERROR
|
||||
LOG(FATAL) << "Receive " << cur_message_id << " after " << message_id << " in channelDifference of "
|
||||
LOG(ERROR) << "Receive " << cur_message_id << " after " << message_id << " in channelDifference of "
|
||||
<< dialog_id << " with pts " << request_pts << " and limit " << request_limit << ": "
|
||||
<< to_string(difference);
|
||||
after_get_channel_difference(dialog_id, false);
|
||||
|
@ -6233,7 +6233,8 @@ void Td::on_request(uint64 id, const td_api::leaveChat &request) {
|
||||
return promise.set_value(Unit());
|
||||
}
|
||||
|
||||
new_status = DialogParticipantStatus::Creator(false, status.is_anonymous(), status.get_rank());
|
||||
auto rank = status.get_rank();
|
||||
new_status = DialogParticipantStatus::Creator(false, status.is_anonymous(), std::move(rank));
|
||||
}
|
||||
}
|
||||
contacts_manager_->set_dialog_participant_status(dialog_id, DialogId(contacts_manager_->get_my_id()),
|
||||
|
@ -302,8 +302,8 @@ void Scheduler::register_migrated_actor(ActorInfo *actor_info) {
|
||||
VLOG(actor) << "Register migrated actor: " << tag("name", *actor_info) << tag("ptr", actor_info)
|
||||
<< tag("actor_count", actor_count_);
|
||||
actor_count_++;
|
||||
LOG_CHECK(actor_info->is_migrating()) << *actor_info << " " << actor_count_ << " " << sched_id_ << " "
|
||||
<< actor_info->migrate_dest() << " " << actor_info->is_running() << close_flag_;
|
||||
LOG_CHECK(actor_info->is_migrating()) << *actor_info << ' ' << actor_count_ << ' ' << sched_id_ << ' '
|
||||
<< actor_info->migrate_dest() << ' ' << actor_info->is_running() << ' ' << close_flag_;
|
||||
CHECK(sched_id_ == actor_info->migrate_dest());
|
||||
// CHECK(!actor_info->is_running());
|
||||
actor_info->finish_migrate();
|
||||
|
@ -55,42 +55,57 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
static uint64 gcd(uint64 a, uint64 b) {
|
||||
static uint64 pq_gcd(uint64 a, uint64 b) {
|
||||
if (a == 0) {
|
||||
return b;
|
||||
}
|
||||
if (b == 0) {
|
||||
return a;
|
||||
}
|
||||
|
||||
int shift = 0;
|
||||
while ((a & 1) == 0 && (b & 1) == 0) {
|
||||
while ((a & 1) == 0) {
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
shift++;
|
||||
}
|
||||
DCHECK((b & 1) != 0);
|
||||
|
||||
while (true) {
|
||||
while ((a & 1) == 0) {
|
||||
a >>= 1;
|
||||
}
|
||||
while ((b & 1) == 0) {
|
||||
b >>= 1;
|
||||
}
|
||||
if (a > b) {
|
||||
a -= b;
|
||||
a = (a - b) >> 1;
|
||||
while ((a & 1) == 0) {
|
||||
a >>= 1;
|
||||
}
|
||||
} else if (b > a) {
|
||||
b -= a;
|
||||
b = (b - a) >> 1;
|
||||
while ((b & 1) == 0) {
|
||||
b >>= 1;
|
||||
}
|
||||
} else {
|
||||
return a << shift;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns (c + a * b) % pq
|
||||
static uint64 pq_add_mul(uint64 c, uint64 a, uint64 b, uint64 pq) {
|
||||
while (b) {
|
||||
if (b & 1) {
|
||||
c += a;
|
||||
if (c >= pq) {
|
||||
c -= pq;
|
||||
}
|
||||
}
|
||||
a += a;
|
||||
if (a >= pq) {
|
||||
a -= pq;
|
||||
}
|
||||
b >>= 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64 pq_factorize(uint64 pq) {
|
||||
if (pq < 2 || pq > (static_cast<uint64>(1) << 63)) {
|
||||
if (pq <= 2 || pq > (static_cast<uint64>(1) << 63)) {
|
||||
return 1;
|
||||
}
|
||||
if ((pq & 1) == 0) {
|
||||
return 2;
|
||||
}
|
||||
uint64 g = 0;
|
||||
for (int i = 0, iter = 0; i < 3 || iter < 1000; i++) {
|
||||
uint64 q = Random::fast(17, 32) % (pq - 1);
|
||||
@ -99,28 +114,9 @@ uint64 pq_factorize(uint64 pq) {
|
||||
int lim = 1 << (min(5, i) + 18);
|
||||
for (int j = 1; j < lim; j++) {
|
||||
iter++;
|
||||
uint64 a = x;
|
||||
uint64 b = x;
|
||||
uint64 c = q;
|
||||
|
||||
// c += a * b
|
||||
while (b) {
|
||||
if (b & 1) {
|
||||
c += a;
|
||||
if (c >= pq) {
|
||||
c -= pq;
|
||||
}
|
||||
}
|
||||
a += a;
|
||||
if (a >= pq) {
|
||||
a -= pq;
|
||||
}
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
x = c;
|
||||
x = pq_add_mul(q, x, x, pq);
|
||||
uint64 z = x < y ? pq + x - y : x - y;
|
||||
g = gcd(z, pq);
|
||||
g = pq_gcd(z, pq);
|
||||
if (g != 1) {
|
||||
break;
|
||||
}
|
||||
|
@ -14,11 +14,9 @@
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#if TD_HAVE_OPENSSL
|
||||
static bool is_prime(td::uint64 x) {
|
||||
for (td::uint64 d = 2; d < x && d * d <= x; d++) {
|
||||
if (x % d == 0) {
|
||||
@ -28,9 +26,9 @@ static bool is_prime(td::uint64 x) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static td::vector<td::uint64> gen_primes(td::uint64 L, td::uint64 R, int limit = 0) {
|
||||
static td::vector<td::uint64> gen_primes(td::uint64 L, td::uint64 R, std::size_t limit = 0) {
|
||||
td::vector<td::uint64> res;
|
||||
for (auto x = L; x <= R && (limit <= 0 || res.size() < static_cast<std::size_t>(limit)); x++) {
|
||||
for (auto x = L; x <= R && (limit <= 0 || res.size() < limit); x++) {
|
||||
if (is_prime(x)) {
|
||||
res.push_back(x);
|
||||
}
|
||||
@ -38,24 +36,26 @@ static td::vector<td::uint64> gen_primes(td::uint64 L, td::uint64 R, int limit =
|
||||
return res;
|
||||
}
|
||||
|
||||
static td::vector<td::uint64> gen_primes() {
|
||||
static td::vector<td::uint64> gen_primes(int mode) {
|
||||
td::vector<td::uint64> result;
|
||||
td::append(result, gen_primes(1, 100));
|
||||
td::append(result, gen_primes((1ull << 31) - 500000, std::numeric_limits<td::uint64>::max(), 5));
|
||||
td::append(result, gen_primes((1ull << 32) - 500000, std::numeric_limits<td::uint64>::max(), 5));
|
||||
td::append(result, gen_primes((1ull << 39) - 500000, std::numeric_limits<td::uint64>::max(), 1));
|
||||
if (mode == 1) {
|
||||
for (size_t i = 10; i <= 19; i++) {
|
||||
td::append(result, gen_primes(i * 100000000, (i + 1) * 100000000, 1));
|
||||
}
|
||||
} else {
|
||||
td::append(result, gen_primes(1, 100));
|
||||
td::append(result, gen_primes((1ull << 31) - 500000, std::numeric_limits<td::uint64>::max(), 5));
|
||||
td::append(result, gen_primes((1ull << 32) - 500000, std::numeric_limits<td::uint64>::max(), 2));
|
||||
td::append(result, gen_primes((1ull << 39) - 500000, std::numeric_limits<td::uint64>::max(), 1));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
using PqQuery = std::pair<td::uint64, td::uint64>;
|
||||
|
||||
static bool cmp(const PqQuery &a, const PqQuery &b) {
|
||||
return a.first * a.second < b.first * b.second;
|
||||
}
|
||||
|
||||
static td::vector<PqQuery> gen_pq_queries() {
|
||||
static td::vector<PqQuery> gen_pq_queries(int mode = 0) {
|
||||
td::vector<PqQuery> res;
|
||||
auto primes = gen_primes();
|
||||
auto primes = gen_primes(mode);
|
||||
for (auto q : primes) {
|
||||
for (auto p : primes) {
|
||||
if (p > q) {
|
||||
@ -64,11 +64,38 @@ static td::vector<PqQuery> gen_pq_queries() {
|
||||
res.emplace_back(p, q);
|
||||
}
|
||||
}
|
||||
std::sort(res.begin(), res.end(), cmp);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void test_pq(td::uint64 first, td::uint64 second) {
|
||||
static td::string to_binary(td::uint64 x) {
|
||||
td::string result;
|
||||
do {
|
||||
result = static_cast<char>(x & 255) + result;
|
||||
x >>= 8;
|
||||
} while (x > 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void test_pq_fast(td::uint64 first, td::uint64 second) {
|
||||
if ((static_cast<td::uint64>(1) << 63) / first <= second) {
|
||||
return;
|
||||
}
|
||||
|
||||
td::string p_str;
|
||||
td::string q_str;
|
||||
int err = td::pq_factorize(to_binary(first * second), &p_str, &q_str);
|
||||
ASSERT_EQ(err, 0);
|
||||
|
||||
ASSERT_STREQ(p_str, to_binary(first));
|
||||
ASSERT_STREQ(q_str, to_binary(second));
|
||||
}
|
||||
|
||||
#if TD_HAVE_OPENSSL
|
||||
static void test_pq_slow(td::uint64 first, td::uint64 second) {
|
||||
if ((static_cast<td::uint64>(1) << 63) / first > second) {
|
||||
return;
|
||||
}
|
||||
|
||||
td::BigNum p = td::BigNum::from_decimal(PSLICE() << first).move_as_ok();
|
||||
td::BigNum q = td::BigNum::from_decimal(PSLICE() << second).move_as_ok();
|
||||
|
||||
@ -101,18 +128,35 @@ TEST(CryptoPQ, hands) {
|
||||
ASSERT_EQ(179424611ull, td::pq_factorize(179424611ull * 179424673ull));
|
||||
|
||||
#if TD_HAVE_OPENSSL
|
||||
test_pq(4294467311, 4294467449);
|
||||
test_pq_slow(4294467311, 4294467449);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(CryptoPQ, four) {
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
test_pq_fast(2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CryptoPQ, generated_fast) {
|
||||
auto queries = gen_pq_queries();
|
||||
for (const auto &query : queries) {
|
||||
test_pq_fast(query.first, query.second);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CryptoPQ, generated_server) {
|
||||
auto queries = gen_pq_queries(1);
|
||||
for (const auto &query : queries) {
|
||||
test_pq_fast(query.first, query.second);
|
||||
}
|
||||
}
|
||||
|
||||
#if TD_HAVE_OPENSSL
|
||||
TEST(CryptoPQ, generated_slow) {
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
test_pq(2, 2);
|
||||
}
|
||||
auto queries = gen_pq_queries();
|
||||
for (const auto &query : queries) {
|
||||
test_pq(query.first, query.second);
|
||||
test_pq_slow(query.first, query.second);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user