Add linked_chat_id support.

GitOrigin-RevId: 220feb41f7557dafc02bf0f04f43b8b15d50e2d9
This commit is contained in:
levlam 2019-09-13 04:11:21 +03:00
parent 1f22f9e0b7
commit 867c0f615b
4 changed files with 103 additions and 23 deletions

View File

@ -440,13 +440,14 @@ basicGroupFullInfo description:string creator_user_id:int32 members:vector<chatM
//@date Point in time (Unix timestamp) when the current user joined, or the point in time when the supergroup or channel was created, in case the user is not a member
//@status Status of the current user in the supergroup or channel
//@member_count Member count; 0 if unknown. Currently it is guaranteed to be known only if the supergroup or channel was found through SearchPublicChats
//@has_linked_chat True, if the channel has a discussion supergroup, or the supergroup is a discussion supergroup for a channel
//@sign_messages True, if messages sent to the channel should contain information about the sender. This field is only applicable to channels
//@is_channel True, if the supergroup is a channel
//@is_verified True, if the supergroup or channel is verified
//@restriction_reason If non-empty, contains the reason why access to this supergroup or channel must be restricted. Format of the string is "{type}: {description}".
//-{type} Contains the type of the restriction and at least one of the suffixes "-all", "-ios", "-android", or "-wp", which describe the platforms on which access should be restricted. (For example, "terms-ios-android". {description} contains a human-readable description of the restriction, which can be shown to the user)
//@is_scam True, if many users reported this supergroup as a scam
supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_count:int32 sign_messages:Bool is_channel:Bool is_verified:Bool restriction_reason:string is_scam:Bool = Supergroup;
supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_count:int32 has_linked_chat:Bool sign_messages:Bool is_channel:Bool is_verified:Bool restriction_reason:string is_scam:Bool = Supergroup;
//@description Contains full information about a supergroup or channel
//@param_description Supergroup or channel description
@ -454,6 +455,7 @@ supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_co
//@administrator_count Number of privileged users in the supergroup or channel; 0 if unknown
//@restricted_count Number of restricted users in the supergroup; 0 if unknown
//@banned_count Number of users banned from chat; 0 if unknown
//@linked_chat_id Chat identifier of a discussion supergroup for the channel, or a channel, for which the supergroup is a discussion supergroup; 0 if none
//@can_get_members True, if members of the chat can be retrieved
//@can_set_username True, if the chat can be made public
//@can_set_sticker_set True, if the supergroup sticker set can be changed
@ -463,7 +465,7 @@ supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_co
//@invite_link Invite link for this chat
//@upgraded_from_basic_group_id Identifier of the basic group from which supergroup was upgraded; 0 if none
//@upgraded_from_max_message_id Identifier of the last message in the basic group from which supergroup was upgraded; 0 if none
supergroupFullInfo description:string member_count:int32 administrator_count:int32 restricted_count:int32 banned_count:int32 can_get_members:Bool can_set_username:Bool can_set_sticker_set:Bool can_view_statistics:Bool is_all_history_available:Bool sticker_set_id:int64 invite_link:string upgraded_from_basic_group_id:int32 upgraded_from_max_message_id:int53 = SupergroupFullInfo;
supergroupFullInfo description:string member_count:int32 administrator_count:int32 restricted_count:int32 banned_count:int32 linked_chat_id:int53 can_get_members:Bool can_set_username:Bool can_set_sticker_set:Bool can_view_statistics:Bool is_all_history_available:Bool sticker_set_id:int64 invite_link:string upgraded_from_basic_group_id:int32 upgraded_from_max_message_id:int53 = SupergroupFullInfo;
//@class SecretChatState @description Describes the current secret chat state

Binary file not shown.

View File

