Merge remote-tracking branch 'td/master'

This commit is contained in:
Andrea Cavalli 2021-04-10 19:44:10 +02:00
commit 799d106c49
24 changed files with 511 additions and 364 deletions

View File

@ -243,7 +243,7 @@ int64 CallbackQueriesManager::send_callback_query(FullMessageId full_message_id,
} }
auto dialog_id = full_message_id.get_dialog_id(); auto dialog_id = full_message_id.get_dialog_id();
td_->messages_manager_->have_dialog_force(dialog_id); td_->messages_manager_->have_dialog_force(dialog_id, "send_callback_query");
if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) {
promise.set_error(Status::Error(5, "Can't access the chat")); promise.set_error(Status::Error(5, "Can't access the chat"));
return 0; return 0;

View File

@ -6365,7 +6365,7 @@ void ContactsManager::set_channel_discussion_group(DialogId dialog_id, DialogId
ChannelId broadcast_channel_id; ChannelId broadcast_channel_id;
telegram_api::object_ptr<telegram_api::InputChannel> broadcast_input_channel; telegram_api::object_ptr<telegram_api::InputChannel> broadcast_input_channel;
if (dialog_id.is_valid()) { if (dialog_id.is_valid()) {
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_channel_discussion_group 1")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
@ -6395,7 +6395,7 @@ void ContactsManager::set_channel_discussion_group(DialogId dialog_id, DialogId
ChannelId group_channel_id; ChannelId group_channel_id;
telegram_api::object_ptr<telegram_api::InputChannel> group_input_channel; telegram_api::object_ptr<telegram_api::InputChannel> group_input_channel;
if (discussion_dialog_id.is_valid()) { if (discussion_dialog_id.is_valid()) {
if (!td_->messages_manager_->have_dialog_force(discussion_dialog_id)) { if (!td_->messages_manager_->have_dialog_force(discussion_dialog_id, "set_channel_discussion_group 2")) {
return promise.set_error(Status::Error(400, "Discussion chat not found")); return promise.set_error(Status::Error(400, "Discussion chat not found"));
} }
if (discussion_dialog_id.get_type() != DialogType::Channel) { if (discussion_dialog_id.get_type() != DialogType::Channel) {
@ -6435,7 +6435,7 @@ void ContactsManager::set_channel_location(DialogId dialog_id, const DialogLocat
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_channel_location")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
@ -6467,7 +6467,7 @@ void ContactsManager::set_channel_slow_mode_delay(DialogId dialog_id, int32 slow
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_channel_slow_mode_delay")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
@ -6495,7 +6495,7 @@ void ContactsManager::get_channel_statistics_dc_id(DialogId dialog_id, bool for_
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_channel_statistics_dc_id")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
@ -6716,7 +6716,7 @@ void ContactsManager::delete_channel(ChannelId channel_id, Promise<Unit> &&promi
} }
void ContactsManager::delete_dialog(DialogId dialog_id, Promise<Unit> &&promise) { void ContactsManager::delete_dialog(DialogId dialog_id, Promise<Unit> &&promise) {
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "delete_dialog")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
@ -7074,7 +7074,7 @@ td_api::object_ptr<td_api::CanTransferOwnershipResult> ContactsManager::get_can_
void ContactsManager::transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password, void ContactsManager::transfer_dialog_ownership(DialogId dialog_id, UserId user_id, const string &password,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "transfer_dialog_ownership")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
if (!have_user_force(user_id)) { if (!have_user_force(user_id)) {
@ -7126,7 +7126,7 @@ void ContactsManager::transfer_channel_ownership(
} }
Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool creator_only) { Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool creator_only) {
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "can_manage_dialog_invite_links")) {
return Status::Error(3, "Chat not found"); return Status::Error(3, "Chat not found");
} }
@ -7866,7 +7866,7 @@ void ContactsManager::on_load_contacts_from_database(string value) {
} }
void ContactsManager::on_get_contacts_finished(size_t expected_contact_count) { void ContactsManager::on_get_contacts_finished(size_t expected_contact_count) {
LOG(INFO) << "Finished to get " << contacts_hints_.size() << " contacts out of " << expected_contact_count; LOG(INFO) << "Finished to get " << contacts_hints_.size() << " contacts out of expected " << expected_contact_count;
are_contacts_loaded_ = true; are_contacts_loaded_ = true;
auto promises = std::move(load_contacts_queries_); auto promises = std::move(load_contacts_queries_);
load_contacts_queries_.clear(); load_contacts_queries_.clear();
@ -9236,7 +9236,11 @@ void ContactsManager::on_load_user_full_from_database(UserId user_id, string val
Dependencies dependencies; Dependencies dependencies;
dependencies.user_ids.insert(user_id); dependencies.user_ids.insert(user_id);
resolve_dependencies_force(td_, dependencies, "user_full"); if (!resolve_dependencies_force(td_, dependencies, "user_full")) {
users_full_.erase(user_id);
G()->td_db()->get_sqlite_pmc()->erase(get_user_full_database_key(user_id), Auto());
return;
}
if (user_full->need_phone_number_privacy_exception && is_user_contact(user_id)) { if (user_full->need_phone_number_privacy_exception && is_user_contact(user_id)) {
user_full->need_phone_number_privacy_exception = false; user_full->need_phone_number_privacy_exception = false;
@ -9423,7 +9427,11 @@ void ContactsManager::on_load_chat_full_from_database(ChatId chat_id, string val
dependencies.user_ids.insert(participant.inviter_user_id); dependencies.user_ids.insert(participant.inviter_user_id);
} }
dependencies.user_ids.insert(chat_full->invite_link.get_creator_user_id()); dependencies.user_ids.insert(chat_full->invite_link.get_creator_user_id());
resolve_dependencies_force(td_, dependencies, "chat_full"); if (!resolve_dependencies_force(td_, dependencies, "chat_full")) {
chats_full_.erase(chat_id);
G()->td_db()->get_sqlite_pmc()->erase(get_chat_full_database_key(chat_id), Auto());
return;
}
for (auto &participant : chat_full->participants) { for (auto &participant : chat_full->participants) {
get_bot_info_force(participant.user_id); get_bot_info_force(participant.user_id);
@ -9527,7 +9535,11 @@ void ContactsManager::on_load_channel_full_from_database(ChannelId channel_id, s
dependencies.chat_ids.insert(channel_full->migrated_from_chat_id); dependencies.chat_ids.insert(channel_full->migrated_from_chat_id);
dependencies.user_ids.insert(channel_full->bot_user_ids.begin(), channel_full->bot_user_ids.end()); dependencies.user_ids.insert(channel_full->bot_user_ids.begin(), channel_full->bot_user_ids.end());
dependencies.user_ids.insert(channel_full->invite_link.get_creator_user_id()); dependencies.user_ids.insert(channel_full->invite_link.get_creator_user_id());
resolve_dependencies_force(td_, dependencies, "channel_full"); if (!resolve_dependencies_force(td_, dependencies, "channel_full")) {
channels_full_.erase(channel_id);
G()->td_db()->get_sqlite_pmc()->erase(get_channel_full_database_key(channel_id), Auto());
return;
}
for (auto &user_id : channel_full->bot_user_ids) { for (auto &user_id : channel_full->bot_user_ids) {
get_bot_info_force(user_id); get_bot_info_force(user_id);
@ -14384,7 +14396,7 @@ std::pair<int32, vector<UserId>> ContactsManager::search_among_users(const vecto
void ContactsManager::add_dialog_participant(DialogId dialog_id, UserId user_id, int32 forward_limit, void ContactsManager::add_dialog_participant(DialogId dialog_id, UserId user_id, int32 forward_limit,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "add_dialog_participant")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
@ -14409,7 +14421,7 @@ void ContactsManager::add_dialog_participants(DialogId dialog_id, const vector<U
return promise.set_error(Status::Error(3, "Method is not available for bots")); return promise.set_error(Status::Error(3, "Method is not available for bots"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "add_dialog_participants")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
@ -14432,7 +14444,7 @@ void ContactsManager::set_dialog_participant_status(DialogId dialog_id, UserId u
const tl_object_ptr<td_api::ChatMemberStatus> &chat_member_status, const tl_object_ptr<td_api::ChatMemberStatus> &chat_member_status,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
auto status = get_dialog_participant_status(chat_member_status); auto status = get_dialog_participant_status(chat_member_status);
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_dialog_participant_status")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
@ -14453,7 +14465,7 @@ void ContactsManager::set_dialog_participant_status(DialogId dialog_id, UserId u
void ContactsManager::ban_dialog_participant(DialogId dialog_id, UserId user_id, int32 banned_until_date, void ContactsManager::ban_dialog_participant(DialogId dialog_id, UserId user_id, int32 banned_until_date,
bool revoke_messages, Promise<Unit> &&promise) { bool revoke_messages, Promise<Unit> &&promise) {
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "ban_dialog_participant")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
@ -14477,7 +14489,7 @@ DialogParticipant ContactsManager::get_dialog_participant(DialogId dialog_id, Us
bool force, Promise<Unit> &&promise) { bool force, Promise<Unit> &&promise) {
LOG(INFO) << "Receive GetChatMember request to get " << user_id << " in " << dialog_id << " with random_id " LOG(INFO) << "Receive GetChatMember request to get " << user_id << " in " << dialog_id << " with random_id "
<< random_id; << random_id;
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_dialog_participant")) {
promise.set_error(Status::Error(3, "Chat not found")); promise.set_error(Status::Error(3, "Chat not found"));
return DialogParticipant(); return DialogParticipant();
} }
@ -14571,7 +14583,7 @@ void ContactsManager::search_dialog_participants(DialogId dialog_id, const strin
Promise<DialogParticipants> &&promise) { Promise<DialogParticipants> &&promise) {
LOG(INFO) << "Receive searchChatMembers request to search for \"" << query << "\" in " << dialog_id << " with filter " LOG(INFO) << "Receive searchChatMembers request to search for \"" << query << "\" in " << dialog_id << " with filter "
<< filter; << filter;
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "search_dialog_participants")) {
return promise.set_error(Status::Error(3, "Chat not found")); return promise.set_error(Status::Error(3, "Chat not found"));
} }
if (limit < 0) { if (limit < 0) {
@ -14861,7 +14873,7 @@ void ContactsManager::do_get_channel_participants(ChannelId channel_id, ChannelP
vector<DialogAdministrator> ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries, vector<DialogAdministrator> ContactsManager::get_dialog_administrators(DialogId dialog_id, int left_tries,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
LOG(INFO) << "Receive GetChatAdministrators request in " << dialog_id << " with " << left_tries << " left tries"; LOG(INFO) << "Receive GetChatAdministrators request in " << dialog_id << " with " << left_tries << " left tries";
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_dialog_administrators")) {
promise.set_error(Status::Error(3, "Chat not found")); promise.set_error(Status::Error(3, "Chat not found"));
return {}; return {};
} }

View File

@ -51,38 +51,46 @@ void add_message_sender_dependencies(Dependencies &dependencies, DialogId dialog
} }
} }
void resolve_dependencies_force(Td *td, const Dependencies &dependencies, const char *source) { bool resolve_dependencies_force(Td *td, const Dependencies &dependencies, const char *source) {
bool success = true;
for (auto user_id : dependencies.user_ids) { for (auto user_id : dependencies.user_ids) {
if (user_id.is_valid() && !td->contacts_manager_->have_user_force(user_id)) { if (user_id.is_valid() && !td->contacts_manager_->have_user_force(user_id)) {
LOG(ERROR) << "Can't find " << user_id << " from " << source; LOG(ERROR) << "Can't find " << user_id << " from " << source;
success = false;
} }
} }
for (auto chat_id : dependencies.chat_ids) { for (auto chat_id : dependencies.chat_ids) {
if (chat_id.is_valid() && !td->contacts_manager_->have_chat_force(chat_id)) { if (chat_id.is_valid() && !td->contacts_manager_->have_chat_force(chat_id)) {
LOG(ERROR) << "Can't find " << chat_id << " from " << source; LOG(ERROR) << "Can't find " << chat_id << " from " << source;
success = false;
} }
} }
for (auto channel_id : dependencies.channel_ids) { for (auto channel_id : dependencies.channel_ids) {
if (channel_id.is_valid() && !td->contacts_manager_->have_channel_force(channel_id)) { if (channel_id.is_valid() && !td->contacts_manager_->have_channel_force(channel_id)) {
LOG(ERROR) << "Can't find " << channel_id << " from " << source; LOG(ERROR) << "Can't find " << channel_id << " from " << source;
success = false;
} }
} }
for (auto secret_chat_id : dependencies.secret_chat_ids) { for (auto secret_chat_id : dependencies.secret_chat_ids) {
if (secret_chat_id.is_valid() && !td->contacts_manager_->have_secret_chat_force(secret_chat_id)) { if (secret_chat_id.is_valid() && !td->contacts_manager_->have_secret_chat_force(secret_chat_id)) {
LOG(ERROR) << "Can't find " << secret_chat_id << " from " << source; LOG(ERROR) << "Can't find " << secret_chat_id << " from " << source;
success = false;
} }
} }
for (auto dialog_id : dependencies.dialog_ids) { for (auto dialog_id : dependencies.dialog_ids) {
if (dialog_id.is_valid() && !td->messages_manager_->have_dialog_force(dialog_id)) { if (dialog_id.is_valid() && !td->messages_manager_->have_dialog_force(dialog_id, source)) {
LOG(ERROR) << "Can't find " << dialog_id << " from " << source; LOG(ERROR) << "Can't find " << dialog_id << " from " << source;
td->messages_manager_->force_create_dialog(dialog_id, "resolve_dependencies_force"); td->messages_manager_->force_create_dialog(dialog_id, "resolve_dependencies_force", true);
success = false;
} }
} }
for (auto web_page_id : dependencies.web_page_ids) { for (auto web_page_id : dependencies.web_page_ids) {
if (web_page_id.is_valid()) { if (web_page_id.is_valid()) {
td->web_pages_manager_->have_web_page_force(web_page_id); td->web_pages_manager_->have_web_page_force(web_page_id);
success = false;
} }
} }
return success;
} }
} // namespace td } // namespace td

View File

@ -34,6 +34,6 @@ void add_dialog_dependencies(Dependencies &dependencies, DialogId dialog_id);
void add_message_sender_dependencies(Dependencies &dependencies, DialogId dialog_id); void add_message_sender_dependencies(Dependencies &dependencies, DialogId dialog_id);
void resolve_dependencies_force(Td *td, const Dependencies &dependencies, const char *source); bool resolve_dependencies_force(Td *td, const Dependencies &dependencies, const char *source);
} // namespace td } // namespace td

View File

@ -790,7 +790,8 @@ void GroupCallManager::on_update_group_call_participant_order_timeout(GroupCallI
auto new_order = get_real_participant_order(can_manage, participant, participants); auto new_order = get_real_participant_order(can_manage, participant, participants);
if (new_order != participant.order) { if (new_order != participant.order) {
participant.order = new_order; participant.order = new_order;
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant,
"on_update_group_call_participant_order_timeout");
} }
} }
update_group_call_participant_order_timeout_.set_timeout_in(group_call_id.get(), update_group_call_participant_order_timeout_.set_timeout_in(group_call_id.get(),
@ -932,7 +933,7 @@ DialogId GroupCallManager::get_group_call_participant_id(
} }
case td_api::messageSenderChat::ID: { case td_api::messageSenderChat::ID: {
DialogId dialog_id(static_cast<const td_api::messageSenderChat *>(message_sender.get())->chat_id_); DialogId dialog_id(static_cast<const td_api::messageSenderChat *>(message_sender.get())->chat_id_);
if (td_->messages_manager_->have_dialog_force(dialog_id)) { if (td_->messages_manager_->have_dialog_force(dialog_id, "get_group_call_participant_id")) {
return dialog_id; return dialog_id;
} }
break; break;
@ -1061,7 +1062,7 @@ void GroupCallManager::get_group_call_join_as(DialogId dialog_id,
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_group_call_join_as")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) {
@ -1075,7 +1076,7 @@ void GroupCallManager::create_voice_chat(DialogId dialog_id, Promise<GroupCallId
if (!dialog_id.is_valid()) { if (!dialog_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); return promise.set_error(Status::Error(400, "Invalid chat identifier specified"));
} }
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "create_voice_chat")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) {
@ -1355,6 +1356,9 @@ void GroupCallManager::on_get_group_call_participants(
} }
auto real_participant_count = participants->count_; auto real_participant_count = participants->count_;
if (!group_call->is_joined) {
real_participant_count++;
}
if (is_empty) { if (is_empty) {
auto known_participant_count = participants_it != group_call_participants_.end() auto known_participant_count = participants_it != group_call_participants_.end()
? static_cast<int32>(participants_it->second->participants.size()) ? static_cast<int32>(participants_it->second->participants.size())
@ -1584,6 +1588,7 @@ bool GroupCallManager::process_pending_group_call_participant_updates(InputGroup
} }
}; };
bool need_update = false;
while (!pending_version_updates.empty()) { while (!pending_version_updates.empty()) {
process_mute_updates(); process_mute_updates();
@ -1618,11 +1623,13 @@ bool GroupCallManager::process_pending_group_call_participant_updates(InputGroup
diff += process_group_call_participant(input_group_call_id, std::move(participant)); diff += process_group_call_participant(input_group_call_id, std::move(participant));
} }
pending_version_updates.erase(it); pending_version_updates.erase(it);
} else if (!group_call->syncing_participants) { } else {
// found a gap // found a gap
LOG(INFO) << "Receive " << participants.size() << " group call participant updates with version " << version if (!group_call->syncing_participants) {
<< ", but current version is " << group_call->version; LOG(INFO) << "Receive " << participants.size() << " group call participant updates with version " << version
sync_participants_timeout_.add_timeout_in(group_call->group_call_id.get(), 1.0); << ", but current version is " << group_call->version;
sync_participants_timeout_.add_timeout_in(group_call->group_call_id.get(), 1.0);
}
break; break;
} }
} }
@ -1637,10 +1644,10 @@ bool GroupCallManager::process_pending_group_call_participant_updates(InputGroup
sync_participants_timeout_.cancel_timeout(group_call->group_call_id.get()); sync_participants_timeout_.cancel_timeout(group_call->group_call_id.get());
} }
bool need_update = set_group_call_participant_count(group_call, group_call->participant_count + diff, need_update |= set_group_call_participant_count(group_call, group_call->participant_count + diff,
"process_pending_group_call_participant_updates"); "process_pending_group_call_participant_updates");
if (is_left && group_call->is_joined) { if (is_left && group_call->is_joined) {
on_group_call_left_impl(group_call, need_rejoin); on_group_call_left_impl(group_call, need_rejoin, "process_pending_group_call_participant_updates");
need_update = true; need_update = true;
} }
if (need_update) { if (need_update) {
@ -1706,13 +1713,19 @@ GroupCallParticipantOrder GroupCallManager::get_real_participant_order(
if (participant.is_self) { if (participant.is_self) {
return participants->min_order; return participants->min_order;
} }
if (real_order.is_valid()) {
LOG(DEBUG) << "Order " << real_order << " of " << participant.dialog_id << " is less than last known order "
<< participants->min_order;
}
return GroupCallParticipantOrder(); return GroupCallParticipantOrder();
} }
void GroupCallManager::process_group_call_participants( void GroupCallManager::process_group_call_participants(
InputGroupCallId input_group_call_id, vector<tl_object_ptr<telegram_api::groupCallParticipant>> &&participants, InputGroupCallId input_group_call_id, vector<tl_object_ptr<telegram_api::groupCallParticipant>> &&participants,
int32 version, const string &offset, bool is_load, bool is_sync) { int32 version, const string &offset, bool is_load, bool is_sync) {
if (offset.empty() && is_load && !participants.empty() && participants[0]->self_) { // if receive exactly one participant, then the current user is the only participant
// there are no reasons to process it independently
if (offset.empty() && is_load && participants.size() >= 2 && participants[0]->self_) {
GroupCallParticipant participant(participants[0], version); GroupCallParticipant participant(participants[0], version);
if (participant.is_valid()) { if (participant.is_valid()) {
process_my_group_call_participant(input_group_call_id, std::move(participant)); process_my_group_call_participant(input_group_call_id, std::move(participant));
@ -1787,7 +1800,6 @@ void GroupCallManager::process_group_call_participants(
for (auto participant_it = group_participants.begin(); participant_it != group_participants.end();) { for (auto participant_it = group_participants.begin(); participant_it != group_participants.end();) {
auto &participant = *participant_it; auto &participant = *participant_it;
if (old_participant_dialog_ids.count(participant.dialog_id) == 0) { if (old_participant_dialog_ids.count(participant.dialog_id) == 0) {
CHECK(!participant.order.is_valid() || participant.order >= min_order);
++participant_it; ++participant_it;
continue; continue;
} }
@ -1795,7 +1807,8 @@ void GroupCallManager::process_group_call_participants(
if (participant.is_self) { if (participant.is_self) {
if (participant.order != min_order) { if (participant.order != min_order) {
participant.order = min_order; participant.order = min_order;
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant,
"process_group_call_participants self");
} }
++participant_it; ++participant_it;
continue; continue;
@ -1805,7 +1818,7 @@ void GroupCallManager::process_group_call_participants(
if (participant.order.is_valid()) { if (participant.order.is_valid()) {
CHECK(participant.order >= participants_it->second->min_order); CHECK(participant.order >= participants_it->second->min_order);
participant.order = GroupCallParticipantOrder(); participant.order = GroupCallParticipantOrder();
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant, "process_group_call_participants sync");
} }
on_remove_group_call_participant(input_group_call_id, participant.dialog_id); on_remove_group_call_participant(input_group_call_id, participant.dialog_id);
participant_it = group_participants.erase(participant_it); participant_it = group_participants.erase(participant_it);
@ -1829,7 +1842,8 @@ void GroupCallManager::process_group_call_participants(
if (old_min_order > real_order && real_order >= min_order) { if (old_min_order > real_order && real_order >= min_order) {
CHECK(!participant.order.is_valid() || participant.is_self); CHECK(!participant.order.is_valid() || participant.is_self);
participant.order = real_order; participant.order = real_order;
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant,
"process_group_call_participants load");
} }
} }
@ -1858,7 +1872,8 @@ void GroupCallManager::update_group_call_participants_can_be_muted(InputGroupCal
for (auto &participant : participants->participants) { for (auto &participant : participants->participants) {
if (update_group_call_participant_can_be_muted(can_manage, participants, participant) && if (update_group_call_participant_can_be_muted(can_manage, participants, participant) &&
participant.order.is_valid()) { participant.order.is_valid()) {
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant,
"update_group_call_participants_can_be_muted");
} }
} }
} }
@ -1900,7 +1915,7 @@ int GroupCallManager::process_group_call_participant(InputGroupCallId input_grou
auto can_self_unmute = !participant.get_is_muted_by_admin(); auto can_self_unmute = !participant.get_is_muted_by_admin();
if (can_self_unmute != group_call->can_self_unmute) { if (can_self_unmute != group_call->can_self_unmute) {
group_call->can_self_unmute = can_self_unmute; group_call->can_self_unmute = can_self_unmute;
send_update_group_call(group_call, "process_group_call_participant"); send_update_group_call(group_call, "process_group_call_participant 1");
} }
} }
} }
@ -1913,7 +1928,7 @@ int GroupCallManager::process_group_call_participant(InputGroupCallId input_grou
if (participant.joined_date == 0) { if (participant.joined_date == 0) {
LOG(INFO) << "Remove " << old_participant; LOG(INFO) << "Remove " << old_participant;
if (old_participant.order.is_valid()) { if (old_participant.order.is_valid()) {
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant, "process_group_call_participant remove");
} }
on_remove_group_call_participant(input_group_call_id, old_participant.dialog_id); on_remove_group_call_participant(input_group_call_id, old_participant.dialog_id);
remove_recent_group_call_speaker(input_group_call_id, old_participant.dialog_id); remove_recent_group_call_speaker(input_group_call_id, old_participant.dialog_id);
@ -1939,7 +1954,7 @@ int GroupCallManager::process_group_call_participant(InputGroupCallId input_grou
LOG(INFO) << "Edit " << old_participant << " to " << participant; LOG(INFO) << "Edit " << old_participant << " to " << participant;
if (old_participant != participant && (old_participant.order.is_valid() || participant.order.is_valid())) { if (old_participant != participant && (old_participant.order.is_valid() || participant.order.is_valid())) {
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant, "process_group_call_participant edit");
} }
on_participant_speaking_in_group_call(input_group_call_id, participant); on_participant_speaking_in_group_call(input_group_call_id, participant);
old_participant = std::move(participant); old_participant = std::move(participant);
@ -1955,17 +1970,25 @@ int GroupCallManager::process_group_call_participant(InputGroupCallId input_grou
CHECK(!participant.is_min); CHECK(!participant.is_min);
int diff = participant.is_just_joined ? 1 : 0; int diff = participant.is_just_joined ? 1 : 0;
participant.order = get_real_participant_order(can_manage, participant, participants);
if (participant.is_just_joined) { if (participant.is_just_joined) {
LOG(INFO) << "Add new " << participant; LOG(INFO) << "Add new " << participant;
} else { } else {
LOG(INFO) << "Receive new " << participant; LOG(INFO) << "Receive new " << participant;
} }
participant.order = get_real_participant_order(can_manage, participant, participants);
participant.is_just_joined = false; participant.is_just_joined = false;
update_group_call_participant_can_be_muted(can_manage, participants, participant); update_group_call_participant_can_be_muted(can_manage, participants, participant);
participants->participants.push_back(std::move(participant)); participants->participants.push_back(std::move(participant));
if (participants->participants.back().order.is_valid()) { if (participants->participants.back().order.is_valid()) {
send_update_group_call_participant(input_group_call_id, participants->participants.back()); send_update_group_call_participant(input_group_call_id, participants->participants.back(),
"process_group_call_participant add");
} else {
auto *group_call = get_group_call(input_group_call_id);
CHECK(group_call != nullptr && group_call->is_inited);
if (group_call->loaded_all_participants) {
group_call->loaded_all_participants = false;
send_update_group_call(group_call, "process_group_call_participant 2");
}
} }
on_add_group_call_participant(input_group_call_id, participants->participants.back().dialog_id); on_add_group_call_participant(input_group_call_id, participants->participants.back().dialog_id);
on_participant_speaking_in_group_call(input_group_call_id, participants->participants.back()); on_participant_speaking_in_group_call(input_group_call_id, participants->participants.back());
@ -2003,7 +2026,7 @@ void GroupCallManager::on_update_dialog_about(DialogId dialog_id, const string &
if ((from_server || participant->is_fake) && participant->about != about) { if ((from_server || participant->is_fake) && participant->about != about) {
participant->about = about; participant->about = about;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant, "on_update_dialog_about");
} }
} }
} }
@ -2134,7 +2157,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di
have_as_dialog_id = false; have_as_dialog_id = false;
} }
} else { } else {
if (!td_->messages_manager_->have_dialog_force(as_dialog_id)) { if (!td_->messages_manager_->have_dialog_force(as_dialog_id, "join_group_call")) {
return promise.set_error(Status::Error(400, "Alias chat not found")); return promise.set_error(Status::Error(400, "Alias chat not found"));
} }
} }
@ -2946,7 +2969,7 @@ void GroupCallManager::toggle_group_call_participant_is_muted(GroupCallId group_
participant->pending_is_muted_generation = ++toggle_is_muted_generation_; participant->pending_is_muted_generation = ++toggle_is_muted_generation_;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant, "toggle_group_call_participant_is_muted");
} }
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, dialog_id, auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, dialog_id,
@ -2986,7 +3009,8 @@ void GroupCallManager::on_toggle_group_call_participant_is_muted(InputGroupCallI
participant->server_is_muted_locally != participant->pending_is_muted_locally) { participant->server_is_muted_locally != participant->pending_is_muted_locally) {
LOG(ERROR) << "Failed to mute/unmute " << dialog_id << " in " << input_group_call_id; LOG(ERROR) << "Failed to mute/unmute " << dialog_id << " in " << input_group_call_id;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant,
"on_toggle_group_call_participant_is_muted");
} }
} }
promise.set_value(Unit()); promise.set_value(Unit());
@ -3036,7 +3060,7 @@ void GroupCallManager::set_group_call_participant_volume_level(GroupCallId group
participant->pending_volume_level = volume_level; participant->pending_volume_level = volume_level;
participant->pending_volume_level_generation = ++set_volume_level_generation_; participant->pending_volume_level_generation = ++set_volume_level_generation_;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant, "set_group_call_participant_volume_level");
} }
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, dialog_id, auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, dialog_id,
@ -3074,7 +3098,8 @@ void GroupCallManager::on_set_group_call_participant_volume_level(InputGroupCall
LOG(ERROR) << "Failed to set volume level of " << dialog_id << " in " << input_group_call_id; LOG(ERROR) << "Failed to set volume level of " << dialog_id << " in " << input_group_call_id;
participant->pending_volume_level = 0; participant->pending_volume_level = 0;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant,
"on_set_group_call_participant_volume_level");
} }
} else { } else {
participant->pending_volume_level = 0; participant->pending_volume_level = 0;
@ -3131,7 +3156,8 @@ void GroupCallManager::toggle_group_call_participant_is_hand_raised(GroupCallId
participant->pending_is_hand_raised = is_hand_raised; participant->pending_is_hand_raised = is_hand_raised;
participant->pending_is_hand_raised_generation = ++toggle_is_hand_raised_generation_; participant->pending_is_hand_raised_generation = ++toggle_is_hand_raised_generation_;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant,
"toggle_group_call_participant_is_hand_raised");
} }
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, dialog_id, auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, dialog_id,
@ -3169,7 +3195,8 @@ void GroupCallManager::on_toggle_group_call_participant_is_hand_raised(InputGrou
if (participant->get_is_hand_raised() != participant->pending_is_hand_raised) { if (participant->get_is_hand_raised() != participant->pending_is_hand_raised) {
LOG(ERROR) << "Failed to change raised hand state for " << dialog_id << " in " << input_group_call_id; LOG(ERROR) << "Failed to change raised hand state for " << dialog_id << " in " << input_group_call_id;
if (participant->order.is_valid()) { if (participant->order.is_valid()) {
send_update_group_call_participant(input_group_call_id, *participant); send_update_group_call_participant(input_group_call_id, *participant,
"on_toggle_group_call_participant_is_hand_raised");
} }
} }
promise.set_value(Unit()); promise.set_value(Unit());
@ -3199,6 +3226,10 @@ void GroupCallManager::load_group_call_participants(GroupCallId group_call_id, i
CHECK(participants_it->second != nullptr); CHECK(participants_it->second != nullptr);
next_offset = participants_it->second->next_offset; next_offset = participants_it->second->next_offset;
} }
if (limit == 1 && next_offset.empty()) {
// prevent removing self as the first user and deducing that there are no more participants
limit = 2;
}
td_->create_handler<GetGroupCallParticipantsQuery>(std::move(promise)) td_->create_handler<GetGroupCallParticipantsQuery>(std::move(promise))
->send(input_group_call_id, std::move(next_offset), limit); ->send(input_group_call_id, std::move(next_offset), limit);
} }
@ -3254,12 +3285,12 @@ void GroupCallManager::on_group_call_left(InputGroupCallId input_group_call_id,
return; return;
} }
if (group_call->is_joined && group_call->audio_source == audio_source) { if (group_call->is_joined && group_call->audio_source == audio_source) {
on_group_call_left_impl(group_call, need_rejoin); on_group_call_left_impl(group_call, need_rejoin, "on_group_call_left");
send_update_group_call(group_call, "on_group_call_left"); send_update_group_call(group_call, "on_group_call_left");
} }
} }
void GroupCallManager::on_group_call_left_impl(GroupCall *group_call, bool need_rejoin) { void GroupCallManager::on_group_call_left_impl(GroupCall *group_call, bool need_rejoin, const char *source) {
if (!(group_call != nullptr && group_call->is_inited && group_call->is_joined)) { if (!(group_call != nullptr && group_call->is_inited && group_call->is_joined)) {
return; return;
} }
@ -3342,7 +3373,7 @@ void GroupCallManager::try_clear_group_call_participants(InputGroupCallId input_
if (participant.order.is_valid()) { if (participant.order.is_valid()) {
CHECK(participant.order >= participants->min_order); CHECK(participant.order >= participants->min_order);
participant.order = GroupCallParticipantOrder(); participant.order = GroupCallParticipantOrder();
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant, "try_clear_group_call_participants");
} }
on_remove_group_call_participant(input_group_call_id, participant.dialog_id); on_remove_group_call_participant(input_group_call_id, participant.dialog_id);
} }
@ -3419,6 +3450,10 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptr<telegra
if (!group_call->dialog_id.is_valid()) { if (!group_call->dialog_id.is_valid()) {
group_call->dialog_id = dialog_id; group_call->dialog_id = dialog_id;
} }
if (call.is_active && join_params.empty() && !group_call->is_joined &&
(group_call->need_rejoin || is_group_call_being_joined(input_group_call_id))) {
call.participant_count++;
}
LOG(INFO) << "Update " << call.group_call_id << " with " << group_call->participant_count LOG(INFO) << "Update " << call.group_call_id << " with " << group_call->participant_count
<< " participants and version " << group_call->version; << " participants and version " << group_call->version;
if (!group_call->is_inited) { if (!group_call->is_inited) {
@ -3713,7 +3748,8 @@ DialogId GroupCallManager::set_group_call_participant_is_speaking_by_source(Inpu
bool can_manage = can_manage_group_call(input_group_call_id); bool can_manage = can_manage_group_call(input_group_call_id);
participant.order = get_real_participant_order(can_manage, participant, participants_it->second.get()); participant.order = get_real_participant_order(can_manage, participant, participants_it->second.get());
if (participant.order.is_valid()) { if (participant.order.is_valid()) {
send_update_group_call_participant(input_group_call_id, participant); send_update_group_call_participant(input_group_call_id, participant,
"set_group_call_participant_is_speaking_by_source");
} }
} }
@ -3738,6 +3774,7 @@ bool GroupCallManager::set_group_call_participant_count(GroupCall *group_call, i
count = 0; count = 0;
} }
bool result = false;
auto input_group_call_id = get_input_group_call_id(group_call->group_call_id).ok(); auto input_group_call_id = get_input_group_call_id(group_call->group_call_id).ok();
if (need_group_call_participants(input_group_call_id, group_call)) { if (need_group_call_participants(input_group_call_id, group_call)) {
auto known_participant_count = auto known_participant_count =
@ -3750,12 +3787,17 @@ bool GroupCallManager::set_group_call_participant_count(GroupCall *group_call, i
} }
count = known_participant_count; count = known_participant_count;
} else if (group_call->loaded_all_participants && count > known_participant_count) { } else if (group_call->loaded_all_participants && count > known_participant_count) {
count = known_participant_count; if (group_call->joined_date_asc) {
group_call->loaded_all_participants = false;
result = true;
} else {
count = known_participant_count;
}
} }
} }
if (group_call->participant_count == count) { if (group_call->participant_count == count) {
return false; return result;
} }
group_call->participant_count = count; group_call->participant_count = count;
@ -3867,15 +3909,16 @@ void GroupCallManager::send_update_group_call(const GroupCall *group_call, const
} }
void GroupCallManager::send_update_group_call_participant(GroupCallId group_call_id, void GroupCallManager::send_update_group_call_participant(GroupCallId group_call_id,
const GroupCallParticipant &participant) { const GroupCallParticipant &participant, const char *source) {
if (G()->shared_config().get_option_boolean("disable_group_calls")) { if (G()->shared_config().get_option_boolean("disable_group_calls")) {
return; return;
} }
LOG(INFO) << "Send update about " << participant << " in " << group_call_id << " from " << source;
send_closure(G()->td(), &Td::send_update, get_update_group_call_participant_object(group_call_id, participant)); send_closure(G()->td(), &Td::send_update, get_update_group_call_participant_object(group_call_id, participant));
} }
void GroupCallManager::send_update_group_call_participant(InputGroupCallId input_group_call_id, void GroupCallManager::send_update_group_call_participant(InputGroupCallId input_group_call_id,
const GroupCallParticipant &participant) { const GroupCallParticipant &participant, const char *source) {
if (G()->shared_config().get_option_boolean("disable_group_calls")) { if (G()->shared_config().get_option_boolean("disable_group_calls")) {
return; return;
} }
@ -3883,7 +3926,7 @@ void GroupCallManager::send_update_group_call_participant(InputGroupCallId input
if(!(group_call != nullptr && group_call->is_inited)) { if(!(group_call != nullptr && group_call->is_inited)) {
return; return;
} }
send_update_group_call_participant(group_call->group_call_id, participant); send_update_group_call_participant(group_call->group_call_id, participant, source);
} }
} // namespace td } // namespace td

