Merge commit 'e72c129f9ce3b7463c7a42406aab0d3ebffdc6be'

Conflicts:
	td/telegram/MessagesManager.cpp
This commit is contained in:
Andrea Cavalli 2021-01-23 22:47:58 +01:00
commit 9a01a9da1d
16 changed files with 899 additions and 888 deletions

View File

@ -248,7 +248,7 @@ public final class Example {
private static void getMainChatList(final int limit) {
synchronized (mainChatList) {
if (!haveFullMainChatList && limit > mainChatList.size()) {
// have enough chats in the chat list or chat list is too small
// send GetChats request if there are some unknown chats and have not enough known chats
long offsetOrder = Long.MAX_VALUE;
long offsetChatId = 0;
if (!mainChatList.isEmpty()) {
@ -281,11 +281,10 @@ public final class Example {
return;
}
// have enough chats in the chat list to answer request
java.util.Iterator<OrderedChat> iter = mainChatList.iterator();
System.out.println();
System.out.println("First " + limit + " chat(s) out of " + mainChatList.size() + " known chat(s):");
for (int i = 0; i < limit; i++) {
for (int i = 0; i < limit && i < mainChatList.size(); i++) {
long chatId = iter.next().chatId;
TdApi.Chat chat = chats.get(chatId);
synchronized (chat) {

View File

@ -728,6 +728,8 @@ void AuthManager::on_get_authorization(tl_object_ptr<telegram_api::auth_Authoriz
td->schedule_get_terms_of_service(0);
td->schedule_get_promo_data(0);
G()->td_db()->get_binlog_pmc()->set("fetched_marks_as_unread", "1");
} else {
send_closure(G()->state_manager(), &StateManager::on_online, true);
}
send_closure(G()->config_manager(), &ConfigManager::request_config);
if (query_id_ != 0) {

View File

@ -8624,7 +8624,7 @@ void ContactsManager::on_load_chat_full_from_database(ChatId chat_id, string val
update_chat_full(chat_full, chat_id, true);
}
ContactsManager::ChatFull *ContactsManager::get_chat_full_force(ChatId chat_id) {
ContactsManager::ChatFull *ContactsManager::get_chat_full_force(ChatId chat_id, const char *source) {
if (!have_chat_force(chat_id)) {
return nullptr;
}
@ -8640,7 +8640,7 @@ ContactsManager::ChatFull *ContactsManager::get_chat_full_force(ChatId chat_id)
return nullptr;
}
LOG(INFO) << "Trying to load full " << chat_id << " from database";
LOG(INFO) << "Trying to load full " << chat_id << " from database from " << source;
on_load_chat_full_from_database(chat_id,
G()->td_db()->get_sqlite_sync_pmc()->get(get_chat_full_database_key(chat_id)));
return get_chat_full(chat_id);
@ -10462,7 +10462,7 @@ void ContactsManager::on_get_chat_participants(tl_object_ptr<telegram_api::ChatP
return;
}
ChatFull *chat_full = get_chat_full_force(chat_id);
ChatFull *chat_full = get_chat_full_force(chat_id, "telegram_api::chatParticipants");
if (chat_full == nullptr) {
LOG(INFO) << "Ignore update of members for unknown full " << chat_id;
return;
@ -11116,7 +11116,7 @@ void ContactsManager::on_get_chat_invite_link(ChatId chat_id,
return;
}
auto chat_full = get_chat_full_force(chat_id);
auto chat_full = get_chat_full_force(chat_id, "on_get_chat_invite_link");
if (chat_full == nullptr) {
update_invite_link(dialog_invite_links_[DialogId(chat_id)], std::move(invite_link_ptr));
return;
@ -11548,7 +11548,7 @@ void ContactsManager::on_update_chat_add_user(ChatId chat_id, UserId inviter_use
LOG(INFO) << "Receive updateChatParticipantAdd to " << chat_id << " with " << user_id << " invited by "
<< inviter_user_id << " at " << date << " with version " << version;
ChatFull *chat_full = get_chat_full_force(chat_id);
ChatFull *chat_full = get_chat_full_force(chat_id, "on_update_chat_add_user");
if (chat_full == nullptr) {
LOG(INFO) << "Ignoring update about members of " << chat_id;
return;
@ -11653,7 +11653,7 @@ void ContactsManager::on_update_chat_edit_administrator(ChatId chat_id, UserId u
update_chat(c, chat_id);
}
ChatFull *chat_full = get_chat_full_force(chat_id);
ChatFull *chat_full = get_chat_full_force(chat_id, "on_update_chat_edit_administrator");
if (chat_full != nullptr) {
if (chat_full->version + 1 == version) {
for (auto &participant : chat_full->participants) {
@ -11683,7 +11683,7 @@ void ContactsManager::on_update_chat_delete_user(ChatId chat_id, UserId user_id,
LOG(INFO) << "Receive updateChatParticipantDelete from " << chat_id << " with " << user_id << " and version "
<< version;
ChatFull *chat_full = get_chat_full_force(chat_id);
ChatFull *chat_full = get_chat_full_force(chat_id, "on_update_chat_delete_user");
if (chat_full == nullptr) {
LOG(INFO) << "Ignoring update about members of " << chat_id;
return;
@ -11942,7 +11942,7 @@ void ContactsManager::on_update_chat_description(ChatId chat_id, string &&descri
return;
}
auto chat_full = get_chat_full_force(chat_id);
auto chat_full = get_chat_full_force(chat_id, "on_update_chat_description");
if (chat_full == nullptr) {
return;
}
@ -12018,7 +12018,7 @@ void ContactsManager::drop_chat_photos(ChatId chat_id, bool is_empty, bool drop_
}
void ContactsManager::drop_chat_full(ChatId chat_id) {
ChatFull *chat_full = get_chat_full_force(chat_id);
ChatFull *chat_full = get_chat_full_force(chat_id, "drop_chat_full");
if (chat_full == nullptr) {
drop_chat_photos(chat_id, false, false, "drop_chat_full");
@ -12908,27 +12908,27 @@ bool ContactsManager::is_chat_full_outdated(const ChatFull *chat_full, const Cha
return false;
}
bool ContactsManager::load_chat_full(ChatId chat_id, bool force, Promise<Unit> &&promise) {
bool ContactsManager::load_chat_full(ChatId chat_id, bool force, Promise<Unit> &&promise, const char *source) {
auto c = get_chat(chat_id);
if (c == nullptr) {
promise.set_error(Status::Error(6, "Group not found"));
return false;
}
auto chat_full = get_chat_full_force(chat_id);
auto chat_full = get_chat_full_force(chat_id, source);
if (chat_full == nullptr) {
LOG(INFO) << "Full " << chat_id << " not found";
send_get_chat_full_query(chat_id, std::move(promise), "load_chat_full");
send_get_chat_full_query(chat_id, std::move(promise), source);
return false;
}
if (is_chat_full_outdated(chat_full, c, chat_id)) {
LOG(INFO) << "Have outdated full " << chat_id;
if (td_->auth_manager_->is_bot() && !force) {
send_get_chat_full_query(chat_id, std::move(promise), "load expired chat_full");
send_get_chat_full_query(chat_id, std::move(promise), source);
return false;
} else {
send_get_chat_full_query(chat_id, Auto(), "load expired chat_full");
send_get_chat_full_query(chat_id, Auto(), source);
}
}
@ -13401,7 +13401,11 @@ std::pair<int32, vector<UserId>> ContactsManager::search_among_users(const vecto
if (u == nullptr) {
continue;
}
hints.add(user_id.get(), u->first_name + " " + u->last_name + " " + u->username);
if (query.empty()) {
hints.add(user_id.get(), Slice(" "));
} else {
hints.add(user_id.get(), PSLICE() << u->first_name << ' ' << u->last_name << ' ' << u->username);
}
hints.set_rating(user_id.get(), -get_user_was_online(u, user_id));
}
@ -13415,7 +13419,7 @@ DialogParticipant ContactsManager::get_chat_participant(ChatId chat_id, UserId u
LOG(INFO) << "Trying to get " << user_id << " as member of " << chat_id;
if (force) {
promise.set_value(Unit());
} else if (!load_chat_full(chat_id, force, std::move(promise))) {
} else if (!load_chat_full(chat_id, force, std::move(promise), "get_chat_participant")) {
return DialogParticipant();
}
// promise is already set
@ -13440,7 +13444,7 @@ std::pair<int32, vector<DialogParticipant>> ContactsManager::search_chat_partici
if (force) {
promise.set_value(Unit());
} else if (!load_chat_full(chat_id, force, std::move(promise))) {
} else if (!load_chat_full(chat_id, force, std::move(promise), "search_chat_participants")) {
return {};
}
// promise is already set
@ -13770,7 +13774,7 @@ void ContactsManager::on_update_dialog_administrators(DialogId dialog_id, vector
void ContactsManager::reload_dialog_administrators(DialogId dialog_id, int32 hash, Promise<Unit> &&promise) {
switch (dialog_id.get_type()) {
case DialogType::Chat:
load_chat_full(dialog_id.get_chat_id(), false, std::move(promise));
load_chat_full(dialog_id.get_chat_id(), false, std::move(promise), "reload_dialog_administrators");
break;
case DialogType::Channel:
td_->create_handler<GetChannelAdministratorsQuery>(std::move(promise))->send(dialog_id.get_channel_id(), hash);

View File

@ -465,7 +465,7 @@ class ContactsManager : public Actor {
bool have_chat_force(ChatId chat_id);
bool get_chat(ChatId chat_id, int left_tries, Promise<Unit> &&promise);
void reload_chat(ChatId chat_id, Promise<Unit> &&promise);
bool load_chat_full(ChatId chat_id, bool force, Promise<Unit> &&promise);
bool load_chat_full(ChatId chat_id, bool force, Promise<Unit> &&promise, const char *source);
FileSourceId get_chat_full_file_source_id(ChatId chat_id);
void reload_chat_full(ChatId chat_id, Promise<Unit> &&promise);
@ -1105,7 +1105,7 @@ class ContactsManager : public Actor {
const ChatFull *get_chat_full(ChatId chat_id) const;
ChatFull *get_chat_full(ChatId chat_id);
ChatFull *get_chat_full_force(ChatId chat_id);
ChatFull *get_chat_full_force(ChatId chat_id, const char *source);
ChatFull *add_chat_full(ChatId chat_id);

View File

@ -810,6 +810,28 @@ StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipan
}
}
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantsFilter &filter) {
switch (filter.type) {
case DialogParticipantsFilter::Type::Contacts:
return string_builder << "Contacts";
case DialogParticipantsFilter::Type::Administrators:
return string_builder << "Administrators";
case DialogParticipantsFilter::Type::Members:
return string_builder << "Members";
case DialogParticipantsFilter::Type::Restricted:
return string_builder << "Restricted";
case DialogParticipantsFilter::Type::Banned:
return string_builder << "Banned";
case DialogParticipantsFilter::Type::Mention:
return string_builder << "Mention";
case DialogParticipantsFilter::Type::Bots:
return string_builder << "Bots";
default:
UNREACHABLE();
return string_builder;
}
}
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter) {
if (filter == nullptr) {
return DialogParticipantsFilter{DialogParticipantsFilter::Type::Members};

View File

@ -463,6 +463,8 @@ class DialogParticipantsFilter {
}
};
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantsFilter &filter);
DialogParticipantsFilter get_dialog_participants_filter(const tl_object_ptr<td_api::ChatMembersFilter> &filter);
DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api::ChatMemberStatus> &status);

View File

@ -1599,7 +1599,8 @@ void GroupCallManager::finish_load_group_call_administrators(InputGroupCallId in
}
auto *group_call_participants = add_group_call_participants(input_group_call_id);
if (group_call_participants->administrator_user_ids == administrator_user_ids) {
if (group_call_participants->are_administrators_loaded &&
group_call_participants->administrator_user_ids == administrator_user_ids) {
return;
}

View File

@ -57,9 +57,7 @@ MessageReplyInfo::MessageReplyInfo(tl_object_ptr<telegram_api::messageReplies> &
ServerMessageId(reply_info->read_max_id_).is_valid()) {
last_read_inbox_message_id = MessageId(ServerMessageId(reply_info->read_max_id_));
}
if (last_read_inbox_message_id > max_message_id) {
LOG(ERROR) << "Receive last_read_inbox_message_id = " << last_read_inbox_message_id
<< ", but max_message_id = " << max_message_id;
if (last_read_inbox_message_id > max_message_id) { // possible if last thread message was deleted after it was read
max_message_id = last_read_inbox_message_id;
}
LOG(DEBUG) << "Parsed " << oneline(to_string(reply_info)) << " to " << *this;

View File

@ -84,11 +84,6 @@
namespace td {
void dummyUpdate::store(TlStorerToString &s, const char *field_name) const {
s.store_class_begin(field_name, "dummyUpdate");
s.store_class_end();
}
class GetDialogFiltersQuery : public Td::ResultHandler {
Promise<vector<tl_object_ptr<telegram_api::dialogFilter>>> promise_;
@ -666,10 +661,9 @@ class UnpinAllMessagesQuery : public Td::ResultHandler {
affected_history->pts_, affected_history->pts_count_,
std::move(promise), "unpin all messages");
} else {
VLOG(add_pending_update) << "Calling add_pending_update (1)";
td->messages_manager_->add_pending_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
affected_history->pts_count_, false, std::move(promise),
"unpin all messages");
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
affected_history->pts_count_, std::move(promise),
"unpin all messages");
}
} else if (affected_history->offset_ <= 0) {
promise_.set_value(Unit());
@ -1572,10 +1566,9 @@ class ReadMessagesContentsQuery : public Td::ResultHandler {
CHECK(affected_messages->get_id() == telegram_api::messages_affectedMessages::ID);
if (affected_messages->pts_count_ > 0) {
VLOG(add_pending_update) << "Calling add_pending_update (2)";
td->messages_manager_->add_pending_update(make_tl_object<dummyUpdate>(), affected_messages->pts_,
affected_messages->pts_count_, false, Promise<Unit>(),
"read messages content query");
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_messages->pts_,
affected_messages->pts_count_, Promise<Unit>(),
"read messages content query");
}
promise_.set_value(Unit());
@ -1791,10 +1784,9 @@ class ReadHistoryQuery : public Td::ResultHandler {
LOG(INFO) << "Receive result for ReadHistoryQuery: " << to_string(affected_messages);
if (affected_messages->pts_count_ > 0) {
VLOG(add_pending_update) << "Calling add_pending_update (3)";
td->messages_manager_->add_pending_update(make_tl_object<dummyUpdate>(), affected_messages->pts_,
affected_messages->pts_count_, false, Promise<Unit>(),
"read history query");
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_messages->pts_,
affected_messages->pts_count_, Promise<Unit>(),
"read history query");
}
promise_.set_value(Unit());
@ -2171,7 +2163,6 @@ class GetMessagePublicForwardsQuery : public Td::ResultHandler {
}
auto info = td->messages_manager_->on_get_messages(result_ptr.move_as_ok(), "GetMessagePublicForwardsQuery");
LOG_IF(ERROR, !info.is_channel_messages) << "Receive ordinary messages in GetMessagePublicForwardsQuery";
td->messages_manager_->on_get_message_public_forwards_result(random_id_, info.total_count,
std::move(info.messages));
@ -2262,10 +2253,9 @@ class DeleteHistoryQuery : public Td::ResultHandler {
CHECK(affected_history->get_id() == telegram_api::messages_affectedHistory::ID);
if (affected_history->pts_count_ > 0) {
VLOG(add_pending_update) << "Calling add_pending_update (4)";
td->messages_manager_->add_pending_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
affected_history->pts_count_, false, Promise<Unit>(),
"delete history query");
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
affected_history->pts_count_, Promise<Unit>(),
"delete history query");
}
if (affected_history->offset_ > 0) {
@ -2463,10 +2453,9 @@ class ReadAllMentionsQuery : public Td::ResultHandler {
<< dialog_id_;
td->updates_manager_->get_difference("Wrong messages_readMentions result");
} else {
VLOG(add_pending_update) << "Calling add_pending_update (5)";
td->messages_manager_->add_pending_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
affected_history->pts_count_, false, Promise<Unit>(),
"read all mentions query");
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_history->pts_,
affected_history->pts_count_, Promise<Unit>(),
"read all mentions query");
}
}
@ -2600,10 +2589,9 @@ class SendMessageActor : public NetActorOnce {
return;
}
VLOG(add_pending_update) << "Calling add_pending_update (6)";
td->messages_manager_->add_pending_update(
td->updates_manager_->add_pending_pts_update(
make_tl_object<updateSentMessage>(random_id_, message_id, sent_message->date_), sent_message->pts_,
sent_message->pts_count_, false, Promise<Unit>(), "send message actor");
sent_message->pts_count_, Promise<Unit>(), "send message actor");
}
void on_error(uint64 id, Status status) override {
@ -3623,10 +3611,9 @@ class DeleteMessagesQuery : public Td::ResultHandler {
CHECK(affected_messages->get_id() == telegram_api::messages_affectedMessages::ID);
if (affected_messages->pts_count_ > 0) {
VLOG(add_pending_update) << "Calling add_pending_update (7)";
td->messages_manager_->add_pending_update(make_tl_object<dummyUpdate>(), affected_messages->pts_,
affected_messages->pts_count_, false, Promise<Unit>(),
"delete messages query");
td->updates_manager_->add_pending_pts_update(make_tl_object<dummyUpdate>(), affected_messages->pts_,
affected_messages->pts_count_, Promise<Unit>(),
"delete messages query");
}
if (--query_count_ == 0) {
promise_.set_value(Unit());
@ -6216,7 +6203,7 @@ tl_object_ptr<telegram_api::inputEncryptedChat> MessagesManager::get_input_encry
}
}
bool MessagesManager::is_allowed_useless_update(const tl_object_ptr<telegram_api::Update> &update) const {
bool MessagesManager::is_allowed_useless_update(const tl_object_ptr<telegram_api::Update> &update) {
auto constructor_id = update->get_id();
if (constructor_id == dummyUpdate::ID) {
// allow dummyUpdate just in case
@ -6231,24 +6218,8 @@ bool MessagesManager::is_allowed_useless_update(const tl_object_ptr<telegram_api
return false;
}
bool MessagesManager::check_update_dialog_id(const tl_object_ptr<telegram_api::Update> &update, DialogId dialog_id) {
switch (dialog_id.get_type()) {
case DialogType::User:
case DialogType::Chat:
return true;
case DialogType::Channel:
case DialogType::SecretChat:
case DialogType::None:
LOG(ERROR) << "Receive update in wrong " << dialog_id << ": " << oneline(to_string(update));
return false;
default:
UNREACHABLE();
return false;
}
}
void MessagesManager::skip_old_pending_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts,
int32 old_pts, int32 pts_count, const char *source) {
void MessagesManager::skip_old_pending_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts,
int32 old_pts, int32 pts_count, const char *source) {
if (update->get_id() == telegram_api::updateNewMessage::ID) {
auto update_new_message = static_cast<telegram_api::updateNewMessage *>(update.get());
auto full_message_id = get_full_message_id(update_new_message->message_, false);
@ -6287,198 +6258,6 @@ void MessagesManager::skip_old_pending_update(tl_object_ptr<telegram_api::Update
<< "Receive useless update " << oneline(to_string(update)) << " from " << source;
}
int32 MessagesManager::get_min_pending_pts() const {
int32 result = std::numeric_limits<int32>::max();
if (!pending_pts_updates_.empty()) {
auto pts = pending_pts_updates_.begin()->first;
if (pts < result) {
result = pts;
}
}
if (!postponed_pts_updates_.empty()) {
auto pts = postponed_pts_updates_.begin()->first;
if (pts < result) {
result = pts;
}
}
return result;
}
void MessagesManager::add_pending_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 pts_count,
bool force_apply, Promise<Unit> &&promise, const char *source) {
// do not try to run getDifference from this function
CHECK(update != nullptr);
CHECK(source != nullptr);
VLOG(messages) << "Receive from " << source << " pending " << to_string(update) << "new_pts = " << new_pts
<< ", pts_count = " << pts_count << ", force_apply = " << force_apply;
if (pts_count < 0 || new_pts <= pts_count) {
LOG(ERROR) << "Receive update with wrong pts = " << new_pts << " or pts_count = " << pts_count << " from " << source
<< ": " << oneline(to_string(update));
return promise.set_value(Unit());
}
// TODO need to save all updates that can change result of running queries not associated with pts (for example
// getHistory) and apply them to result of this queries
switch (update->get_id()) {
case dummyUpdate::ID:
case updateSentMessage::ID:
case telegram_api::updateReadMessagesContents::ID:
case telegram_api::updateDeleteMessages::ID:
// nothing to check
break;
case telegram_api::updateNewMessage::ID: {
auto update_new_message = static_cast<const telegram_api::updateNewMessage *>(update.get());
DialogId dialog_id = get_message_dialog_id(update_new_message->message_);
if (!check_update_dialog_id(update, dialog_id)) {
return promise.set_value(Unit());
}
break;
}
case telegram_api::updateReadHistoryInbox::ID: {
auto update_read_history_inbox = static_cast<const telegram_api::updateReadHistoryInbox *>(update.get());
auto dialog_id = DialogId(update_read_history_inbox->peer_);
if (!check_update_dialog_id(update, dialog_id)) {
return promise.set_value(Unit());
}
break;
}
case telegram_api::updateReadHistoryOutbox::ID: {
auto update_read_history_outbox = static_cast<const telegram_api::updateReadHistoryOutbox *>(update.get());
auto dialog_id = DialogId(update_read_history_outbox->peer_);
if (!check_update_dialog_id(update, dialog_id)) {
return promise.set_value(Unit());
}
break;
}
case telegram_api::updateEditMessage::ID: {
auto update_edit_message = static_cast<const telegram_api::updateEditMessage *>(update.get());
DialogId dialog_id = get_message_dialog_id(update_edit_message->message_);
if (!check_update_dialog_id(update, dialog_id)) {
return promise.set_value(Unit());
}
break;
}
case telegram_api::updatePinnedMessages::ID: {
auto update_pinned_messages = static_cast<const telegram_api::updatePinnedMessages *>(update.get());
auto dialog_id = DialogId(update_pinned_messages->peer_);
if (!check_update_dialog_id(update, dialog_id)) {
return promise.set_value(Unit());
}
break;
}
default:
LOG(ERROR) << "Receive unexpected update " << oneline(to_string(update)) << "from " << source;
return;
}
if (force_apply) {
CHECK(pending_pts_updates_.empty());
CHECK(accumulated_pts_ == -1);
if (pts_count != 0) {
LOG(ERROR) << "Receive forced update with pts_count = " << pts_count << " from " << source;
}
process_update(std::move(update));
return promise.set_value(Unit());
}
if (DROP_UPDATES) {
set_get_difference_timeout(1.0);
return promise.set_value(Unit());
}
int32 old_pts = td_->updates_manager_->get_pts();
if (new_pts < old_pts - 99 && Slice(source) != "after get difference") {
bool need_restore_pts = new_pts < old_pts - 19999;
auto now = Time::now();
if (now > last_pts_jump_warning_time_ + 1 && (need_restore_pts || now < last_pts_jump_warning_time_ + 5)) {
LOG(ERROR) << "Restore pts after delete_first_messages from " << old_pts << " to " << new_pts
<< " is disabled, pts_count = " << pts_count << ", update is from " << source << ": "
<< oneline(to_string(update));
last_pts_jump_warning_time_ = now;
}
if (need_restore_pts) {
set_get_difference_timeout(0.001);
/*
LOG(WARNING) << "Restore pts after delete_first_messages";
td_->updates_manager_->set_pts(new_pts - 1, "restore pts after delete_first_messages");
old_pts = td_->updates_manager_->get_pts();
CHECK(old_pts == new_pts - 1);
*/
}
}
if (new_pts <= old_pts || (old_pts >= 1 && new_pts > old_pts + 500000000)) {
skip_old_pending_update(std::move(update), new_pts, old_pts, pts_count, source);
return promise.set_value(Unit());
}
auto old_postponed_pts_updates_behavior
= G()->shared_config().get_option_boolean("experiment_old_postponed_pts_updates_behavior", false);
if (td_->updates_manager_->running_get_difference() || (!old_postponed_pts_updates_behavior && !postponed_pts_updates_.empty())) {
VLOG(messages) << "Save pending update got while running getDifference from " << source;
if (td_->updates_manager_->running_get_difference()) {
CHECK(update->get_id() == dummyUpdate::ID || update->get_id() == updateSentMessage::ID);
}
postpone_pts_update(std::move(update), new_pts, pts_count, std::move(promise));
return;
}
if (old_pts + pts_count > new_pts) {
LOG(WARNING) << "Have old_pts (= " << old_pts << ") + pts_count (= " << pts_count << ") > new_pts (= " << new_pts
<< "). Logged in " << G()->shared_config().get_option_integer("authorization_date") << ". Update from "
<< source << " = " << oneline(to_string(update));
postpone_pts_update(std::move(update), new_pts, pts_count, std::move(promise));
set_get_difference_timeout(0.001);
return;
}
accumulated_pts_count_ += pts_count;
if (new_pts > accumulated_pts_) {
accumulated_pts_ = new_pts;
}
if (old_pts + accumulated_pts_count_ > accumulated_pts_) {
LOG(WARNING) << "Have old_pts (= " << old_pts << ") + accumulated_pts_count (= " << accumulated_pts_count_
<< ") > accumulated_pts (= " << accumulated_pts_ << "). new_pts = " << new_pts
<< ", pts_count = " << pts_count << ". Logged in "
<< G()->shared_config().get_option_integer("authorization_date") << ". Update from " << source << " = "
<< oneline(to_string(update));
postpone_pts_update(std::move(update), new_pts, pts_count, std::move(promise));
set_get_difference_timeout(0.001);
return;
}
LOG_IF(INFO, pts_count == 0 && update->get_id() != dummyUpdate::ID) << "Skip useless update " << to_string(update);
if (pending_pts_updates_.empty() && old_pts + accumulated_pts_count_ == accumulated_pts_ &&
!pts_gap_timeout_.has_timeout()) {
if (pts_count > 0) {
process_update(std::move(update));
td_->updates_manager_->set_pts(accumulated_pts_, "process pending updates fast path")
.set_value(Unit()); // TODO can't set until get messages really stored on persistent storage
accumulated_pts_count_ = 0;
accumulated_pts_ = -1;
}
promise.set_value(Unit());
return;
}
pending_pts_updates_.emplace(new_pts, PendingPtsUpdate(std::move(update), new_pts, pts_count, std::move(promise)));
if (old_pts + accumulated_pts_count_ < accumulated_pts_) {
set_get_difference_timeout(UpdatesManager::MAX_UNFILLED_GAP_TIME);
return;
}
CHECK(old_pts + accumulated_pts_count_ == accumulated_pts_);
if (!pending_pts_updates_.empty()) {
process_pending_updates();
}
}
MessagesManager::Dialog *MessagesManager::get_service_notifications_dialog() {
UserId service_notifications_user_id = td_->contacts_manager_->add_service_notifications_user();
DialogId service_notifications_dialog_id(service_notifications_user_id);
@ -6810,10 +6589,11 @@ bool MessagesManager::is_visible_message_reply_info(DialogId dialog_id, const Me
if (!m->message_id.is_valid()) {
return false;
}
if (!m->message_id.is_server() && !m->message_id.is_yet_unsent()) {
bool is_broadcast = is_broadcast_channel(dialog_id);
if (!m->message_id.is_server() && !(is_broadcast && m->message_id.is_yet_unsent())) {
return false;
}
if (is_broadcast_channel(dialog_id) && (m->had_reply_markup || m->reply_markup != nullptr)) {
if (is_broadcast && (m->had_reply_markup || m->reply_markup != nullptr)) {
return false;
}
return is_active_message_reply_info(dialog_id, m->reply_info);
@ -7301,11 +7081,11 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p
if (new_pts < old_pts - 19999 && !is_postponed_update) {
// restore channel pts after delete_first_messages
auto now = Time::now();
if (now > last_pts_jump_warning_time_ + 1) {
LOG(WARNING) << "Restore pts in " << d->dialog_id << " from " << source << " after delete_first_messages from "
if (now > last_channel_pts_jump_warning_time_ + 1) {
LOG(ERROR) << "Restore pts in " << d->dialog_id << " from " << source << " after delete_first_messages from "
<< old_pts << " to " << new_pts << " is temporarily disabled, pts_count = " << pts_count
<< ", update is from " << source << ": " << oneline(to_string(update));
last_pts_jump_warning_time_ = now;
last_channel_pts_jump_warning_time_ = now;
}
get_channel_difference(dialog_id, old_pts, true, "add_pending_channel_update old");
}
@ -7388,16 +7168,7 @@ bool MessagesManager::is_old_channel_update(DialogId dialog_id, int32 new_pts) {
return new_pts <= (d == nullptr ? load_channel_pts(dialog_id) : d->pts);
}
void MessagesManager::set_get_difference_timeout(double timeout) {
if (!pts_gap_timeout_.has_timeout()) {
LOG(INFO) << "Gap in pts has found, current pts is " << td_->updates_manager_->get_pts();
pts_gap_timeout_.set_callback(std::move(UpdatesManager::fill_pts_gap));
pts_gap_timeout_.set_callback_data(static_cast<void *>(td_));
pts_gap_timeout_.set_timeout_in(timeout);
}
}
void MessagesManager::process_update(tl_object_ptr<telegram_api::Update> &&update) {
void MessagesManager::process_pts_update(tl_object_ptr<telegram_api::Update> &&update) {
switch (update->get_id()) {
case dummyUpdate::ID:
LOG(INFO) << "Process dummyUpdate";
@ -7562,30 +7333,6 @@ void MessagesManager::on_message_edited(FullMessageId full_message_id, int32 pts
update_used_hashtags(dialog_id, m);
}
void MessagesManager::process_pending_updates() {
for (auto &update : pending_pts_updates_) {
process_update(std::move(update.second.update));
update.second.promise.set_value(Unit());
}
td_->updates_manager_->set_pts(accumulated_pts_, "process pending updates")
.set_value(Unit()); // TODO can't set until get messages really stored on persistent storage
drop_pending_updates();
}
void MessagesManager::drop_pending_updates() {
accumulated_pts_count_ = 0;
accumulated_pts_ = -1;
pts_gap_timeout_.cancel_timeout();
pending_pts_updates_.clear();
}
void MessagesManager::postpone_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 pts, int32 pts_count,
Promise<Unit> &&promise) {
VLOG(postponed_pts_update) << "Postponed pts size: " << postponed_pts_updates_.size();
postponed_pts_updates_.emplace(pts, PendingPtsUpdate(std::move(update), pts, pts_count, std::move(promise)));
}
string MessagesManager::get_notification_settings_scope_database_key(NotificationSettingsScope scope) {
switch (scope) {
case NotificationSettingsScope::Private:
@ -8923,31 +8670,11 @@ void MessagesManager::before_get_difference() {
// scheduled messages are not returned in getDifference, so we must always reget them after it
scheduled_messages_sync_generation_++;
postponed_pts_updates_.insert(std::make_move_iterator(pending_pts_updates_.begin()),
std::make_move_iterator(pending_pts_updates_.end()));
drop_pending_updates();
}
void MessagesManager::after_get_difference() {
CHECK(!td_->updates_manager_->running_get_difference());
if (postponed_pts_updates_.size()) {
auto postponed_updates = std::move(postponed_pts_updates_);
postponed_pts_updates_.clear();
LOG(INFO) << "Begin to apply " << postponed_updates.size() << " postponed pts updates";
for (auto &postponed_update : postponed_updates) {
auto &update = postponed_update.second;
add_pending_update(std::move(update.update), update.pts, update.pts_count, false, std::move(update.promise),
"after get difference");
CHECK(!td_->updates_manager_->running_get_difference());
}
LOG(INFO) << "Finish to apply postponed pts updates, have " << postponed_pts_updates_.size()
<< " left postponed updates";
}
running_get_difference_ = false;
if (!pending_on_get_dialogs_.empty()) {
@ -9013,13 +8740,13 @@ void MessagesManager::after_get_difference() {
LOG(ERROR) << "Unknown dialog " << dialog_id;
break;
}
if (dialog_id.get_type() == DialogType::Channel || pending_pts_updates_.empty() || message_id.is_scheduled() ||
if (dialog_id.get_type() == DialogType::Channel || message_id.is_scheduled() ||
message_id <= d->last_new_message_id) {
LOG(ERROR) << "Receive updateMessageId from " << it.second << " to " << full_message_id
<< " but not receive corresponding message, last_new_message_id = " << d->last_new_message_id;
}
if (dialog_id.get_type() != DialogType::Channel &&
(pending_pts_updates_.empty() || message_id.is_scheduled() || message_id <= d->last_new_message_id)) {
(message_id.is_scheduled() || message_id <= d->last_new_message_id)) {
dump_debug_message_op(get_dialog(dialog_id));
}
if (message_id.is_scheduled() || message_id <= d->last_new_message_id) {
@ -12026,7 +11753,7 @@ void MessagesManager::init() {
always_wait_for_mailbox();
start_time_ = Time::now();
last_pts_jump_warning_time_ = start_time_ - 3600;
last_channel_pts_jump_warning_time_ = start_time_ - 3600;
bool is_authorized = td_->auth_manager_->is_authorized();
bool was_authorized_user = td_->auth_manager_->was_authorized() && !td_->auth_manager_->is_bot();
@ -16792,7 +16519,7 @@ void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&p
return;
case DialogType::Chat:
send_closure_later(G()->contacts_manager(), &ContactsManager::load_chat_full, dialog_id.get_chat_id(), false,
std::move(promise));
std::move(promise), "get_dialog_info_full");
return;
case DialogType::Channel:
send_closure_later(G()->contacts_manager(), &ContactsManager::load_channel_full, dialog_id.get_channel_id(),
@ -28313,7 +28040,7 @@ FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageI
FileId new_file_id, const char *source) {
CHECK(source != nullptr);
// do not try to run getDifference from this function
if (DROP_UPDATES) {
if (DROP_SEND_MESSAGE_UPDATES) {
return {};
}
if (!new_message_id.is_valid()) {
@ -30881,7 +30608,8 @@ std::pair<int32, vector<DialogParticipant>> MessagesManager::search_private_chat
std::pair<int32, vector<DialogParticipant>> MessagesManager::search_dialog_participants(
DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter, int64 &random_id,
bool without_bot_info, bool force, Promise<Unit> &&promise) {
LOG(INFO) << "Receive searchChatMembers request to search for " << query << " in " << dialog_id;
LOG(INFO) << "Receive searchChatMembers request to search for \"" << query << "\" in " << dialog_id << " with filter "
<< filter;
if (!have_dialog_force(dialog_id)) {
promise.set_error(Status::Error(3, "Chat not found"));
return {};
@ -33521,6 +33249,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d,
}
break;
case DialogType::Chat:
d->is_is_blocked_inited = true;
break;
case DialogType::Channel: {
auto channel_type = td_->contacts_manager_->get_channel_type(dialog_id.get_channel_id());

View File

@ -67,7 +67,6 @@
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
#include "td/utils/StringBuilder.h"
#include "td/utils/tl_storers.h"
#include <array>
#include <functional>
@ -94,56 +93,6 @@ class MultiSequenceDispatcher;
class Td;
class dummyUpdate : public telegram_api::Update {
public:
static constexpr int32 ID = 1234567891;
int32 get_id() const override {
return ID;
}
void store(TlStorerUnsafe &s) const override {
UNREACHABLE();
}
void store(TlStorerCalcLength &s) const override {
UNREACHABLE();
}
void store(TlStorerToString &s, const char *field_name) const override;
};
class updateSentMessage : public telegram_api::Update {
public:
int64 random_id_;
MessageId message_id_;
int32 date_;
updateSentMessage(int64 random_id, MessageId message_id, int32 date)
: random_id_(random_id), message_id_(message_id), date_(date) {
}
static constexpr int32 ID = 1234567890;
int32 get_id() const override {
return ID;
}
void store(TlStorerUnsafe &s) const override {
UNREACHABLE();
}
void store(TlStorerCalcLength &s) const override {
UNREACHABLE();
}
void store(TlStorerToString &s, const char *field_name) const override {
s.store_class_begin(field_name, "updateSentMessage");
s.store_field("random_id", random_id_);
s.store_field("message_id", message_id_.get());
s.store_field("date", date_);
s.store_class_end();
}
};
class MessagesManager : public Actor {
public:
// static constexpr int32 MESSAGE_FLAG_IS_UNREAD = 1 << 0;
@ -792,10 +741,10 @@ class MessagesManager : public Actor {
tl_object_ptr<td_api::messages> get_messages_object(int32 total_count, const vector<FullMessageId> &full_message_ids,
bool skip_not_found);
int32 get_min_pending_pts() const;
void process_pts_update(tl_object_ptr<telegram_api::Update> &&update);
void add_pending_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 pts_count,
bool force_apply, Promise<Unit> &&promise, const char *source);
void skip_old_pending_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 old_pts,
int32 pts_count, const char *source);
void add_pending_channel_update(DialogId dialog_id, tl_object_ptr<telegram_api::Update> &&update, int32 new_pts,
int32 pts_count, Promise<Unit> &&promise, const char *source,
@ -1732,7 +1681,7 @@ class MessagesManager : public Actor {
static constexpr const char *DELETE_MESSAGE_USER_REQUEST_SOURCE = "user request";
static constexpr bool DROP_UPDATES = false;
static constexpr bool DROP_SEND_MESSAGE_UPDATES = false;
void memory_cleanup(bool full);
@ -1832,10 +1781,6 @@ class MessagesManager : public Actor {
bool can_set_game_score(DialogId dialog_id, const Message *m) const;
bool check_update_dialog_id(const tl_object_ptr<telegram_api::Update> &update, DialogId dialog_id);
void process_update(tl_object_ptr<telegram_api::Update> &&update);
void process_channel_update(tl_object_ptr<telegram_api::Update> &&update);
void on_message_edited(FullMessageId full_message_id, int32 pts);
@ -2068,7 +2013,7 @@ class MessagesManager : public Actor {
static void set_message_id(unique_ptr<Message> &message, MessageId message_id);
bool is_allowed_useless_update(const tl_object_ptr<telegram_api::Update> &update) const;
static bool is_allowed_useless_update(const tl_object_ptr<telegram_api::Update> &update);
bool is_message_auto_read(DialogId dialog_id, bool is_outgoing) const;
@ -2795,18 +2740,6 @@ class MessagesManager : public Actor {
void load_notification_settings();
void set_get_difference_timeout(double timeout);
void skip_old_pending_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 old_pts,
int32 pts_count, const char *source);
void process_pending_updates();
void drop_pending_updates();
void postpone_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 pts, int32 pts_count,
Promise<Unit> &&promise);
static string get_channel_pts_key(DialogId dialog_id);
int32 load_channel_pts(DialogId dialog_id) const;
@ -3019,10 +2952,7 @@ class MessagesManager : public Actor {
std::shared_ptr<UploadThumbnailCallback> upload_thumbnail_callback_;
std::shared_ptr<UploadDialogPhotoCallback> upload_dialog_photo_callback_;
int32 accumulated_pts_count_ = 0;
int32 accumulated_pts_ = -1;
Timeout pts_gap_timeout_;
double last_pts_jump_warning_time_ = 0;
double last_channel_pts_jump_warning_time_ = 0;
std::unordered_map<FileId, std::pair<FullMessageId, FileId>, FileIdHash>
being_uploaded_files_; // file_id -> message, thumbnail_file_id
@ -3121,8 +3051,6 @@ class MessagesManager : public Actor {
bool running_get_difference_ = false; // true after before_get_difference and false after after_get_difference
std::unordered_map<DialogId, unique_ptr<Dialog>, DialogIdHash> dialogs_;
std::multimap<int32, PendingPtsUpdate> pending_pts_updates_;
std::multimap<int32, PendingPtsUpdate> postponed_pts_updates_;
std::unordered_set<DialogId, DialogIdHash>
loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_

View File

@ -100,9 +100,9 @@ class SearchStickersQuery : public Td::ResultHandler {
string emoji_;
public:
void send(string emoji) {
void send(string emoji, int32 hash) {
emoji_ = std::move(emoji);
send_query(G()->net_query_creator().create(telegram_api::messages_getStickers(emoji_, 0)));
send_query(G()->net_query_creator().create(telegram_api::messages_getStickers(emoji_, hash)));
}
void on_result(uint64 id, BufferSlice packet) override {
@ -3084,16 +3084,21 @@ vector<FileId> StickersManager::search_stickers(string emoji, int32 limit, Promi
}
auto it = found_stickers_.find(emoji);
if (it != found_stickers_.end()) {
if (it != found_stickers_.end() && Time::now() < it->second.next_reload_time_) {
promise.set_value(Unit());
auto result_size = min(static_cast<size_t>(limit), it->second.size());
return vector<FileId>(it->second.begin(), it->second.begin() + result_size);
const auto &sticker_ids = it->second.sticker_ids_;
auto result_size = min(static_cast<size_t>(limit), sticker_ids.size());
return vector<FileId>(sticker_ids.begin(), sticker_ids.begin() + result_size);
}
auto &promises = search_stickers_queries_[emoji];
promises.push_back(std::move(promise));
if (promises.size() == 1u) {
td_->create_handler<SearchStickersQuery>()->send(std::move(emoji));
int32 hash = 0;
if (it != found_stickers_.end()) {
hash = get_recent_stickers_hash(it->second.sticker_ids_);
}
td_->create_handler<SearchStickersQuery>()->send(std::move(emoji), hash);
}
return {};
@ -3103,17 +3108,27 @@ void StickersManager::on_find_stickers_success(const string &emoji,
tl_object_ptr<telegram_api::messages_Stickers> &&stickers) {
CHECK(stickers != nullptr);
switch (stickers->get_id()) {
case telegram_api::messages_stickersNotModified::ID:
return on_find_stickers_fail(emoji, Status::Error(500, "Receive messages.stickerNotModified"));
case telegram_api::messages_stickersNotModified::ID: {
auto it = found_stickers_.find(emoji);
if (it == found_stickers_.end()) {
return on_find_stickers_fail(emoji, Status::Error(500, "Receive messages.stickerNotModified"));
}
auto &found_stickers = it->second;
found_stickers.next_reload_time_ = Time::now() + found_stickers.cache_time_;
break;
}
case telegram_api::messages_stickers::ID: {
auto found_stickers = move_tl_object_as<telegram_api::messages_stickers>(stickers);
vector<FileId> &sticker_ids = found_stickers_[emoji];
CHECK(sticker_ids.empty());
auto received_stickers = move_tl_object_as<telegram_api::messages_stickers>(stickers);
for (auto &sticker : found_stickers->stickers_) {
auto &found_stickers = found_stickers_[emoji];
found_stickers.cache_time_ = 300;
found_stickers.next_reload_time_ = Time::now() + found_stickers.cache_time_;
found_stickers.sticker_ids_.clear();
for (auto &sticker : received_stickers->stickers_) {
FileId sticker_id = on_get_sticker_document(std::move(sticker)).second;
if (sticker_id.is_valid()) {
sticker_ids.push_back(sticker_id);
found_stickers.sticker_ids_.push_back(sticker_id);
}
}
break;
@ -3134,7 +3149,10 @@ void StickersManager::on_find_stickers_success(const string &emoji,
}
void StickersManager::on_find_stickers_fail(const string &emoji, Status &&error) {
CHECK(found_stickers_.count(emoji) == 0);
if (found_stickers_.count(emoji) != 0) {
found_stickers_[emoji].cache_time_ = Random::fast(40, 80);
return on_find_stickers_success(emoji, make_tl_object<telegram_api::messages_stickersNotModified>());
}
auto it = search_stickers_queries_.find(emoji);
CHECK(it != search_stickers_queries_.end());

View File

@ -682,7 +682,12 @@ class StickersManager : public Actor {
Hints installed_sticker_sets_hints_[2]; // search installed sticker sets by their title and name
std::unordered_map<string, vector<FileId>> found_stickers_;
struct FoundStickers {
vector<FileId> sticker_ids_;
int32 cache_time_ = 300;
double next_reload_time_ = 0;
};
std::unordered_map<string, FoundStickers> found_stickers_;
std::unordered_map<string, vector<Promise<Unit>>> search_stickers_queries_;
std::unordered_map<string, vector<StickerSetId>> found_sticker_sets_;

View File

@ -736,7 +736,7 @@ class GetGroupFullInfoRequest : public RequestActor<> {
ChatId chat_id_;
void do_run(Promise<Unit> &&promise) override {
td->contacts_manager_->load_chat_full(chat_id_, get_tries() < 2, std::move(promise));
td->contacts_manager_->load_chat_full(chat_id_, get_tries() < 2, std::move(promise), "getBasicGroupFullInfo");
}
void do_send_result() override {
@ -4289,11 +4289,11 @@ Status Td::init(DbKey key) {
}
if (is_online_) {
if (auth_manager_->is_bot()) {
send_closure(G()->state_manager(), &StateManager::on_online, false);
}
on_online_updated(true, true);
}
if (auth_manager_->is_bot()) {
send_closure(G()->state_manager(), &StateManager::on_online, true);
}
// Send binlog events to managers
//

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@
#include "td/telegram/ChatId.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/InputGroupCallId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/PtsManager.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
@ -20,6 +21,7 @@
#include "td/utils/common.h"
#include "td/utils/logging.h"
#include "td/utils/tl_storers.h"
#include <map>
#include <unordered_set>
@ -30,15 +32,67 @@ extern int VERBOSITY_NAME(get_difference);
class Td;
class dummyUpdate : public telegram_api::Update {
public:
static constexpr int32 ID = 1234567891;
int32 get_id() const override {
return ID;
}
void store(TlStorerUnsafe &s) const override {
UNREACHABLE();
}
void store(TlStorerCalcLength &s) const override {
UNREACHABLE();
}
void store(TlStorerToString &s, const char *field_name) const override {
s.store_class_begin(field_name, "dummyUpdate");
s.store_class_end();
}
};
class updateSentMessage : public telegram_api::Update {
public:
int64 random_id_;
MessageId message_id_;
int32 date_;
updateSentMessage(int64 random_id, MessageId message_id, int32 date)
: random_id_(random_id), message_id_(message_id), date_(date) {
}
static constexpr int32 ID = 1234567890;
int32 get_id() const override {
return ID;
}
void store(TlStorerUnsafe &s) const override {
UNREACHABLE();
}
void store(TlStorerCalcLength &s) const override {
UNREACHABLE();
}
void store(TlStorerToString &s, const char *field_name) const override {
s.store_class_begin(field_name, "updateSentMessage");
s.store_field("random_id", random_id_);
s.store_field("message_id", message_id_.get());
s.store_field("date", date_);
s.store_class_end();
}
};
class UpdatesManager : public Actor {
public:
UpdatesManager(Td *td, ActorShared<> parent);
void on_get_updates(tl_object_ptr<telegram_api::Updates> &&updates_ptr, Promise<Unit> &&promise);
void on_get_updates_state(tl_object_ptr<telegram_api::updates_state> &&state, const char *source);
void on_get_difference(tl_object_ptr<telegram_api::updates_Difference> &&difference_ptr);
void add_pending_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 new_pts, int32 pts_count,
Promise<Unit> &&promise, const char *source);
static std::unordered_set<int64> get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr);
@ -57,38 +111,32 @@ class UpdatesManager : public Actor {
void schedule_get_difference(const char *source);
void init_state();
void ping_server();
void on_server_pong(tl_object_ptr<telegram_api::updates_state> &&state);
int32 get_pts() const {
return pts_manager_.mem_pts();
}
int32 get_qts() const {
return qts_manager_.mem_pts();
}
int32 get_date() const {
return date_;
}
Promise<> set_pts(int32 pts, const char *source) TD_WARN_UNUSED_RESULT;
static const double MAX_UNFILLED_GAP_TIME;
static void fill_pts_gap(void *td);
bool running_get_difference() const {
return running_get_difference_;
}
private:
static constexpr int32 FORCED_GET_DIFFERENCE_PTS_DIFF = 100000;
static const double MAX_UNFILLED_GAP_TIME;
static constexpr bool DROP_PTS_UPDATES = false;
friend class OnUpdate;
class PendingUpdates {
class PendingPtsUpdate {
public:
tl_object_ptr<telegram_api::Update> update;
int32 pts;
int32 pts_count;
Promise<Unit> promise;
PendingPtsUpdate(tl_object_ptr<telegram_api::Update> &&update, int32 pts, int32 pts_count, Promise<Unit> &&promise)
: update(std::move(update)), pts(pts), pts_count(pts_count), promise(std::move(promise)) {
}
};
class PendingSeqUpdates {
public:
int32 seq_begin;
int32 seq_end;
@ -96,8 +144,8 @@ class UpdatesManager : public Actor {
vector<tl_object_ptr<telegram_api::Update>> updates;
Promise<Unit> promise;
PendingUpdates(int32 seq_begin, int32 seq_end, int32 date, vector<tl_object_ptr<telegram_api::Update>> &&updates,
Promise<Unit> &&promise)
PendingSeqUpdates(int32 seq_begin, int32 seq_end, int32 date, vector<tl_object_ptr<telegram_api::Update>> &&updates,
Promise<Unit> &&promise)
: seq_begin(seq_begin), seq_end(seq_end), date(date), updates(std::move(updates)), promise(std::move(promise)) {
}
};
@ -119,11 +167,20 @@ class UpdatesManager : public Actor {
int32 short_update_date_ = 0;
std::multimap<int32, PendingUpdates> postponed_updates_; // updates received during getDifference
std::multimap<int32, PendingUpdates> pending_seq_updates_; // updates with too big seq
int32 accumulated_pts_count_ = 0;
int32 accumulated_pts_ = -1;
double last_pts_jump_warning_time_ = 0;
std::multimap<int32, PendingPtsUpdate> pending_pts_updates_;
std::multimap<int32, PendingPtsUpdate> postponed_pts_updates_;
std::multimap<int32, PendingSeqUpdates> postponed_updates_; // updates received during getDifference
std::multimap<int32, PendingSeqUpdates> pending_seq_updates_; // updates with too big seq
std::map<int32, PendingQtsUpdate> pending_qts_updates_; // updates with too big qts
Timeout pts_gap_timeout_;
Timeout seq_gap_timeout_;
Timeout qts_gap_timeout_;
@ -139,6 +196,17 @@ class UpdatesManager : public Actor {
void tear_down() override;
int32 get_pts() const {
return pts_manager_.mem_pts();
}
int32 get_qts() const {
return qts_manager_.mem_pts();
}
int32 get_date() const {
return date_;
}
Promise<> set_pts(int32 pts, const char *source) TD_WARN_UNUSED_RESULT;
Promise<> add_pts(int32 pts);
void on_pts_ack(PtsManager::PtsId ack_token);
void save_pts(int32 pts);
@ -151,6 +219,14 @@ class UpdatesManager : public Actor {
int32 get_short_update_date() const;
void init_state();
void on_get_updates_state(tl_object_ptr<telegram_api::updates_state> &&state, const char *source);
void on_server_pong(tl_object_ptr<telegram_api::updates_state> &&state);
void on_get_difference(tl_object_ptr<telegram_api::updates_Difference> &&difference_ptr);
void process_get_difference_updates(vector<tl_object_ptr<telegram_api::Message>> &&new_messages,
vector<tl_object_ptr<telegram_api::EncryptedMessage>> &&new_encrypted_messages,
vector<tl_object_ptr<telegram_api::Update>> &&other_updates);
@ -166,15 +242,26 @@ class UpdatesManager : public Actor {
void process_updates(vector<tl_object_ptr<telegram_api::Update>> &&updates, bool force_apply,
Promise<Unit> &&promise);
void postpone_pts_update(tl_object_ptr<telegram_api::Update> &&update, int32 pts, int32 pts_count,
Promise<Unit> &&promise);
void process_pts_update(tl_object_ptr<telegram_api::Update> &&update);
void process_seq_updates(int32 seq_end, int32 date, vector<tl_object_ptr<telegram_api::Update>> &&updates,
Promise<Unit> &&promise);
void process_qts_update(tl_object_ptr<telegram_api::Update> &&update_ptr, int32 qts, Promise<Unit> &&promise);
void process_pending_pts_updates();
void process_pending_seq_updates();
void process_pending_qts_updates();
void drop_pending_pts_updates();
static void fill_pts_gap(void *td);
static void fill_seq_gap(void *td);
static void fill_qts_gap(void *td);
@ -183,22 +270,36 @@ class UpdatesManager : public Actor {
static void fill_gap(void *td, const char *source);
void set_pts_gap_timeout(double timeout);
void set_seq_gap_timeout(double timeout);
void set_qts_gap_timeout(double timeout);
void run_get_difference(bool is_recursive, const char *source);
void on_failed_get_difference();
void on_failed_get_updates_state(Status &&error);
void on_failed_get_difference(Status &&error);
void before_get_difference(bool is_initial);
void after_get_difference();
int32 get_min_pending_pts() const;
static bool have_update_pts_changed(const vector<tl_object_ptr<telegram_api::Update>> &updates);
static bool check_pts_update_dialog_id(DialogId dialog_id);
static bool check_pts_update(const tl_object_ptr<telegram_api::Update> &update);
static bool is_pts_update(const telegram_api::Update *update);
static int32 get_update_pts(const telegram_api::Update *update);
static bool is_qts_update(const telegram_api::Update *update);
static int32 get_update_qts(const telegram_api::Update *update);
static const vector<tl_object_ptr<telegram_api::Update>> *get_updates(const telegram_api::Updates *updates_ptr);
@ -223,185 +324,133 @@ class UpdatesManager : public Actor {
bool is_acceptable_update(const telegram_api::Update *update) const;
void on_update(tl_object_ptr<telegram_api::updateNewMessage> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateMessageID> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadMessagesContents> update, bool force_apply,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEditMessage> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDeleteMessages> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadHistoryInbox> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadHistoryOutbox> update, bool force_apply,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNotifySettings> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePeerSettings> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePeerLocated> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateMessageID> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadMessagesContents> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEditMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDeleteMessages> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadHistoryInbox> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadHistoryOutbox> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNotifySettings> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePeerSettings> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePeerLocated> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateWebPage> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelWebPage> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateWebPage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelWebPage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateFolderPeers> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateFolderPeers> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserTyping> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatUserTyping> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelUserTyping> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEncryptedChatTyping> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserTyping> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatUserTyping> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelUserTyping> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEncryptedChatTyping> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserStatus> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserName> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserPhone> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserPhoto> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserStatus> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserName> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserPhone> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateUserPhoto> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePeerBlocked> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePeerBlocked> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipants> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipantAdd> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipantAdmin> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipantDelete> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipants> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipantAdd> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipantAdmin> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatParticipantDelete> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatDefaultBannedRights> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChatDefaultBannedRights> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateServiceNotification> update, bool force_apply,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateServiceNotification> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDcOptions> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDcOptions> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChat> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChat> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewChannelMessage> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelInbox> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelOutbox> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelReadMessagesContents> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelTooLong> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannel> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEditChannelMessage> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDeleteChannelMessages> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelMessageViews> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelMessageForwards> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelAvailableMessages> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewChannelMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelInbox> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelOutbox> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelReadMessagesContents> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelTooLong> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannel> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEditChannelMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDeleteChannelMessages> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelMessageViews> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelMessageForwards> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelAvailableMessages> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelDiscussionInbox> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelDiscussionOutbox> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelDiscussionInbox> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadChannelDiscussionOutbox> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePinnedMessages> update, bool force_apply, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePinnedChannelMessages> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePinnedMessages> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePinnedChannelMessages> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDraftMessage> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDraftMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogPinned> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePinnedDialogs> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogUnreadMark> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogPinned> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePinnedDialogs> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogUnreadMark> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogFilter> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogFilters> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogFilterOrder> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogFilter> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogFilters> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDialogFilterOrder> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotInlineQuery> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotInlineSend> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotInlineQuery> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotInlineSend> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotCallbackQuery> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateInlineBotCallbackQuery> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotCallbackQuery> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateInlineBotCallbackQuery> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateFavedStickers> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateFavedStickers> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateSavedGifs> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateSavedGifs> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateConfig> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateConfig> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePtsChanged> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePtsChanged> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePrivacy> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePrivacy> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEncryption> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewEncryptedMessage> update, bool force_apply,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEncryptedMessagesRead> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEncryption> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewEncryptedMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateEncryptedMessagesRead> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewStickerSet> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateStickerSets> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateStickerSetsOrder> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadFeaturedStickers> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateRecentStickers> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewStickerSet> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateStickerSets> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateStickerSetsOrder> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateReadFeaturedStickers> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateRecentStickers> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotShippingQuery> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotPrecheckoutQuery> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotShippingQuery> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotPrecheckoutQuery> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotWebhookJSON> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotWebhookJSONQuery> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotWebhookJSON> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateBotWebhookJSONQuery> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePhoneCall> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePhoneCallSignalingData> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePhoneCall> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updatePhoneCallSignalingData> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateGroupCall> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateGroupCallParticipants> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateGroupCall> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateGroupCallParticipants> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateContactsReset> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateContactsReset> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateLangPackTooLong> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateLangPack> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateLangPackTooLong> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateLangPack> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateGeoLiveViewed> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateGeoLiveViewed> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateMessagePoll> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateMessagePollVote> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateMessagePoll> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateMessagePollVote> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewScheduledMessage> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDeleteScheduledMessages> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateNewScheduledMessage> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateDeleteScheduledMessages> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateLoginToken> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateLoginToken> update, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelParticipant> update, bool /*force_apply*/,
Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateChannelParticipant> update, Promise<Unit> &&promise);
// unsupported updates
void on_update(tl_object_ptr<telegram_api::updateTheme> update, bool /*force_apply*/, Promise<Unit> &&promise);
void on_update(tl_object_ptr<telegram_api::updateTheme> update, Promise<Unit> &&promise);
};
} // namespace td

View File

@ -717,7 +717,7 @@ class CliClient final : public Actor {
case td_api::stickerSets::ID: {
auto sticker_sets = static_cast<const td_api::stickerSets *>(result.get());
result_str = PSTRING() << "StickerSets { total_count = " << sticker_sets->total_count_
<< ", count = " << sticker_sets->sets_.size() << "}";
<< ", count = " << sticker_sets->sets_.size() << " }";
break;
}
default: