diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a174b2d2b..915c1572e 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -706,6 +706,7 @@ usernames active_usernames:vector disabled_usernames:vector edit //@emoji_status Emoji status to be shown instead of the default Telegram Premium badge; may be null. For Telegram Premium users only //@is_contact The user is a contact of the current user //@is_mutual_contact The user is a contact of the current user and the current user is a contact of the user +//@is_close_friend The user is a close friend of the current user; implies that the user is a contact //@is_verified True, if the user is verified //@is_premium True, if the user is a Telegram Premium user //@is_support True, if the user is Telegram support account @@ -716,7 +717,7 @@ usernames active_usernames:vector disabled_usernames:vector edit //@type Type of the user //@language_code IETF language tag of the user's language; only available to bots //@added_to_attachment_menu True, if the user added the current bot to attachment menu; only available to bots -user id:int53 first_name:string last_name:string usernames:usernames phone_number:string status:UserStatus profile_photo:profilePhoto emoji_status:emojiStatus is_contact:Bool is_mutual_contact:Bool is_verified:Bool is_premium:Bool is_support:Bool restriction_reason:string is_scam:Bool is_fake:Bool have_access:Bool type:UserType language_code:string added_to_attachment_menu:Bool = User; +user id:int53 first_name:string last_name:string usernames:usernames phone_number:string status:UserStatus profile_photo:profilePhoto emoji_status:emojiStatus is_contact:Bool is_mutual_contact:Bool is_close_friend:Bool is_verified:Bool is_premium:Bool is_support:Bool restriction_reason:string is_scam:Bool is_fake:Bool have_access:Bool type:UserType language_code:string added_to_attachment_menu:Bool = User; //@description Contains information about a bot diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 24d837152..7f224bc9a 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -4398,38 +4398,44 @@ void ContactsManager::User::store(StorerT &storer) const { bool has_restriction_reasons = !restriction_reasons.empty(); bool has_emoji_status = !emoji_status.is_empty(); bool has_usernames = !usernames.is_empty(); + bool has_flags2 = true; BEGIN_STORE_FLAGS(); STORE_FLAG(is_received); STORE_FLAG(is_verified); STORE_FLAG(is_deleted); STORE_FLAG(is_bot); STORE_FLAG(can_join_groups); - STORE_FLAG(can_read_all_group_messages); // 5 + STORE_FLAG(can_read_all_group_messages); STORE_FLAG(is_inline_bot); STORE_FLAG(need_location_bot); STORE_FLAG(has_last_name); STORE_FLAG(legacy_has_username); - STORE_FLAG(has_photo); // 10 - STORE_FLAG(false); // legacy is_restricted + STORE_FLAG(has_photo); + STORE_FLAG(false); // legacy is_restricted STORE_FLAG(has_language_code); STORE_FLAG(have_access_hash); STORE_FLAG(is_support); - STORE_FLAG(is_min_access_hash); // 15 + STORE_FLAG(is_min_access_hash); STORE_FLAG(is_scam); STORE_FLAG(has_cache_version); STORE_FLAG(has_is_contact); STORE_FLAG(is_contact); - STORE_FLAG(is_mutual_contact); // 20 + STORE_FLAG(is_mutual_contact); STORE_FLAG(has_restriction_reasons); STORE_FLAG(need_apply_min_photo); STORE_FLAG(is_fake); STORE_FLAG(can_be_added_to_attach_menu); - STORE_FLAG(is_premium); // 25 + STORE_FLAG(is_premium); STORE_FLAG(attach_menu_enabled); STORE_FLAG(has_emoji_status); STORE_FLAG(has_usernames); STORE_FLAG(can_be_edited_bot); END_STORE_FLAGS(); + if (has_flags2) { + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_close_friend); + END_STORE_FLAGS(); + } store(first_name, storer); if (has_last_name) { store(last_name, storer); @@ -4479,6 +4485,7 @@ void ContactsManager::User::parse(ParserT &parser) { bool has_restriction_reasons; bool has_emoji_status; bool has_usernames; + bool has_flags2 = parser.version() >= static_cast(Version::AddUserFlags2); BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_received); PARSE_FLAG(is_verified); @@ -4511,6 +4518,11 @@ void ContactsManager::User::parse(ParserT &parser) { PARSE_FLAG(has_usernames); PARSE_FLAG(can_be_edited_bot); END_PARSE_FLAGS(); + if (has_flags2) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_close_friend); + END_PARSE_FLAGS(); + } parse(first_name, parser); if (has_last_name) { parse(last_name, parser); @@ -4543,6 +4555,7 @@ void ContactsManager::User::parse(ParserT &parser) { is_contact = link_state_outbound == 3; is_mutual_contact = is_contact && link_state_inbound == 3; + is_close_friend = false; } parse(was_online, parser); if (legacy_is_restricted) { @@ -4592,6 +4605,11 @@ void ContactsManager::User::parse(ParserT &parser) { is_mutual_contact = false; cache_version = 0; } + if (!is_contact && is_close_friend) { + LOG(ERROR) << "Have invalid flag is_close_friend"; + is_close_friend = false; + cache_version = 0; + } } template @@ -6770,7 +6788,7 @@ void ContactsManager::on_update_contacts_reset() { if (user_id != my_id) { CHECK(contacts_hints_.has_key(user_id.get())); } - on_update_user_is_contact(u, user_id, false, false); + on_update_user_is_contact(u, user_id, false, false, false); CHECK(u->is_is_contact_changed); u->cache_version = 0; u->is_repaired = false; @@ -9840,7 +9858,7 @@ void ContactsManager::on_deleted_contacts(const vector &deleted_contact_ } LOG(INFO) << "Drop contact with " << user_id; - on_update_user_is_contact(u, user_id, false, false); + on_update_user_is_contact(u, user_id, false, false, false); CHECK(u->is_is_contact_changed); u->cache_version = 0; u->is_repaired = false; @@ -9896,7 +9914,7 @@ void ContactsManager::on_get_contacts(tl_object_ptris_is_contact_changed); u->cache_version = 0; u->is_repaired = false; @@ -10157,7 +10175,8 @@ void ContactsManager::on_get_user(tl_object_ptr &&user_ptr, on_update_user_online(u, user_id, std::move(user->status_)); auto is_mutual_contact = (flags & USER_FLAG_IS_MUTUAL_CONTACT) != 0; - on_update_user_is_contact(u, user_id, is_contact, is_mutual_contact); + auto is_close_friend = (flags2 & USER_FLAG_IS_CLOSE_FRIEND) != 0; + on_update_user_is_contact(u, user_id, is_contact, is_mutual_contact, is_close_friend); } if (is_received || !u->is_received) { @@ -13298,24 +13317,31 @@ void ContactsManager::on_update_user_emoji_status(User *u, UserId user_id, Emoji } } -void ContactsManager::on_update_user_is_contact(User *u, UserId user_id, bool is_contact, bool is_mutual_contact) { +void ContactsManager::on_update_user_is_contact(User *u, UserId user_id, bool is_contact, bool is_mutual_contact, + bool is_close_friend) { UserId my_id = get_my_id(); if (user_id == my_id) { is_mutual_contact = is_contact; + is_close_friend = false; } - if (!is_contact && is_mutual_contact) { - LOG(ERROR) << "Receive is_mutual_contact == true for non-contact " << user_id; + if (!is_contact && (is_mutual_contact || is_close_friend)) { + LOG(ERROR) << "Receive is_mutual_contact = " << is_mutual_contact << ", and is_close_friend = " << is_close_friend + << " for non-contact " << user_id; is_mutual_contact = false; + is_close_friend = false; } - if (u->is_contact != is_contact || u->is_mutual_contact != is_mutual_contact) { - LOG(DEBUG) << "Update " << user_id << " is_contact from (" << u->is_contact << ", " << u->is_mutual_contact - << ") to (" << is_contact << ", " << is_mutual_contact << ")"; + if (u->is_contact != is_contact || u->is_mutual_contact != is_mutual_contact || + u->is_close_friend != is_close_friend) { + LOG(DEBUG) << "Update " << user_id << " is_contact from (" << u->is_contact << ", " << u->is_mutual_contact << ", " + << u->is_close_friend << ") to (" << is_contact << ", " << is_mutual_contact << ", " + << u->is_close_friend << ")"; if (u->is_contact != is_contact) { u->is_is_contact_changed = true; } u->is_contact = is_contact; u->is_mutual_contact = is_mutual_contact; + u->is_close_friend = is_close_friend; u->is_changed = true; } } @@ -18601,8 +18627,8 @@ td_api::object_ptr ContactsManager::get_update_unknown_user_ auto have_access = user_id == get_my_id() || user_messages_.count(user_id) != 0; return td_api::make_object(td_api::make_object( user_id.get(), "", "", nullptr, "", td_api::make_object(), nullptr, nullptr, false, - false, false, false, false, "", false, false, have_access, td_api::make_object(), "", - false)); + false, false, false, false, false, "", false, false, have_access, td_api::make_object(), + "", false)); } int64 ContactsManager::get_user_id_object(UserId user_id, const char *source) const { @@ -18638,9 +18664,9 @@ tl_object_ptr ContactsManager::get_user_object(UserId user_id, con return make_tl_object( user_id.get(), u->first_name, u->last_name, u->usernames.get_usernames_object(), u->phone_number, get_user_status_object(user_id, u), get_profile_photo_object(td_->file_manager_.get(), u->photo), - std::move(emoji_status), u->is_contact, u->is_mutual_contact, u->is_verified, u->is_premium, u->is_support, - get_restriction_reason_description(u->restriction_reasons), u->is_scam, u->is_fake, have_access, std::move(type), - u->language_code, u->attach_menu_enabled); + std::move(emoji_status), u->is_contact, u->is_mutual_contact, u->is_close_friend, u->is_verified, u->is_premium, + u->is_support, get_restriction_reason_description(u->restriction_reasons), u->is_scam, u->is_fake, have_access, + std::move(type), u->language_code, u->attach_menu_enabled); } vector ContactsManager::get_user_ids_object(const vector &user_ids, const char *source) const { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index d6482b10d..8d58a932a 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -771,6 +771,7 @@ class ContactsManager final : public Actor { bool is_fake = false; bool is_contact = false; bool is_mutual_contact = false; + bool is_close_friend = false; bool need_apply_min_photo = false; bool can_be_added_to_attach_menu = false; bool attach_menu_enabled = false; @@ -1184,6 +1185,7 @@ class ContactsManager final : public Actor { static constexpr int32 USER_FLAG_HAS_EMOJI_STATUS = 1 << 30; static constexpr int32 USER_FLAG_HAS_USERNAMES = 1 << 0; static constexpr int32 USER_FLAG_CAN_BE_EDITED_BOT = 1 << 1; + static constexpr int32 USER_FLAG_IS_CLOSE_FRIEND = 1 << 2; static constexpr int32 USER_FULL_FLAG_IS_BLOCKED = 1 << 0; static constexpr int32 USER_FULL_FLAG_HAS_ABOUT = 1 << 1; @@ -1378,7 +1380,8 @@ class ContactsManager final : public Actor { void on_update_user_photo(User *u, UserId user_id, tl_object_ptr &&photo, const char *source); void on_update_user_emoji_status(User *u, UserId user_id, EmojiStatus emoji_status); - void on_update_user_is_contact(User *u, UserId user_id, bool is_contact, bool is_mutual_contact); + void on_update_user_is_contact(User *u, UserId user_id, bool is_contact, bool is_mutual_contact, + bool is_close_friend); void on_update_user_online(User *u, UserId user_id, tl_object_ptr &&status); void on_update_user_local_was_online(User *u, UserId user_id, int32 local_was_online); diff --git a/td/telegram/Version.h b/td/telegram/Version.h index 3e828fb1c..5daa82a44 100644 --- a/td/telegram/Version.h +++ b/td/telegram/Version.h @@ -61,6 +61,7 @@ enum class Version : int32 { AddMessageMediaSpoiler, // 45 MakeParticipantFlags64Bit, AddDocumentFlags, + AddUserFlags2, Next };