@ -2686,6 +2686,7 @@ void ContactsManager::Channel::store(StorerT &storer) const {
STORE_FLAG(have_default_permissions);
STORE_FLAG(is_scam);
STORE_FLAG(has_cache_version);
STORE_FLAG(has_linked_channel);
END_STORE_FLAGS();
store(status, storer);
@ -2746,6 +2747,7 @@ void ContactsManager::Channel::parse(ParserT &parser) {
PARSE_FLAG(have_default_permissions);
PARSE_FLAG(is_scam);
PARSE_FLAG(has_cache_version);
PARSE_FLAG(has_linked_channel);
END_PARSE_FLAGS();
if (use_new_rights) {
@ -6570,6 +6572,9 @@ void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id) {
void ContactsManager::update_channel_full(ChannelFull *channel_full, ChannelId channel_id) {
CHECK(channel_full != nullptr);
if (channel_full->is_changed) {
if (channel_full->linked_channel_id.is_valid()) {
td_->messages_manager_->force_create_dialog(DialogId(channel_full->linked_channel_id), "update_channel_full");
}
if (channel_full->participant_count < channel_full->administrator_count) {
channel_full->administrator_count = channel_full->participant_count;
}
@ -6863,7 +6868,8 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
// Ignoring channel_full->photo
if (!have_channel(channel_id)) {
auto c = get_channel(channel_id);
if (c == nullptr) {
LOG(ERROR) << channel_id << " not found";
return;
}
@ -6907,15 +6913,12 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
channel->is_changed = true;
if (participant_count != 0) {
auto c = get_channel(channel_id);
if (c != nullptr && c->participant_count != participant_count) {
if (participant_count != 0 && c->participant_count != participant_count) {
c->participant_count = participant_count;
c->need_send_update = true;
update_channel(c, channel_id);
}
}
}
td_->messages_manager_->on_read_channel_outbox(channel_id,
MessageId(ServerMessageId(channel_full->read_outbox_max_id_)));
@ -6956,6 +6959,18 @@ void ContactsManager::on_get_chat_full(tl_object_ptr<telegram_api::ChatFull> &&c
on_update_bot_info(std::move(bot_info));
}
ChannelId linked_channel_id;
if ((channel_full->flags_ & CHANNEL_FULL_FLAG_HAS_LINKED_CHANNEL_ID) != 0) {
linked_channel_id = ChannelId(channel_full->linked_chat_id_);
auto linked_channel = get_channel_force(linked_channel_id);
if (linked_channel == nullptr || c->is_megagroup == linked_channel->is_megagroup ||
channel_id == linked_channel_id) {
LOG(ERROR) << "Failed to add a link between " << channel_id << " and " << linked_channel_id;
linked_channel_id = ChannelId();
}
}
on_update_channel_full_linked_channel_id(channel, channel_id, linked_channel_id);
ChatId migrated_from_chat_id;
MessageId migrated_from_max_message_id;
@ -8060,6 +8075,55 @@ void ContactsManager::on_update_channel_full_invite_link(
}
}
void ContactsManager::on_update_channel_full_linked_channel_id(ChannelFull *channel_full, ChannelId channel_id,
ChannelId linked_channel_id) {
CHECK(channel_full != nullptr);
if (channel_full->linked_channel_id != linked_channel_id) {
if (channel_full->linked_channel_id.is_valid()) {
// remove link from a previously linked channel_full
auto linked_channel = get_channel_force(channel_full->linked_channel_id);
if (linked_channel != nullptr && linked_channel->has_linked_channel) {
linked_channel->has_linked_channel = false;
update_channel(linked_channel, channel_full->linked_channel_id);
reload_channel(channel_full->linked_channel_id, Auto());
}
auto linked_channel_full = get_channel_full(channel_full->linked_channel_id);
if (linked_channel_full != nullptr && linked_channel_full->linked_channel_id == channel_id) {
linked_channel_full->linked_channel_id = ChannelId();
linked_channel_full->is_changed = true;
update_channel_full(linked_channel_full, channel_full->linked_channel_id);
}
}
channel_full->linked_channel_id = linked_channel_id;
channel_full->is_changed = true;
if (channel_full->linked_channel_id.is_valid()) {
// add link from a newly linked channel_full
auto linked_channel = get_channel_force(channel_full->linked_channel_id);
if (linked_channel != nullptr && !linked_channel->has_linked_channel) {
linked_channel->has_linked_channel = true;
update_channel(linked_channel, channel_full->linked_channel_id);
reload_channel(channel_full->linked_channel_id, Auto());
}
auto linked_channel_full = get_channel_full(channel_full->linked_channel_id);
if (linked_channel_full != nullptr && linked_channel_full->linked_channel_id != channel_id) {
linked_channel_full->linked_channel_id = channel_id;
linked_channel_full->is_changed = true;
update_channel_full(linked_channel_full, channel_full->linked_channel_id);
}
}
}
Channel *c = get_channel(channel_id);
CHECK(c != nullptr);
if (linked_channel_id.is_valid() != c->has_linked_channel) {
c->has_linked_channel = linked_channel_id.is_valid();
c->need_send_update = true;
update_channel(c, channel_id);
}
}
void ContactsManager::on_get_dialog_invite_link_info(const string &invite_link,
tl_object_ptr<telegram_api::ChatInvite> &&chat_invite_ptr) {
auto &invite_link_info = invite_link_infos_[invite_link];
@ -10244,6 +10308,7 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
bool has_access_hash = (channel.flags_ & CHANNEL_FLAG_HAS_ACCESS_HASH) != 0;
auto access_hash = has_access_hash ? channel.access_hash_ : 0;
bool has_linked_channel = (channel.flags_ & CHANNEL_FLAG_HAS_LINKED_CHAT) != 0;
bool sign_messages = (channel.flags_ & CHANNEL_FLAG_SIGN_MESSAGES) != 0;
bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0;
bool is_verified = (channel.flags_ & CHANNEL_FLAG_IS_VERIFIED) != 0;
@ -10335,8 +10400,10 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
c->need_send_update = true;
}
if (c->sign_messages != sign_messages || c->is_megagroup != is_megagroup || c->is_verified != is_verified ||
c->restriction_reason != restriction_reason || c->is_scam != is_scam) {
if (c->has_linked_channel != has_linked_channel || c->sign_messages != sign_messages ||
c->is_megagroup != is_megagroup || c->is_verified != is_verified || c->restriction_reason != restriction_reason ||
c->is_scam != is_scam) {
c->has_linked_channel = has_linked_channel;
c->sign_messages = sign_messages;
c->is_megagroup = is_megagroup;
c->is_verified = is_verified;
@ -10391,6 +10458,7 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co
tl_object_ptr<telegram_api::chatBannedRights> banned_rights; // == nullptr
on_update_channel_default_permissions(c, channel_id, get_restricted_rights(banned_rights));
bool has_linked_channel = false;
bool sign_messages = false;
bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0;
bool is_verified = false;
@ -10413,8 +10481,10 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co
c->need_send_update = true;
}
if (c->sign_messages != sign_messages || c->is_megagroup != is_megagroup || c->is_verified != is_verified ||
c->restriction_reason != restriction_reason || c->is_scam != is_scam) {
if (c->has_linked_channel != has_linked_channel || c->sign_messages != sign_messages ||
c->is_megagroup != is_megagroup || c->is_verified != is_verified || c->restriction_reason != restriction_reason ||
c->is_scam != is_scam) {
c->has_linked_channel = has_linked_channel;
c->sign_messages = sign_messages;
c->is_megagroup = is_megagroup;
c->is_verified = is_verified;
@ -10617,7 +10687,7 @@ int32 ContactsManager::get_supergroup_id_object(ChannelId channel_id, const char
send_closure(G()->td(), &Td::send_update,
td_api::make_object<td_api::updateSupergroup>(td_api::make_object<td_api::supergroup>(
channel_id.get(), string(), 0, DialogParticipantStatus::Banned(0).get_chat_member_status_object(),
0, false, true, false, "", false)));
0, false, false, true, false, "", false)));
}
return channel_id.get();
}
@ -10631,9 +10701,9 @@ tl_object_ptr<td_api::supergroup> ContactsManager::get_supergroup_object(Channel
if (channel == nullptr) {
return nullptr;
}
return make_tl_object<td_api::supergroup>(channel_id.get(), channel->username, channel->date,
get_channel_status(channel).get_chat_member_status_object(),
channel->participant_count, channel->sign_messages, !channel->is_megagroup,
return make_tl_object<td_api::supergroup>(
channel_id.get(), channel->username, channel->date, get_channel_status(channel).get_chat_member_status_object(),
channel->participant_count, channel->has_linked_channel, channel->sign_messages, !channel->is_megagroup,
channel->is_verified, channel->restriction_reason, channel->is_scam);
}
@ -10646,9 +10716,10 @@ tl_object_ptr<td_api::supergroupFullInfo> ContactsManager::get_supergroup_full_i
CHECK(channel_full != nullptr);
return make_tl_object<td_api::supergroupFullInfo>(
channel_full->description, channel_full->participant_count, channel_full->administrator_count,
channel_full->restricted_count, channel_full->banned_count, channel_full->can_get_participants,
channel_full->can_set_username, channel_full->can_set_sticker_set, channel_full->can_view_statistics,
channel_full->is_all_history_available, channel_full->sticker_set_id, channel_full->invite_link,
channel_full->restricted_count, channel_full->banned_count, DialogId(channel_full->linked_channel_id).get(),
channel_full->can_get_participants, channel_full->can_set_username, channel_full->can_set_sticker_set,
channel_full->can_view_statistics, channel_full->is_all_history_available, channel_full->sticker_set_id,
channel_full->invite_link,
get_basic_group_id_object(channel_full->migrated_from_chat_id, "get_supergroup_full_info_object"),
channel_full->migrated_from_max_message_id.get());
}

View File

@ -638,9 +638,10 @@ class ContactsManager : public Actor {
int32 date = 0;
int32 participant_count = 0;
static constexpr uint32 CACHE_VERSION = 1;
static constexpr uint32 CACHE_VERSION = 2;
uint32 cache_version = 0;
bool has_linked_channel = false;
bool sign_messages = false;
bool is_megagroup = false;
@ -680,6 +681,8 @@ class ContactsManager : public Actor {
int64 sticker_set_id = 0; // do not forget to store along with access hash
ChannelId linked_channel_id;
MessageId migrated_from_max_message_id;
ChatId migrated_from_chat_id;
@ -805,6 +808,7 @@ class ContactsManager : public Actor {
static constexpr int32 CHANNEL_FLAG_HAS_UNBAN_DATE = 1 << 16;
static constexpr int32 CHANNEL_FLAG_HAS_PARTICIPANT_COUNT = 1 << 17;
static constexpr int32 CHANNEL_FLAG_IS_SCAM = 1 << 19;
static constexpr int32 CHANNEL_FLAG_HAS_LINKED_CHAT = 1 << 20;
static constexpr int32 CHANNEL_FULL_FLAG_HAS_PARTICIPANT_COUNT = 1 << 0;
static constexpr int32 CHANNEL_FULL_FLAG_HAS_ADMINISTRATOR_COUNT = 1 << 1;
@ -820,6 +824,7 @@ class ContactsManager : public Actor {
static constexpr int32 CHANNEL_FULL_FLAG_HAS_FOLDER_ID = 1 << 11;
static constexpr int32 CHANNEL_FULL_FLAG_CAN_VIEW_STATISTICS = 1 << 12;
static constexpr int32 CHANNEL_FULL_FLAG_HAS_ONLINE_MEMBER_COUNT = 1 << 13;
static constexpr int32 CHANNEL_FULL_FLAG_HAS_LINKED_CHANNEL_ID = 1 << 13;
static constexpr int32 CHAT_INVITE_FLAG_IS_CHANNEL = 1 << 0;
static constexpr int32 CHAT_INVITE_FLAG_IS_BROADCAST = 1 << 1;
@ -942,6 +947,8 @@ class ContactsManager : public Actor {
void on_update_channel_full_invite_link(ChannelFull *channel_full,
tl_object_ptr<telegram_api::ExportedChatInvite> &&invite_link_ptr);
void on_update_channel_full_linked_channel_id(ChannelFull *channel_full, ChannelId channel_id,
ChannelId linked_channel_id);
static bool speculative_add_count(int32 &count, int32 new_count);