View File

@ -263,7 +263,7 @@ class GroupCallManager : public Actor {
void on_group_call_left(InputGroupCallId input_group_call_id, int32 audio_source, bool need_rejoin); void on_group_call_left(InputGroupCallId input_group_call_id, int32 audio_source, bool need_rejoin);
void on_group_call_left_impl(GroupCall *group_call, bool need_rejoin); void on_group_call_left_impl(GroupCall *group_call, bool need_rejoin, const char *source);
InputGroupCallId update_group_call(const tl_object_ptr<telegram_api::GroupCall> &group_call_ptr, DialogId dialog_id); InputGroupCallId update_group_call(const tl_object_ptr<telegram_api::GroupCall> &group_call_ptr, DialogId dialog_id);
@ -303,10 +303,11 @@ class GroupCallManager : public Actor {
void send_update_group_call(const GroupCall *group_call, const char *source); void send_update_group_call(const GroupCall *group_call, const char *source);
void send_update_group_call_participant(GroupCallId group_call_id, const GroupCallParticipant &participant); void send_update_group_call_participant(GroupCallId group_call_id, const GroupCallParticipant &participant,
const char *source);
void send_update_group_call_participant(InputGroupCallId input_group_call_id, void send_update_group_call_participant(InputGroupCallId input_group_call_id, const GroupCallParticipant &participant,
const GroupCallParticipant &participant); const char *source);
Td *td_; Td *td_;
ActorShared<> parent_; ActorShared<> parent_;

View File

@ -24,6 +24,9 @@ bool GroupCallParticipantOrder::is_valid() const {
} }
string GroupCallParticipantOrder::get_group_call_participant_order_object() const { string GroupCallParticipantOrder::get_group_call_participant_order_object() const {
if (!is_valid()) {
return string();
}
return PSTRING() << lpad0(to_string(active_date), 10) << lpad0(to_string(raise_hand_rating), 19) return PSTRING() << lpad0(to_string(active_date), 10) << lpad0(to_string(raise_hand_rating), 19)
<< lpad0(to_string(joined_date), 10); << lpad0(to_string(joined_date), 10);
} }

View File

@ -16,6 +16,7 @@
#include "td/telegram/ChatId.h" #include "td/telegram/ChatId.h"
#include "td/telegram/Contact.h" #include "td/telegram/Contact.h"
#include "td/telegram/ContactsManager.h" #include "td/telegram/ContactsManager.h"
#include "td/telegram/Dependencies.h"
#include "td/telegram/Document.h" #include "td/telegram/Document.h"
#include "td/telegram/DocumentsManager.h" #include "td/telegram/DocumentsManager.h"
#include "td/telegram/DocumentsManager.hpp" #include "td/telegram/DocumentsManager.hpp"
@ -437,7 +438,7 @@ class MessageChatSetTtl : public MessageContent {
class MessageUnsupported : public MessageContent { class MessageUnsupported : public MessageContent {
public: public:
static constexpr int32 CURRENT_VERSION = 5; static constexpr int32 CURRENT_VERSION = 6;
int32 version = CURRENT_VERSION; int32 version = CURRENT_VERSION;
MessageUnsupported() = default; MessageUnsupported() = default;

View File

@ -6,7 +6,6 @@
// //
#pragma once #pragma once
#include "td/telegram/Dependencies.h"
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/files/FileId.h" #include "td/telegram/files/FileId.h"
#include "td/telegram/FullMessageId.h" #include "td/telegram/FullMessageId.h"
@ -36,6 +35,7 @@
namespace td { namespace td {
struct Dependencies;
class Game; class Game;
struct Photo; struct Photo;
class Td; class Td;

View File

@ -13,6 +13,7 @@
namespace td { namespace td {
// increase MessageUnsupported::CURRENT_VERSION each time a new message content type is added
enum class MessageContentType : int32 { enum class MessageContentType : int32 {
None = -1, None = -1,
Text, Text,

View File

@ -7,6 +7,7 @@
#include "td/telegram/MessageEntity.h" #include "td/telegram/MessageEntity.h"
#include "td/telegram/ContactsManager.h" #include "td/telegram/ContactsManager.h"
#include "td/telegram/Dependencies.h"
#include "td/telegram/misc.h" #include "td/telegram/misc.h"
#include "td/telegram/SecretChatActor.h" #include "td/telegram/SecretChatActor.h"

View File

@ -6,7 +6,6 @@
// //
#pragma once #pragma once
#include "td/telegram/Dependencies.h"
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/UserId.h" #include "td/telegram/UserId.h"
@ -25,6 +24,7 @@
namespace td { namespace td {
class ContactsManager; class ContactsManager;
struct Dependencies;
class MessageEntity { class MessageEntity {
public: public:

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@
#include "td/telegram/AccessRights.h" #include "td/telegram/AccessRights.h"
#include "td/telegram/ChannelId.h" #include "td/telegram/ChannelId.h"
#include "td/telegram/Dependencies.h"
#include "td/telegram/DialogAction.h" #include "td/telegram/DialogAction.h"
#include "td/telegram/DialogDate.h" #include "td/telegram/DialogDate.h"
#include "td/telegram/DialogDb.h" #include "td/telegram/DialogDb.h"
@ -81,17 +80,12 @@
namespace td { namespace td {
struct BinlogEvent; struct BinlogEvent;
struct Dependencies;
class DialogFilter; class DialogFilter;
class DraftMessage; class DraftMessage;
struct InputMessageContent; struct InputMessageContent;
class MessageContent; class MessageContent;
class MultiSequenceDispatcher; class MultiSequenceDispatcher;
class Td; class Td;
class MessagesManager : public Actor { class MessagesManager : public Actor {
@ -508,7 +502,7 @@ class MessagesManager : public Actor {
tl_object_ptr<td_api::chatEvents> get_chat_events_object(int64 random_id); tl_object_ptr<td_api::chatEvents> get_chat_events_object(int64 random_id);
bool have_dialog(DialogId dialog_id) const; bool have_dialog(DialogId dialog_id) const;
bool have_dialog_force(DialogId dialog_id); bool have_dialog_force(DialogId dialog_id, const char *source = "have_dialog_force");
bool have_dialog_info(DialogId dialog_id) const; bool have_dialog_info(DialogId dialog_id) const;
bool have_dialog_info_force(DialogId dialog_id) const; bool have_dialog_info_force(DialogId dialog_id) const;
@ -1118,6 +1112,8 @@ class MessagesManager : public Actor {
int32 last_edit_pts = 0; int32 last_edit_pts = 0;
const char *debug_source = nullptr;
unique_ptr<Message> left; unique_ptr<Message> left;
unique_ptr<Message> right; unique_ptr<Message> right;
@ -1824,7 +1820,7 @@ class MessagesManager : public Actor {
void delete_messages_from_updates(const vector<MessageId> &message_ids); void delete_messages_from_updates(const vector<MessageId> &message_ids);
void delete_dialog_messages(DialogId dialog_id, const vector<MessageId> &message_ids, bool from_updates, void delete_dialog_messages(DialogId dialog_id, const vector<MessageId> &message_ids, bool from_updates,
bool skip_update_for_not_found_messages); bool skip_update_for_not_found_messages, const char *source);
void update_dialog_pinned_messages_from_updates(DialogId dialog_id, const vector<MessageId> &message_ids, void update_dialog_pinned_messages_from_updates(DialogId dialog_id, const vector<MessageId> &message_ids,
bool is_pin); bool is_pin);
@ -1920,7 +1916,7 @@ class MessagesManager : public Actor {
void do_delete_all_dialog_messages(Dialog *d, unique_ptr<Message> &message, bool is_permanently_deleted, void do_delete_all_dialog_messages(Dialog *d, unique_ptr<Message> &message, bool is_permanently_deleted,
vector<int64> &deleted_message_ids); vector<int64> &deleted_message_ids);
void delete_message_from_server(DialogId dialog_id, MessageId message_ids, bool revoke); void delete_sent_message_from_server(DialogId dialog_id, MessageId message_id);
void delete_messages_from_server(DialogId dialog_id, vector<MessageId> message_ids, bool revoke, uint64 log_event_id, void delete_messages_from_server(DialogId dialog_id, vector<MessageId> message_ids, bool revoke, uint64 log_event_id,
Promise<Unit> &&promise); Promise<Unit> &&promise);
@ -2416,9 +2412,9 @@ class MessagesManager : public Actor {
MessageId get_message_id_by_random_id(Dialog *d, int64 random_id, const char *source); MessageId get_message_id_by_random_id(Dialog *d, int64 random_id, const char *source);
Dialog *add_dialog(DialogId dialog_id); Dialog *add_dialog(DialogId dialog_id, const char *source);
Dialog *add_new_dialog(unique_ptr<Dialog> &&d, bool is_loaded_from_database); Dialog *add_new_dialog(unique_ptr<Dialog> &&d, bool is_loaded_from_database, const char *source);
void fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_database_message, MessageId last_database_message_id, void fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_database_message, MessageId last_database_message_id,
int64 order, int32 last_clear_history_date, MessageId last_clear_history_message_id, int64 order, int32 last_clear_history_date, MessageId last_clear_history_message_id,
@ -2440,9 +2436,9 @@ class MessagesManager : public Actor {
Dialog *get_dialog(DialogId dialog_id); Dialog *get_dialog(DialogId dialog_id);
const Dialog *get_dialog(DialogId dialog_id) const; const Dialog *get_dialog(DialogId dialog_id) const;
Dialog *get_dialog_force(DialogId dialog_id); Dialog *get_dialog_force(DialogId dialog_id, const char *source = "get_dialog_force");
Dialog *on_load_dialog_from_database(DialogId dialog_id, const BufferSlice &value); Dialog *on_load_dialog_from_database(DialogId dialog_id, const BufferSlice &value, const char *source);
void on_get_dialogs_from_database(FolderId folder_id, int32 limit, DialogDbGetDialogsResult &&dialogs, void on_get_dialogs_from_database(FolderId folder_id, int32 limit, DialogDbGetDialogsResult &&dialogs,
Promise<Unit> &&promise); Promise<Unit> &&promise);

View File

@ -151,7 +151,7 @@ void PrivacyManager::UserPrivacySettingRule::set_chat_ids(const vector<int64> &d
auto td = G()->td().get_actor_unsafe(); auto td = G()->td().get_actor_unsafe();
for (auto dialog_id_int : dialog_ids) { for (auto dialog_id_int : dialog_ids) {
DialogId dialog_id(dialog_id_int); DialogId dialog_id(dialog_id_int);
if (!td->messages_manager_->have_dialog_force(dialog_id)) { if (!td->messages_manager_->have_dialog_force(dialog_id, "UserPrivacySettingRule::set_chat_ids")) {
LOG(ERROR) << "Ignore not found " << dialog_id; LOG(ERROR) << "Ignore not found " << dialog_id;
continue; continue;
} }

View File

@ -3191,6 +3191,10 @@ bool Td::is_online() const {
} }
void Td::set_is_bot_online(bool is_bot_online) { void Td::set_is_bot_online(bool is_bot_online) {
if (G()->shared_config().get_option_integer("session_count") > 1) {
is_bot_online = false;
}
if (is_bot_online == is_bot_online_) { if (is_bot_online == is_bot_online_) {
return; return;
} }
@ -6376,7 +6380,7 @@ void Td::on_request(uint64 id, const td_api::leaveChat &request) {
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
DialogId dialog_id(request.chat_id_); DialogId dialog_id(request.chat_id_);
td_api::object_ptr<td_api::ChatMemberStatus> new_status = td_api::make_object<td_api::chatMemberStatusLeft>(); td_api::object_ptr<td_api::ChatMemberStatus> new_status = td_api::make_object<td_api::chatMemberStatusLeft>();
if (dialog_id.get_type() == DialogType::Channel && messages_manager_->have_dialog_force(dialog_id)) { if (dialog_id.get_type() == DialogType::Channel && messages_manager_->have_dialog_force(dialog_id, "leaveChat")) {
auto status = contacts_manager_->get_channel_status(dialog_id.get_channel_id()); auto status = contacts_manager_->get_channel_status(dialog_id.get_channel_id());
if (status.is_creator()) { if (status.is_creator()) {
if (!status.is_member()) { if (!status.is_member()) {
@ -7213,7 +7217,7 @@ void Td::on_request(uint64 id, const td_api::resetAllNotificationSettings &reque
void Td::on_request(uint64 id, const td_api::getMapThumbnailFile &request) { void Td::on_request(uint64 id, const td_api::getMapThumbnailFile &request) {
DialogId dialog_id(request.chat_id_); DialogId dialog_id(request.chat_id_);
if (!messages_manager_->have_dialog_force(dialog_id)) { if (!messages_manager_->have_dialog_force(dialog_id, "getMapThumbnailFile")) {
dialog_id = DialogId(); dialog_id = DialogId();
} }

View File

@ -2823,9 +2823,9 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updatePhoneCallSignal
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateGroupCall> update, Promise<Unit> &&promise) { void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateGroupCall> update, Promise<Unit> &&promise) {
DialogId dialog_id(ChatId(update->chat_id_)); DialogId dialog_id(ChatId(update->chat_id_));
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "updateGroupCall")) {
dialog_id = DialogId(ChannelId(update->chat_id_)); dialog_id = DialogId(ChannelId(update->chat_id_));
if (!td_->messages_manager_->have_dialog_force(dialog_id)) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "updateGroupCall")) {
dialog_id = DialogId(); dialog_id = DialogId();
} }
} }

View File

@ -66,7 +66,7 @@ SqliteKeyValue::SeqNo SqliteKeyValue::set(Slice key, Slice value) {
set_stmt_.bind_blob(2, value).ensure(); set_stmt_.bind_blob(2, value).ensure();
auto status = set_stmt_.step(); auto status = set_stmt_.step();
if (status.is_error()) { if (status.is_error()) {
LOG(FATAL) << "Failed to set \"" << key << '"'; LOG(FATAL) << "Failed to set \"" << key << "\": " << status.error();
} }
// set_stmt_.step().ensure(); // set_stmt_.step().ensure();
set_stmt_.reset(); set_stmt_.reset();

View File

@ -42,12 +42,16 @@ string winerror_to_string(int code) {
wchar_t wbuf[size]; wchar_t wbuf[size];
auto res_size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, code, 0, wbuf, size - 1, nullptr); auto res_size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, code, 0, wbuf, size - 1, nullptr);
if (res_size == 0) { if (res_size == 0) {
return "Unknown windows error"; return "Unknown Windows error";
} }
while (res_size != 0 && (wbuf[res_size - 1] == '\n' || wbuf[res_size - 1] == '\r')) { while (res_size != 0 && (wbuf[res_size - 1] == '\n' || wbuf[res_size - 1] == '\r')) {
res_size--; res_size--;
} }
return from_wstring(wbuf, res_size).ok(); auto error_message = from_wstring(wbuf, res_size);
if (error_message.is_error()) {
return "Invalid Windows error";
}
return error_message.move_as_ok();
} }
#endif #endif

View File

@ -85,7 +85,11 @@ inline std::string string_to_unmanaged(String^ str) {
if (!str) { if (!str) {
return std::string(); return std::string();
} }
return td::from_wstring(str->Data(), str->Length()).ok(); auto r_unmanaged_str = td::from_wstring(str->Data(), str->Length());
if (r_unmanaged_str.is_error()) {
return std::string();
}
return r_unmanaged_str.move_as_ok();
} }
inline String^ string_from_unmanaged(const std::string &from) { inline String^ string_from_unmanaged(const std::string &from) {

View File

@ -76,8 +76,8 @@ inline BOOL DeleteFileFromAppW(_In_ LPCWSTR lpFileName) {
} }
inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) { inline BOOL MoveFileExFromAppW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) {
auto func = get_from_app_function<4>("MoveFileFromAppW", &MoveFile); auto func = get_from_app_function<4>("MoveFileFromAppW", static_cast<BOOL(WINAPI *)(LPCWSTR, LPCWSTR)>(nullptr));
if (func == &MoveFile || (dwFlags & ~MOVEFILE_REPLACE_EXISTING) != 0) { if (func == nullptr || (dwFlags & ~MOVEFILE_REPLACE_EXISTING) != 0) {
// if can't find MoveFileFromAppW or have unsupported flags, call MoveFileEx directly // if can't find MoveFileFromAppW or have unsupported flags, call MoveFileEx directly
return MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags); return MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags);
} }

View File

@ -393,7 +393,8 @@ class SocketFdImpl {
int native_fd = get_native_fd().socket(); int native_fd = get_native_fd().socket();
TRY_RESULT(slices_size, narrow_cast_safe<int>(slices.size())); TRY_RESULT(slices_size, narrow_cast_safe<int>(slices.size()));
auto write_res = detail::skip_eintr([&] { auto write_res = detail::skip_eintr([&] {
#ifdef MSG_NOSIGNAL // sendmsg can erroneously return 2^32 - 1 on Android 5.1 and Android 6.0, so it must not be used there
#if defined(MSG_NOSIGNAL) && !TD_ANDROID
msghdr msg; msghdr msg;
std::memset(&msg, 0, sizeof(msg)); std::memset(&msg, 0, sizeof(msg));
msg.msg_iov = const_cast<iovec *>(slices.begin()); msg.msg_iov = const_cast<iovec *>(slices.begin());
@ -412,7 +413,7 @@ class SocketFdImpl {
} }
left -= slice.iov_len; left -= slice.iov_len;
} }
LOG(FATAL) << "Receive " << result << " as writev response, but tried to write only " << result - left LOG(FATAL) << "Receive " << write_res << " as writev response, but tried to write only " << result - left
<< " bytes"; << " bytes";
} }
return write_finish(); return write_finish();
@ -430,7 +431,7 @@ class SocketFdImpl {
}); });
if (write_res >= 0) { if (write_res >= 0) {
auto result = narrow_cast<size_t>(write_res); auto result = narrow_cast<size_t>(write_res);
LOG_CHECK(result <= slice.size()) << "Receive " << result << " as write response, but tried to write only " LOG_CHECK(result <= slice.size()) << "Receive " << write_res << " as write response, but tried to write only "
<< slice.size() << " bytes"; << slice.size() << " bytes";
return result; return result;
} }

View File

@ -470,7 +470,7 @@ CSlice get_temporary_dir() {
} }
auto rs = from_wstring(buf); auto rs = from_wstring(buf);
LOG_IF(FATAL, rs.is_error()) << "GetTempPathW failed: " << rs.error(); LOG_IF(FATAL, rs.is_error()) << "GetTempPathW failed: " << rs.error();
temporary_dir = rs.ok(); temporary_dir = rs.move_as_ok();
} }
if (temporary_dir.size() > 1 && temporary_dir.back() == TD_DIR_SLASH) { if (temporary_dir.size() > 1 && temporary_dir.back() == TD_DIR_SLASH) {
temporary_dir.pop_back(); temporary_dir.pop_back();

View File

@ -18,7 +18,7 @@ namespace td {
Result<std::wstring> to_wstring(CSlice slice) { Result<std::wstring> to_wstring(CSlice slice) {
if (!check_utf8(slice)) { if (!check_utf8(slice)) {
return Status::Error("Wrong encoding"); return Status::Error("Wrong string encoding");
} }
size_t wstring_len = utf8_utf16_length(slice); size_t wstring_len = utf8_utf16_length(slice);
@ -65,7 +65,7 @@ Result<string> from_wstring(const wchar_t *begin, size_t size) {
} }
} }
return Status::Error("Wrong encoding"); return Status::Error("Wrong wstring encoding");
} }
result_len += 1 + (cur >= 0x80) + (cur >= 0x800); result_len += 1 + (cur >= 0x80) + (cur >= 0x800);
} }