Merge remote-tracking branch 'td/master'
This commit is contained in:
commit
a580242be1
@ -46,20 +46,19 @@ static Result<typename T::ReturnType> fetch_result(Slice message, bool check_end
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
AuthKeyHandshake::AuthKeyHandshake(int32 dc_id, int32 expires_in)
|
||||
: mode_(expires_in == 0 ? Mode::Main : Mode::Temp), dc_id_(dc_id), expires_in_(expires_in) {
|
||||
}
|
||||
|
||||
void AuthKeyHandshake::clear() {
|
||||
last_query_ = BufferSlice();
|
||||
state_ = Start;
|
||||
}
|
||||
|
||||
bool AuthKeyHandshake::is_ready_for_start() const {
|
||||
return state_ == Start;
|
||||
}
|
||||
bool AuthKeyHandshake::is_ready_for_message(const UInt128 &message_nonce) const {
|
||||
return state_ != Finish && state_ != Start && nonce_ == message_nonce;
|
||||
}
|
||||
bool AuthKeyHandshake::is_ready_for_finish() const {
|
||||
return state_ == Finish;
|
||||
}
|
||||
|
||||
void AuthKeyHandshake::on_finish() {
|
||||
clear();
|
||||
}
|
||||
@ -105,7 +104,6 @@ Status AuthKeyHandshake::on_res_pq(Slice message, Callback *connection, PublicRs
|
||||
dc_id_, expires_in_));
|
||||
expires_at_ = Time::now() + expires_in_;
|
||||
break;
|
||||
case Mode::Unknown:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -266,17 +264,6 @@ void AuthKeyHandshake::do_send(Callback *connection, const Storer &storer) {
|
||||
return connection->send_no_crypto(storer);
|
||||
}
|
||||
|
||||
Status AuthKeyHandshake::start_main(Callback *connection) {
|
||||
mode_ = Mode::Main;
|
||||
return on_start(connection);
|
||||
}
|
||||
|
||||
Status AuthKeyHandshake::start_tmp(Callback *connection, int32 expires_in) {
|
||||
mode_ = Mode::Temp;
|
||||
expires_in_ = expires_in;
|
||||
return on_start(connection);
|
||||
}
|
||||
|
||||
void AuthKeyHandshake::resume(Callback *connection) {
|
||||
if (state_ == Start) {
|
||||
return on_start(connection).ignore();
|
||||
@ -289,7 +276,7 @@ void AuthKeyHandshake::resume(Callback *connection) {
|
||||
LOG(ERROR) << "Last query empty! UNREACHABLE " << state_;
|
||||
return clear();
|
||||
}
|
||||
LOG(INFO) << "RESUME";
|
||||
LOG(INFO) << "Resume handshake";
|
||||
do_send(connection, create_storer(last_query_.as_slice()));
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,6 @@ class AuthKeyHandshakeContext {
|
||||
};
|
||||
|
||||
class AuthKeyHandshake {
|
||||
enum class Mode { Unknown, Main, Temp };
|
||||
|
||||
public:
|
||||
class Callback {
|
||||
public:
|
||||
@ -45,44 +43,16 @@ class AuthKeyHandshake {
|
||||
virtual void send_no_crypto(const Storer &storer) = 0;
|
||||
};
|
||||
|
||||
AuthKeyHandshake(int32 dc_id, int32 expires_in) {
|
||||
dc_id_ = dc_id;
|
||||
if (expires_in == 0) {
|
||||
mode_ = Mode::Main;
|
||||
} else {
|
||||
mode_ = Mode::Temp;
|
||||
expires_in_ = expires_in;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_ready_for_start() const;
|
||||
Status start_main(Callback *connection) TD_WARN_UNUSED_RESULT;
|
||||
Status start_tmp(Callback *connection, int32 expires_in) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
bool is_ready_for_message(const UInt128 &message_nonce) const;
|
||||
AuthKeyHandshake(int32 dc_id, int32 expires_in);
|
||||
|
||||
bool is_ready_for_finish() const;
|
||||
|
||||
void on_finish();
|
||||
|
||||
void init_main() {
|
||||
clear();
|
||||
mode_ = Mode::Main;
|
||||
}
|
||||
|
||||
void init_temp(int32 expires_in) {
|
||||
clear();
|
||||
mode_ = Mode::Temp;
|
||||
expires_in_ = expires_in;
|
||||
}
|
||||
|
||||
void resume(Callback *connection);
|
||||
|
||||
Status on_message(Slice message, Callback *connection, AuthKeyHandshakeContext *context) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
bool is_ready() const {
|
||||
return is_ready_for_finish();
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
const AuthKey &get_auth_key() const {
|
||||
@ -102,9 +72,10 @@ class AuthKeyHandshake {
|
||||
}
|
||||
|
||||
private:
|
||||
using State = enum { Start, ResPQ, ServerDHParams, DHGenResponse, Finish };
|
||||
enum State : int32 { Start, ResPQ, ServerDHParams, DHGenResponse, Finish };
|
||||
State state_ = Start;
|
||||
Mode mode_ = Mode::Unknown;
|
||||
enum class Mode : int32 { Main, Temp };
|
||||
Mode mode_ = Mode::Main;
|
||||
int32 dc_id_ = 0;
|
||||
int32 expires_in_ = 0;
|
||||
double expires_at_ = 0;
|
||||
|
@ -8416,13 +8416,14 @@ void ContactsManager::load_user_from_database_impl(UserId user_id, Promise<Unit>
|
||||
G()->td_db()->get_sqlite_pmc()->get(get_user_database_key(user_id), PromiseCreator::lambda([user_id](string value) {
|
||||
send_closure(G()->contacts_manager(),
|
||||
&ContactsManager::on_load_user_from_database, user_id,
|
||||
std::move(value));
|
||||
std::move(value), false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_load_user_from_database(UserId user_id, string value) {
|
||||
if (G()->close_flag()) {
|
||||
void ContactsManager::on_load_user_from_database(UserId user_id, string value, bool force) {
|
||||
if (G()->close_flag() && !force) {
|
||||
// the user is in Binlog and will be saved after restart
|
||||
return;
|
||||
}
|
||||
|
||||
@ -8554,7 +8555,7 @@ ContactsManager::User *ContactsManager::get_user_force_impl(UserId user_id) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "Trying to load " << user_id << " from database";
|
||||
on_load_user_from_database(user_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_user_database_key(user_id)));
|
||||
on_load_user_from_database(user_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_user_database_key(user_id)), true);
|
||||
return get_user(user_id);
|
||||
}
|
||||
|
||||
@ -8709,13 +8710,14 @@ void ContactsManager::load_chat_from_database_impl(ChatId chat_id, Promise<Unit>
|
||||
G()->td_db()->get_sqlite_pmc()->get(get_chat_database_key(chat_id), PromiseCreator::lambda([chat_id](string value) {
|
||||
send_closure(G()->contacts_manager(),
|
||||
&ContactsManager::on_load_chat_from_database, chat_id,
|
||||
std::move(value));
|
||||
std::move(value), false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_load_chat_from_database(ChatId chat_id, string value) {
|
||||
if (G()->close_flag()) {
|
||||
void ContactsManager::on_load_chat_from_database(ChatId chat_id, string value, bool force) {
|
||||
if (G()->close_flag() && !force) {
|
||||
// the chat is in Binlog and will be saved after restart
|
||||
return;
|
||||
}
|
||||
|
||||
@ -8791,7 +8793,7 @@ ContactsManager::Chat *ContactsManager::get_chat_force(ChatId chat_id) {
|
||||
}
|
||||
|
||||
LOG(INFO) << "Trying to load " << chat_id << " from database";
|
||||
on_load_chat_from_database(chat_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_chat_database_key(chat_id)));
|
||||
on_load_chat_from_database(chat_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_chat_database_key(chat_id)), true);
|
||||
return get_chat(chat_id);
|
||||
}
|
||||
|
||||
@ -8947,13 +8949,14 @@ void ContactsManager::load_channel_from_database_impl(ChannelId channel_id, Prom
|
||||
G()->td_db()->get_sqlite_pmc()->get(
|
||||
get_channel_database_key(channel_id), PromiseCreator::lambda([channel_id](string value) {
|
||||
send_closure(G()->contacts_manager(), &ContactsManager::on_load_channel_from_database, channel_id,
|
||||
std::move(value));
|
||||
std::move(value), false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string value) {
|
||||
if (G()->close_flag()) {
|
||||
void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string value, bool force) {
|
||||
if (G()->close_flag() && !force) {
|
||||
// the channel is in Binlog and will be saved after restart
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9044,7 +9047,7 @@ ContactsManager::Channel *ContactsManager::get_channel_force(ChannelId channel_i
|
||||
|
||||
LOG(INFO) << "Trying to load " << channel_id << " from database";
|
||||
on_load_channel_from_database(channel_id,
|
||||
G()->td_db()->get_sqlite_sync_pmc()->get(get_channel_database_key(channel_id)));
|
||||
G()->td_db()->get_sqlite_sync_pmc()->get(get_channel_database_key(channel_id)), true);
|
||||
return get_channel(channel_id);
|
||||
}
|
||||
|
||||
@ -9202,13 +9205,14 @@ void ContactsManager::load_secret_chat_from_database_impl(SecretChatId secret_ch
|
||||
G()->td_db()->get_sqlite_pmc()->get(
|
||||
get_secret_chat_database_key(secret_chat_id), PromiseCreator::lambda([secret_chat_id](string value) {
|
||||
send_closure(G()->contacts_manager(), &ContactsManager::on_load_secret_chat_from_database, secret_chat_id,
|
||||
std::move(value));
|
||||
std::move(value), false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsManager::on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value) {
|
||||
if (G()->close_flag()) {
|
||||
void ContactsManager::on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value, bool force) {
|
||||
if (G()->close_flag() && !force) {
|
||||
// the secret chat is in Binlog and will be saved after restart
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9285,7 +9289,7 @@ ContactsManager::SecretChat *ContactsManager::get_secret_chat_force(SecretChatId
|
||||
|
||||
LOG(INFO) << "Trying to load " << secret_chat_id << " from database";
|
||||
on_load_secret_chat_from_database(
|
||||
secret_chat_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_secret_chat_database_key(secret_chat_id)));
|
||||
secret_chat_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_secret_chat_database_key(secret_chat_id)), true);
|
||||
return get_secret_chat(secret_chat_id);
|
||||
}
|
||||
|
||||
@ -14686,68 +14690,81 @@ void ContactsManager::ban_dialog_participant(DialogId dialog_id,
|
||||
}
|
||||
}
|
||||
|
||||
DialogParticipant ContactsManager::get_dialog_participant(DialogId dialog_id,
|
||||
const tl_object_ptr<td_api::MessageSender> &participant_id,
|
||||
int64 &random_id, bool force, Promise<Unit> &&promise) {
|
||||
// TODO TRY_RESULT_PROMISE(promise, participant_dialog_id, get_participant_dialog_id(participant_id));
|
||||
auto r_participant_dialog_id = get_participant_dialog_id(participant_id);
|
||||
if (r_participant_dialog_id.is_error()) {
|
||||
promise.set_error(r_participant_dialog_id.move_as_error());
|
||||
return {};
|
||||
}
|
||||
auto participant_dialog_id = r_participant_dialog_id.move_as_ok();
|
||||
void ContactsManager::get_dialog_participant(DialogId dialog_id,
|
||||
const tl_object_ptr<td_api::MessageSender> &participant_id,
|
||||
Promise<td_api::object_ptr<td_api::chatMember>> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, participant_dialog_id, get_participant_dialog_id(participant_id));
|
||||
|
||||
LOG(INFO) << "Receive GetChatMember request to get " << participant_dialog_id << " in " << dialog_id
|
||||
<< " with random_id " << random_id;
|
||||
auto new_promise = PromiseCreator::lambda(
|
||||
[actor_id = actor_id(this), promise = std::move(promise)](Result<DialogParticipant> &&result) mutable {
|
||||
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(result));
|
||||
send_closure(actor_id, &ContactsManager::finish_get_dialog_participant, std::move(dialog_participant),
|
||||
std::move(promise));
|
||||
});
|
||||
get_dialog_participant(dialog_id, participant_dialog_id, std::move(new_promise));
|
||||
}
|
||||
|
||||
void ContactsManager::finish_get_dialog_participant(DialogParticipant &&dialog_participant,
|
||||
Promise<td_api::object_ptr<td_api::chatMember>> &&promise) {
|
||||
if (G()->close_flag()) {
|
||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
||||
}
|
||||
|
||||
auto participant_dialog_id = dialog_participant.dialog_id;
|
||||
bool is_user = participant_dialog_id.get_type() == DialogType::User;
|
||||
if ((is_user && !have_user(participant_dialog_id.get_user_id())) ||
|
||||
(!is_user && !td_->messages_manager_->have_dialog(participant_dialog_id))) {
|
||||
return promise.set_error(Status::Error(400, "Member not found"));
|
||||
}
|
||||
|
||||
promise.set_value(get_chat_member_object(dialog_participant));
|
||||
}
|
||||
|
||||
void ContactsManager::get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id,
|
||||
Promise<DialogParticipant> &&promise) {
|
||||
LOG(INFO) << "Receive GetChatMember request to get " << participant_dialog_id << " in " << dialog_id;
|
||||
if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_dialog_participant")) {
|
||||
promise.set_error(Status::Error(3, "Chat not found"));
|
||||
return DialogParticipant();
|
||||
return promise.set_error(Status::Error(3, "Chat not found"));
|
||||
}
|
||||
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
if (participant_dialog_id == DialogId(get_my_id())) {
|
||||
promise.set_value(Unit());
|
||||
return {participant_dialog_id, dialog_id.get_user_id(), 0, DialogParticipantStatus::Member()};
|
||||
return promise.set_value(
|
||||
DialogParticipant{participant_dialog_id, dialog_id.get_user_id(), 0, DialogParticipantStatus::Member()});
|
||||
}
|
||||
if (participant_dialog_id == dialog_id) {
|
||||
promise.set_value(Unit());
|
||||
return {participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()};
|
||||
return promise.set_value(
|
||||
DialogParticipant{participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()});
|
||||
}
|
||||
|
||||
promise.set_error(Status::Error(3, "Member not found"));
|
||||
break;
|
||||
return promise.set_error(Status::Error(3, "Member not found"));
|
||||
case DialogType::Chat:
|
||||
if (participant_dialog_id.get_type() != DialogType::User) {
|
||||
promise.set_value(Unit());
|
||||
return DialogParticipant::left(participant_dialog_id);
|
||||
return promise.set_value(DialogParticipant::left(participant_dialog_id));
|
||||
}
|
||||
return get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), force,
|
||||
std::move(promise));
|
||||
return get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), std::move(promise));
|
||||
case DialogType::Channel:
|
||||
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, random_id, force,
|
||||
std::move(promise));
|
||||
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, std::move(promise));
|
||||
case DialogType::SecretChat: {
|
||||
auto peer_user_id = get_secret_chat_user_id(dialog_id.get_secret_chat_id());
|
||||
if (participant_dialog_id == DialogId(get_my_id())) {
|
||||
promise.set_value(Unit());
|
||||
return {participant_dialog_id, peer_user_id.is_valid() ? peer_user_id : get_my_id(), 0,
|
||||
DialogParticipantStatus::Member()};
|
||||
return promise.set_value(DialogParticipant{participant_dialog_id,
|
||||
peer_user_id.is_valid() ? peer_user_id : get_my_id(), 0,
|
||||
DialogParticipantStatus::Member()});
|
||||
}
|
||||
if (participant_dialog_id == DialogId(peer_user_id)) {
|
||||
promise.set_value(Unit());
|
||||
return {participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()};
|
||||
return promise.set_value(
|
||||
DialogParticipant{participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()});
|
||||
}
|
||||
|
||||
promise.set_error(Status::Error(3, "Member not found"));
|
||||
break;
|
||||
return promise.set_error(Status::Error(3, "Member not found"));
|
||||
}
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
promise.set_error(Status::Error(500, "Wrong chat type"));
|
||||
return promise.set_error(Status::Error(500, "Wrong chat type"));
|
||||
}
|
||||
return DialogParticipant();
|
||||
}
|
||||
|
||||
DialogParticipants ContactsManager::search_private_chat_participants(UserId my_user_id, UserId peer_user_id,
|
||||
@ -14874,22 +14891,43 @@ void ContactsManager::search_dialog_participants(DialogId dialog_id, const strin
|
||||
}
|
||||
}
|
||||
|
||||
DialogParticipant ContactsManager::get_chat_participant(ChatId chat_id, UserId user_id, bool force,
|
||||
Promise<Unit> &&promise) {
|
||||
void ContactsManager::get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise) {
|
||||
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), "get_chat_participant")) {
|
||||
return DialogParticipant();
|
||||
}
|
||||
// promise is already set
|
||||
|
||||
auto result = get_chat_participant(chat_id, user_id);
|
||||
if (result == nullptr) {
|
||||
return DialogParticipant::left(DialogId(user_id));
|
||||
auto c = get_chat(chat_id);
|
||||
if (c == nullptr) {
|
||||
return promise.set_error(Status::Error(6, "Group not found"));
|
||||
}
|
||||
|
||||
return *result;
|
||||
auto chat_full = get_chat_full_force(chat_id, "get_chat_participant");
|
||||
if (chat_full == nullptr || (td_->auth_manager_->is_bot() && is_chat_full_outdated(chat_full, c, chat_id))) {
|
||||
auto query_promise = PromiseCreator::lambda(
|
||||
[actor_id = actor_id(this), chat_id, user_id, promise = std::move(promise)](Result<Unit> &&result) mutable {
|
||||
TRY_STATUS_PROMISE(promise, std::move(result));
|
||||
send_closure(actor_id, &ContactsManager::finish_get_chat_participant, chat_id, user_id, std::move(promise));
|
||||
});
|
||||
send_get_chat_full_query(chat_id, std::move(query_promise), "get_chat_participant");
|
||||
}
|
||||
|
||||
if (is_chat_full_outdated(chat_full, c, chat_id)) {
|
||||
send_get_chat_full_query(chat_id, Auto(), "get_chat_participant lazy");
|
||||
}
|
||||
|
||||
finish_get_chat_participant(chat_id, user_id, std::move(promise));
|
||||
}
|
||||
|
||||
void ContactsManager::finish_get_chat_participant(ChatId chat_id, UserId user_id,
|
||||
Promise<DialogParticipant> &&promise) {
|
||||
if (G()->close_flag()) {
|
||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
||||
}
|
||||
|
||||
const auto *participant = get_chat_participant(chat_id, user_id);
|
||||
if (participant == nullptr) {
|
||||
return promise.set_value(DialogParticipant::left(DialogId(user_id)));
|
||||
}
|
||||
|
||||
promise.set_value(DialogParticipant(*participant));
|
||||
}
|
||||
|
||||
void ContactsManager::search_chat_participants(ChatId chat_id, const string &query, int32 limit,
|
||||
@ -14959,77 +14997,46 @@ void ContactsManager::do_search_chat_participants(ChatId chat_id, const string &
|
||||
})});
|
||||
}
|
||||
|
||||
DialogParticipant ContactsManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
|
||||
int64 &random_id, bool force, Promise<Unit> &&promise) {
|
||||
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id << " with random_id "
|
||||
<< random_id;
|
||||
if (random_id != 0) {
|
||||
// request has already been sent before
|
||||
auto it = received_channel_participant_.find(random_id);
|
||||
CHECK(it != received_channel_participant_.end());
|
||||
auto result = std::move(it->second);
|
||||
result.status.update_restrictions();
|
||||
received_channel_participant_.erase(it);
|
||||
promise.set_value(Unit());
|
||||
return result;
|
||||
}
|
||||
void ContactsManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
|
||||
Promise<DialogParticipant> &&promise) {
|
||||
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id;
|
||||
|
||||
auto input_peer = td_->messages_manager_->get_input_peer(participant_dialog_id, AccessRights::Read);
|
||||
if (input_peer == nullptr) {
|
||||
promise.set_error(Status::Error(6, "User not found"));
|
||||
return DialogParticipant();
|
||||
return promise.set_error(Status::Error(6, "User not found"));
|
||||
}
|
||||
|
||||
if (have_channel_participant_cache(channel_id)) {
|
||||
auto *participant = get_channel_participant_from_cache(channel_id, participant_dialog_id);
|
||||
if (participant != nullptr) {
|
||||
promise.set_value(Unit());
|
||||
return *participant;
|
||||
return promise.set_value(DialogParticipant{*participant});
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
random_id = Random::secure_int64();
|
||||
} while (random_id == 0 || received_channel_participant_.find(random_id) != received_channel_participant_.end());
|
||||
received_channel_participant_[random_id]; // reserve place for result
|
||||
|
||||
LOG(DEBUG) << "Get info about " << participant_dialog_id << " membership in the " << channel_id << " with random_id "
|
||||
<< random_id;
|
||||
|
||||
auto on_result_promise =
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), channel_id, random_id,
|
||||
promise = std::move(promise)](Result<DialogParticipant> r_dialog_participant) mutable {
|
||||
send_closure(actor_id, &ContactsManager::on_get_channel_participant, channel_id, random_id,
|
||||
std::move(r_dialog_participant), std::move(promise));
|
||||
});
|
||||
auto on_result_promise = PromiseCreator::lambda([actor_id = actor_id(this), channel_id, promise = std::move(promise)](
|
||||
Result<DialogParticipant> r_dialog_participant) mutable {
|
||||
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(r_dialog_participant));
|
||||
send_closure(actor_id, &ContactsManager::finish_get_channel_participant, channel_id, std::move(dialog_participant),
|
||||
std::move(promise));
|
||||
});
|
||||
|
||||
td_->create_handler<GetChannelParticipantQuery>(std::move(on_result_promise))
|
||||
->send(channel_id, participant_dialog_id, std::move(input_peer));
|
||||
return DialogParticipant();
|
||||
}
|
||||
|
||||
void ContactsManager::on_get_channel_participant(ChannelId channel_id, int64 random_id,
|
||||
Result<DialogParticipant> r_dialog_participant,
|
||||
Promise<Unit> &&promise) {
|
||||
void ContactsManager::finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
|
||||
Promise<DialogParticipant> &&promise) {
|
||||
if (G()->close_flag()) {
|
||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
||||
}
|
||||
|
||||
LOG(INFO) << "Receive a member of a channel " << channel_id << " with random_id " << random_id;
|
||||
LOG(INFO) << "Receive a member " << dialog_participant.dialog_id << " of a channel " << channel_id;
|
||||
|
||||
auto it = received_channel_participant_.find(random_id);
|
||||
CHECK(it != received_channel_participant_.end());
|
||||
|
||||
if (r_dialog_participant.is_error()) {
|
||||
received_channel_participant_.erase(it);
|
||||
promise.set_error(r_dialog_participant.move_as_error());
|
||||
} else {
|
||||
it->second = r_dialog_participant.move_as_ok();
|
||||
if (have_channel_participant_cache(channel_id)) {
|
||||
add_channel_participant_to_cache(channel_id, it->second, false);
|
||||
}
|
||||
promise.set_value(Unit());
|
||||
dialog_participant.status.update_restrictions();
|
||||
if (have_channel_participant_cache(channel_id)) {
|
||||
add_channel_participant_to_cache(channel_id, dialog_participant, false);
|
||||
}
|
||||
promise.set_value(std::move(dialog_participant));
|
||||
}
|
||||
|
||||
void ContactsManager::get_channel_participants(ChannelId channel_id,
|
||||
|
@ -524,9 +524,8 @@ class ContactsManager final : public Actor {
|
||||
void ban_dialog_participant(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
|
||||
int32 banned_until_date, bool revoke_messages, Promise<Unit> &&promise);
|
||||
|
||||
DialogParticipant get_dialog_participant(DialogId dialog_id,
|
||||
const tl_object_ptr<td_api::MessageSender> &participant_id, int64 &random_id,
|
||||
bool force, Promise<Unit> &&promise);
|
||||
void get_dialog_participant(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
|
||||
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
|
||||
|
||||
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter,
|
||||
Promise<DialogParticipants> &&promise);
|
||||
@ -1275,7 +1274,7 @@ class ContactsManager final : public Actor {
|
||||
void on_save_user_to_database(UserId user_id, bool success);
|
||||
void load_user_from_database(User *u, UserId user_id, Promise<Unit> promise);
|
||||
void load_user_from_database_impl(UserId user_id, Promise<Unit> promise);
|
||||
void on_load_user_from_database(UserId user_id, string value);
|
||||
void on_load_user_from_database(UserId user_id, string value, bool force);
|
||||
|
||||
void save_chat(Chat *c, ChatId chat_id, bool from_binlog);
|
||||
static string get_chat_database_key(ChatId chat_id);
|
||||
@ -1285,7 +1284,7 @@ class ContactsManager final : public Actor {
|
||||
void on_save_chat_to_database(ChatId chat_id, bool success);
|
||||
void load_chat_from_database(Chat *c, ChatId chat_id, Promise<Unit> promise);
|
||||
void load_chat_from_database_impl(ChatId chat_id, Promise<Unit> promise);
|
||||
void on_load_chat_from_database(ChatId chat_id, string value);
|
||||
void on_load_chat_from_database(ChatId chat_id, string value, bool force);
|
||||
|
||||
void save_channel(Channel *c, ChannelId channel_id, bool from_binlog);
|
||||
static string get_channel_database_key(ChannelId channel_id);
|
||||
@ -1295,7 +1294,7 @@ class ContactsManager final : public Actor {
|
||||
void on_save_channel_to_database(ChannelId channel_id, bool success);
|
||||
void load_channel_from_database(Channel *c, ChannelId channel_id, Promise<Unit> promise);
|
||||
void load_channel_from_database_impl(ChannelId channel_id, Promise<Unit> promise);
|
||||
void on_load_channel_from_database(ChannelId channel_id, string value);
|
||||
void on_load_channel_from_database(ChannelId channel_id, string value, bool force);
|
||||
|
||||
void save_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog);
|
||||
static string get_secret_chat_database_key(SecretChatId secret_chat_id);
|
||||
@ -1305,7 +1304,7 @@ class ContactsManager final : public Actor {
|
||||
void on_save_secret_chat_to_database(SecretChatId secret_chat_id, bool success);
|
||||
void load_secret_chat_from_database(SecretChat *c, SecretChatId secret_chat_id, Promise<Unit> promise);
|
||||
void load_secret_chat_from_database_impl(SecretChatId secret_chat_id, Promise<Unit> promise);
|
||||
void on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value);
|
||||
void on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value, bool force);
|
||||
|
||||
void save_user_full(const UserFull *user_full, UserId user_id);
|
||||
static string get_user_full_database_key(UserId user_id);
|
||||
@ -1414,10 +1413,20 @@ class ContactsManager final : public Actor {
|
||||
DialogParticipants search_private_chat_participants(UserId my_user_id, UserId peer_user_id, const string &query,
|
||||
int32 limit, DialogParticipantsFilter filter) const;
|
||||
|
||||
DialogParticipant get_chat_participant(ChatId chat_id, UserId user_id, bool force, Promise<Unit> &&promise);
|
||||
void get_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, Promise<DialogParticipant> &&promise);
|
||||
|
||||
DialogParticipant get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id, int64 &random_id,
|
||||
bool force, Promise<Unit> &&promise);
|
||||
void finish_get_dialog_participant(DialogParticipant &&dialog_participant,
|
||||
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
|
||||
|
||||
void get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise);
|
||||
|
||||
void finish_get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise);
|
||||
|
||||
void get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
|
||||
Promise<DialogParticipant> &&promise);
|
||||
|
||||
void finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
|
||||
Promise<DialogParticipant> &&promise);
|
||||
|
||||
static string get_dialog_administrators_database_key(DialogId dialog_id);
|
||||
|
||||
@ -1480,9 +1489,6 @@ class ContactsManager final : public Actor {
|
||||
|
||||
void delete_chat_participant(ChatId chat_id, UserId user_id, bool revoke_messages, Promise<Unit> &&promise);
|
||||
|
||||
void on_get_channel_participant(ChannelId channel_id, int64 random_id, Result<DialogParticipant> r_dialog_participant,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter,
|
||||
Promise<DialogParticipants> &&promise);
|
||||
|
||||
@ -1655,8 +1661,6 @@ class ContactsManager final : public Actor {
|
||||
|
||||
std::unordered_map<int64, std::pair<vector<UserId>, vector<int32>>> imported_contacts_;
|
||||
|
||||
std::unordered_map<int64, DialogParticipant> received_channel_participant_;
|
||||
|
||||
std::unordered_map<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
|
||||
|
||||
// bot-administrators only
|
||||
|
@ -14616,6 +14616,7 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<te
|
||||
added_dialog_ids.push_back(dialog_id);
|
||||
Dialog *d = get_dialog_force(dialog_id, "on_get_dialogs");
|
||||
bool need_update_dialog_pos = false;
|
||||
CHECK(!being_added_dialog_id_.is_valid());
|
||||
being_added_dialog_id_ = dialog_id;
|
||||
if (d == nullptr) {
|
||||
d = add_dialog(dialog_id, "on_get_dialogs");
|
||||
@ -20552,7 +20553,7 @@ tl_object_ptr<td_api::messages> MessagesManager::get_dialog_history(DialogId dia
|
||||
if (from_the_end) {
|
||||
from_message_id = MessageId();
|
||||
}
|
||||
send_closure_later(actor_id(this), &MessagesManager::load_messages, d->dialog_id, from_message_id, offset,
|
||||
send_closure_later(actor_id(this), &MessagesManager::load_messages, dialog_id, from_message_id, offset,
|
||||
limit - static_cast<int32>(messages.size()), left_tries, only_local, std::move(promise));
|
||||
return nullptr;
|
||||
}
|
||||
@ -22221,7 +22222,7 @@ void MessagesManager::preload_newer_messages(const Dialog *d, MessageId max_mess
|
||||
if (limit > 0 && (d->last_message_id == MessageId() || max_message_id < d->last_message_id)) {
|
||||
// need to preload some new messages
|
||||
LOG(INFO) << "Preloading newer after " << max_message_id;
|
||||
load_messages(d->dialog_id, max_message_id, -MAX_GET_HISTORY + 1, MAX_GET_HISTORY, 3, false, Promise<Unit>());
|
||||
load_messages_impl(d, max_message_id, -MAX_GET_HISTORY + 1, MAX_GET_HISTORY, 3, false, Promise<Unit>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -22247,7 +22248,7 @@ void MessagesManager::preload_older_messages(const Dialog *d, MessageId min_mess
|
||||
if (limit > 0) {
|
||||
// need to preload some old messages
|
||||
LOG(INFO) << "Preloading older before " << min_message_id;
|
||||
load_messages(d->dialog_id, min_message_id, 0, MAX_GET_HISTORY / 2, 3, false, Promise<Unit>());
|
||||
load_messages_impl(d, min_message_id, 0, MAX_GET_HISTORY / 2, 3, false, Promise<Unit>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -22273,9 +22274,10 @@ unique_ptr<MessagesManager::Message> MessagesManager::parse_message(DialogId dia
|
||||
return m;
|
||||
}
|
||||
|
||||
void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, int32 offset,
|
||||
int32 limit, bool from_the_end, bool only_local,
|
||||
vector<BufferSlice> &&messages, Promise<Unit> &&promise) {
|
||||
void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId from_message_id,
|
||||
MessageId old_last_database_message_id, int32 offset, int32 limit,
|
||||
bool from_the_end, bool only_local, vector<BufferSlice> &&messages,
|
||||
Promise<Unit> &&promise) {
|
||||
CHECK(-limit < offset && offset <= 0);
|
||||
CHECK(offset < 0 || from_the_end);
|
||||
CHECK(!from_message_id.is_scheduled());
|
||||
@ -22302,6 +22304,17 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
||||
<< d->first_database_message_id << ", last database message is " << d->last_database_message_id
|
||||
<< ", have_full_history = " << d->have_full_history;
|
||||
|
||||
if (old_last_database_message_id < d->last_database_message_id && old_last_database_message_id < from_message_id) {
|
||||
// new messages where added to the database since the request was sent
|
||||
// they should have been received from the database, so we must repeat the request to get them
|
||||
if (from_the_end) {
|
||||
get_history_from_the_end_impl(d, true, only_local, std::move(promise));
|
||||
} else {
|
||||
get_history_impl(d, from_message_id, offset, limit, true, only_local, std::move(promise));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (messages.empty() && from_the_end && d->messages == nullptr) {
|
||||
if (d->have_full_history) {
|
||||
set_dialog_is_empty(d, "on_get_history_from_database empty");
|
||||
@ -22419,18 +22432,24 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
||||
if (last_received_message_id < d->last_database_message_id) {
|
||||
set_dialog_last_database_message_id(d, last_received_message_id, "on_get_history_from_database 12");
|
||||
|
||||
get_history_from_the_end(dialog_id, true, only_local, std::move(promise));
|
||||
get_history_from_the_end_impl(d, true, only_local, std::move(promise));
|
||||
return;
|
||||
}
|
||||
|
||||
if (limit > 1) {
|
||||
// we expected to have messages [first_database_message_id, last_database_message_id] in the database, but
|
||||
// received newer messages [last_received_message_id, ...], none of which can be added
|
||||
// received no messages or newer messages [last_received_message_id, ...], none of which can be added
|
||||
// first_database_message_id and last_database_message_id are very wrong, so it is better to drop them,
|
||||
// pretending that the database has no usable messages
|
||||
LOG(ERROR) << "Receive unusable messages up to " << last_received_message_id << " in " << dialog_id
|
||||
<< " from database from the end, but expected messages from " << d->last_database_message_id
|
||||
<< " up to " << d->first_database_message_id;
|
||||
if (last_received_message_id == MessageId::max()) {
|
||||
LOG(ERROR) << "Receive no usable messages in " << dialog_id
|
||||
<< " from database from the end, but expected messages from " << d->last_database_message_id
|
||||
<< " up to " << d->first_database_message_id;
|
||||
} else {
|
||||
LOG(ERROR) << "Receive " << messages.size() << " unusable messages up to " << last_received_message_id
|
||||
<< " in " << dialog_id << " from database from the end, but expected messages from "
|
||||
<< d->last_database_message_id << " up to " << d->first_database_message_id;
|
||||
}
|
||||
set_dialog_first_database_message_id(d, MessageId(), "on_get_history_from_database 13");
|
||||
set_dialog_last_database_message_id(d, MessageId(), "on_get_history_from_database 14");
|
||||
}
|
||||
@ -22441,7 +22460,7 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
||||
if (from_the_end) {
|
||||
from_message_id = MessageId();
|
||||
}
|
||||
load_messages(dialog_id, from_message_id, offset, limit, 1, false, std::move(promise));
|
||||
load_messages_impl(d, from_message_id, offset, limit, 1, false, std::move(promise));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -22496,14 +22515,21 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
||||
|
||||
void MessagesManager::get_history_from_the_end(DialogId dialog_id, bool from_database, bool only_local,
|
||||
Promise<Unit> &&promise) {
|
||||
CHECK(dialog_id.is_valid());
|
||||
if (G()->close_flag()) {
|
||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
||||
}
|
||||
get_history_from_the_end_impl(get_dialog(dialog_id), from_database, only_local, std::move(promise));
|
||||
}
|
||||
|
||||
void MessagesManager::get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local,
|
||||
Promise<Unit> &&promise) {
|
||||
CHECK(d != nullptr);
|
||||
|
||||
auto dialog_id = d->dialog_id;
|
||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
// can't get history in dialogs without read access
|
||||
return promise.set_value(Unit());
|
||||
}
|
||||
if (G()->close_flag()) {
|
||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
||||
}
|
||||
int32 limit = MAX_GET_HISTORY;
|
||||
if (from_database && G()->parameters().use_message_db) {
|
||||
if (!promise) {
|
||||
@ -22516,10 +22542,12 @@ void MessagesManager::get_history_from_the_end(DialogId dialog_id, bool from_dat
|
||||
db_query.from_message_id = MessageId::max();
|
||||
db_query.limit = limit;
|
||||
G()->td_db()->get_messages_db_async()->get_messages(
|
||||
db_query, PromiseCreator::lambda([dialog_id, only_local, limit, actor_id = actor_id(this),
|
||||
db_query, PromiseCreator::lambda([dialog_id, old_last_database_message_id = d->last_database_message_id,
|
||||
only_local, limit, actor_id = actor_id(this),
|
||||
promise = std::move(promise)](std::vector<BufferSlice> messages) mutable {
|
||||
send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, MessageId::max(), 0, limit,
|
||||
true, only_local, std::move(messages), std::move(promise));
|
||||
send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, MessageId::max(),
|
||||
old_last_database_message_id, 0, limit, true, only_local, std::move(messages),
|
||||
std::move(promise));
|
||||
}));
|
||||
} else {
|
||||
if (only_local || dialog_id.get_type() == DialogType::SecretChat) {
|
||||
@ -22534,8 +22562,16 @@ void MessagesManager::get_history_from_the_end(DialogId dialog_id, bool from_dat
|
||||
|
||||
void MessagesManager::get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit,
|
||||
bool from_database, bool only_local, Promise<Unit> &&promise) {
|
||||
CHECK(dialog_id.is_valid());
|
||||
get_history_impl(get_dialog(dialog_id), from_message_id, offset, limit, from_database, only_local,
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void MessagesManager::get_history_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit,
|
||||
bool from_database, bool only_local, Promise<Unit> &&promise) {
|
||||
CHECK(d != nullptr);
|
||||
CHECK(from_message_id.is_valid());
|
||||
|
||||
auto dialog_id = d->dialog_id;
|
||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
// can't get history in dialogs without read access
|
||||
return promise.set_value(Unit());
|
||||
@ -22553,10 +22589,12 @@ void MessagesManager::get_history(DialogId dialog_id, MessageId from_message_id,
|
||||
db_query.limit = limit;
|
||||
G()->td_db()->get_messages_db_async()->get_messages(
|
||||
db_query,
|
||||
PromiseCreator::lambda([dialog_id, from_message_id, offset, limit, only_local, actor_id = actor_id(this),
|
||||
PromiseCreator::lambda([dialog_id, from_message_id, old_last_database_message_id = d->last_database_message_id,
|
||||
offset, limit, only_local, actor_id = actor_id(this),
|
||||
promise = std::move(promise)](std::vector<BufferSlice> messages) mutable {
|
||||
send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, from_message_id, offset,
|
||||
limit, false, only_local, std::move(messages), std::move(promise));
|
||||
send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, from_message_id,
|
||||
old_last_database_message_id, offset, limit, false, only_local, std::move(messages),
|
||||
std::move(promise));
|
||||
}));
|
||||
} else {
|
||||
if (only_local || dialog_id.get_type() == DialogType::SecretChat) {
|
||||
@ -22572,24 +22610,28 @@ void MessagesManager::get_history(DialogId dialog_id, MessageId from_message_id,
|
||||
|
||||
void MessagesManager::load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit,
|
||||
int left_tries, bool only_local, Promise<Unit> &&promise) {
|
||||
LOG(INFO) << "Load " << (only_local ? "local " : "") << "messages in " << dialog_id << " from " << from_message_id
|
||||
<< " with offset = " << offset << " and limit = " << limit << ". " << left_tries << " tries left";
|
||||
load_messages_impl(get_dialog(dialog_id), from_message_id, offset, limit, left_tries, only_local, std::move(promise));
|
||||
}
|
||||
|
||||
void MessagesManager::load_messages_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit,
|
||||
int left_tries, bool only_local, Promise<Unit> &&promise) {
|
||||
CHECK(d != nullptr);
|
||||
CHECK(offset <= 0);
|
||||
CHECK(left_tries > 0);
|
||||
auto dialog_id = d->dialog_id;
|
||||
LOG(INFO) << "Load " << (only_local ? "local " : "") << "messages in " << dialog_id << " from " << from_message_id
|
||||
<< " with offset = " << offset << " and limit = " << limit << ". " << left_tries << " tries left";
|
||||
only_local |= dialog_id.get_type() == DialogType::SecretChat;
|
||||
if (!only_local) {
|
||||
Dialog *d = get_dialog(dialog_id);
|
||||
if (d != nullptr && d->have_full_history) {
|
||||
LOG(INFO) << "Have full history in " << dialog_id << ", so don't need to get chat history from server";
|
||||
only_local = true;
|
||||
}
|
||||
if (!only_local && d->have_full_history) {
|
||||
LOG(INFO) << "Have full history in " << dialog_id << ", so don't need to get chat history from server";
|
||||
only_local = true;
|
||||
}
|
||||
bool from_database = (left_tries > 2 || only_local) && G()->parameters().use_message_db;
|
||||
// TODO do not send requests to database if (from_message_id < d->first_database_message_id ||
|
||||
// !d->first_database_message_id.is_valid()) && !d->have_full_history
|
||||
|
||||
if (from_message_id == MessageId()) {
|
||||
get_history_from_the_end(dialog_id, from_database, only_local, std::move(promise));
|
||||
get_history_from_the_end_impl(d, from_database, only_local, std::move(promise));
|
||||
return;
|
||||
}
|
||||
if (offset >= -1) {
|
||||
@ -22603,7 +22645,7 @@ void MessagesManager::load_messages(DialogId dialog_id, MessageId from_message_i
|
||||
offset -= max_add;
|
||||
limit = MAX_GET_HISTORY;
|
||||
}
|
||||
get_history(dialog_id, from_message_id, offset, limit, from_database, only_local, std::move(promise));
|
||||
get_history_impl(d, from_message_id, offset, limit, from_database, only_local, std::move(promise));
|
||||
}
|
||||
|
||||
vector<MessageId> MessagesManager::get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result,
|
||||
@ -31952,8 +31994,13 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(DialogId dialog
|
||||
|
||||
Dialog *d = get_dialog_force(dialog_id, source);
|
||||
if (d == nullptr) {
|
||||
if (from_update) {
|
||||
CHECK(!being_added_by_new_message_dialog_id_.is_valid());
|
||||
being_added_by_new_message_dialog_id_ = dialog_id;
|
||||
}
|
||||
d = add_dialog(dialog_id, "add_message_to_dialog");
|
||||
*need_update_dialog_pos = true;
|
||||
being_added_by_new_message_dialog_id_ = DialogId();
|
||||
} else {
|
||||
CHECK(d->dialog_id == dialog_id);
|
||||
}
|
||||
@ -33861,14 +33908,14 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source
|
||||
}
|
||||
|
||||
MessagesManager::Dialog *MessagesManager::add_dialog(DialogId dialog_id, const char *source) {
|
||||
LOG(DEBUG) << "Creating " << dialog_id;
|
||||
LOG(DEBUG) << "Creating " << dialog_id << " from " << source;
|
||||
CHECK(!have_dialog(dialog_id));
|
||||
|
||||
if (G()->parameters().use_message_db) {
|
||||
// TODO preload dialog asynchronously, remove loading from this function
|
||||
auto r_value = G()->td_db()->get_dialog_db_sync()->get_dialog(dialog_id);
|
||||
if (r_value.is_ok()) {
|
||||
LOG(INFO) << "Synchronously loaded " << dialog_id << " from database";
|
||||
LOG(INFO) << "Synchronously loaded " << dialog_id << " from database from " << source;
|
||||
return add_new_dialog(parse_dialog(dialog_id, r_value.ok(), source), true, source);
|
||||
}
|
||||
}
|
||||
@ -33913,7 +33960,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d,
|
||||
}
|
||||
case DialogType::SecretChat:
|
||||
if (d->last_new_message_id.get() <= MessageId::min().get()) {
|
||||
LOG(INFO) << "Set " << d->dialog_id << " last new message in add_new_dialog";
|
||||
LOG(INFO) << "Set " << d->dialog_id << " last new message in add_new_dialog from " << source;
|
||||
d->last_new_message_id = MessageId::min().get_next_message_id(MessageType::Local);
|
||||
}
|
||||
|
||||
@ -34332,8 +34379,9 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
|
||||
d->pending_read_channel_inbox_pts = 0;
|
||||
}
|
||||
if (need_get_history && !td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ &&
|
||||
have_input_peer(dialog_id, AccessRights::Read) && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||
get_history_from_the_end(dialog_id, true, false, Auto());
|
||||
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
||||
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||
get_history_from_the_end_impl(d, true, false, Auto());
|
||||
}
|
||||
if (d->need_repair_server_unread_count && need_unread_counter(d->order)) {
|
||||
CHECK(dialog_type != DialogType::SecretChat);
|
||||
@ -34350,6 +34398,7 @@ void MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Mes
|
||||
CHECK(last_database_message->left == nullptr);
|
||||
CHECK(last_database_message->right == nullptr);
|
||||
|
||||
auto dialog_id = d->dialog_id;
|
||||
auto message_id = last_database_message->message_id;
|
||||
CHECK(message_id.is_valid());
|
||||
LOG_CHECK(d->last_database_message_id == message_id)
|
||||
@ -34357,7 +34406,7 @@ void MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Mes
|
||||
|
||||
bool need_update_dialog_pos = false;
|
||||
const Message *m = nullptr;
|
||||
if (have_input_peer(d->dialog_id, AccessRights::Read)) {
|
||||
if (have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
bool need_update = false;
|
||||
last_database_message->have_previous = false;
|
||||
last_database_message->have_next = false;
|
||||
@ -34365,7 +34414,7 @@ void MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Mes
|
||||
m = add_message_to_dialog(d, std::move(last_database_message), false, &need_update, &need_update_dialog_pos,
|
||||
"add_dialog_last_database_message 1");
|
||||
if (need_update_dialog_pos) {
|
||||
LOG(ERROR) << "Need to update pos in " << d->dialog_id;
|
||||
LOG(ERROR) << "Need to update pos in " << dialog_id;
|
||||
}
|
||||
}
|
||||
if (m != nullptr) {
|
||||
@ -34377,11 +34426,12 @@ void MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Mes
|
||||
d->pending_last_message_id = MessageId();
|
||||
need_update_dialog_pos = true;
|
||||
}
|
||||
on_dialog_updated(d->dialog_id, "add_dialog_last_database_message 4"); // resave without last database message
|
||||
on_dialog_updated(dialog_id, "add_dialog_last_database_message 4"); // resave without last database message
|
||||
|
||||
if (!td_->auth_manager_->is_bot() && d->dialog_id != being_added_dialog_id_ &&
|
||||
have_input_peer(d->dialog_id, AccessRights::Read) && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||
get_history_from_the_end(d->dialog_id, true, false, Auto());
|
||||
if (!td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ &&
|
||||
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
||||
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||
get_history_from_the_end_impl(d, true, false, Auto());
|
||||
}
|
||||
}
|
||||
|
||||
@ -37263,10 +37313,10 @@ void MessagesManager::suffix_load_loop(Dialog *d) {
|
||||
d->suffix_load_has_query_ = true;
|
||||
d->suffix_load_query_message_id_ = from_message_id;
|
||||
if (from_message_id.is_valid()) {
|
||||
get_history(dialog_id, from_message_id, -1, 100, true, true, std::move(promise));
|
||||
get_history_impl(d, from_message_id, -1, 100, true, true, std::move(promise));
|
||||
} else {
|
||||
CHECK(from_message_id == MessageId());
|
||||
get_history_from_the_end(dialog_id, true, true, std::move(promise));
|
||||
get_history_from_the_end_impl(d, true, true, std::move(promise));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2006,18 +2006,27 @@ class MessagesManager final : public Actor {
|
||||
|
||||
void preload_older_messages(const Dialog *d, MessageId min_message_id);
|
||||
|
||||
void on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit,
|
||||
void on_get_history_from_database(DialogId dialog_id, MessageId from_message_id,
|
||||
MessageId old_last_database_message_id, int32 offset, int32 limit,
|
||||
bool from_the_end, bool only_local, vector<BufferSlice> &&messages,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void get_history_from_the_end(DialogId dialog_id, bool from_database, bool only_local, Promise<Unit> &&promise);
|
||||
|
||||
void get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local, Promise<Unit> &&promise);
|
||||
|
||||
void get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, bool from_database,
|
||||
bool only_local, Promise<Unit> &&promise);
|
||||
|
||||
void get_history_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit, bool from_database,
|
||||
bool only_local, Promise<Unit> &&promise);
|
||||
|
||||
void load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, int left_tries,
|
||||
bool only_local, Promise<Unit> &&promise);
|
||||
|
||||
void load_messages_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit, int left_tries,
|
||||
bool only_local, Promise<Unit> &&promise);
|
||||
|
||||
void load_dialog_scheduled_messages(DialogId dialog_id, bool from_database, int32 hash, Promise<Unit> &&promise);
|
||||
|
||||
void on_get_scheduled_messages_from_database(DialogId dialog_id, vector<BufferSlice> &&messages);
|
||||
@ -3339,6 +3348,7 @@ class MessagesManager final : public Actor {
|
||||
FullMessageId being_readded_message_id_;
|
||||
|
||||
DialogId being_added_dialog_id_;
|
||||
DialogId being_added_by_new_message_dialog_id_;
|
||||
|
||||
DialogId debug_channel_difference_dialog_;
|
||||
|
||||
|
@ -215,7 +215,7 @@ Result<BufferSlice> SecretChatActor::create_encrypted_message(int32 my_in_seq_no
|
||||
auto out_seq_no = my_out_seq_no * 2 - 1 - auth_state_.x;
|
||||
|
||||
auto layer = current_layer();
|
||||
BufferSlice random_bytes(32);
|
||||
BufferSlice random_bytes(31);
|
||||
Random::secure_bytes(random_bytes.as_slice().ubegin(), random_bytes.size());
|
||||
auto message_with_layer = secret_api::make_object<secret_api::decryptedMessageLayer>(
|
||||
std::move(random_bytes), layer, in_seq_no, out_seq_no, std::move(message));
|
||||
@ -797,7 +797,9 @@ Result<std::tuple<uint64, BufferSlice, int32>> SecretChatActor::decrypt(BufferSl
|
||||
info.is_creator = auth_state_.x == 0;
|
||||
r_read_result = mtproto::Transport::read(data, *auth_key, &info);
|
||||
if (i + 1 != versions.size() && r_read_result.is_error()) {
|
||||
LOG(WARNING) << tag("mtproto", mtproto_version) << " decryption failed " << r_read_result.error();
|
||||
if (config_state_.his_layer >= static_cast<int32>(SecretChatLayer::Mtproto2)) {
|
||||
LOG(WARNING) << tag("mtproto", mtproto_version) << " decryption failed " << r_read_result.error();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -1933,13 +1935,13 @@ void SecretChatActor::get_dh_config() {
|
||||
}
|
||||
|
||||
auto version = auth_state_.dh_config.version;
|
||||
int32 random_length = 0;
|
||||
int32 random_length = 256; // ignored server-side, always returns 256 random bytes
|
||||
auto query = create_net_query(QueryType::DhConfig, telegram_api::messages_getDhConfig(version, random_length));
|
||||
context_->send_net_query(std::move(query), actor_shared(this), false);
|
||||
}
|
||||
|
||||
Status SecretChatActor::on_dh_config(NetQueryPtr query) {
|
||||
LOG(INFO) << "Got dh config";
|
||||
LOG(INFO) << "Got DH config";
|
||||
TRY_RESULT(config, fetch_result<telegram_api::messages_getDhConfig>(std::move(query)));
|
||||
downcast_call(*config, [&](auto &obj) { this->on_dh_config(obj); });
|
||||
TRY_STATUS(mtproto::DhHandshake::check_config(auth_state_.dh_config.g, auth_state_.dh_config.prime,
|
||||
|
@ -1947,39 +1947,6 @@ class UpgradeGroupChatToSupergroupChatRequest final : public RequestActor<> {
|
||||
}
|
||||
};
|
||||
|
||||
class GetChatMemberRequest final : public RequestActor<> {
|
||||
DialogId dialog_id_;
|
||||
tl_object_ptr<td_api::MessageSender> participant_id_;
|
||||
int64 random_id_;
|
||||
|
||||
DialogParticipant dialog_participant_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) final {
|
||||
dialog_participant_ = td->contacts_manager_->get_dialog_participant(dialog_id_, participant_id_, random_id_,
|
||||
get_tries() < 3, std::move(promise));
|
||||
}
|
||||
|
||||
void do_send_result() final {
|
||||
auto participant_dialog_id = dialog_participant_.dialog_id;
|
||||
bool is_user = participant_dialog_id.get_type() == DialogType::User;
|
||||
if ((is_user && !td->contacts_manager_->have_user(participant_dialog_id.get_user_id())) ||
|
||||
(!is_user && !td->messages_manager_->have_dialog(participant_dialog_id))) {
|
||||
return send_error(Status::Error(3, "Member not found"));
|
||||
}
|
||||
send_result(td->contacts_manager_->get_chat_member_object(dialog_participant_));
|
||||
}
|
||||
|
||||
public:
|
||||
GetChatMemberRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id,
|
||||
tl_object_ptr<td_api::MessageSender> participant_id)
|
||||
: RequestActor(std::move(td), request_id)
|
||||
, dialog_id_(dialog_id)
|
||||
, participant_id_(std::move(participant_id))
|
||||
, random_id_(0) {
|
||||
set_tries(3);
|
||||
}
|
||||
};
|
||||
|
||||
class GetChatAdministratorsRequest final : public RequestActor<> {
|
||||
DialogId dialog_id_;
|
||||
|
||||
@ -6564,7 +6531,9 @@ void Td::on_request(uint64 id, td_api::transferChatOwnership &request) {
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::getChatMember &request) {
|
||||
CREATE_REQUEST(GetChatMemberRequest, request.chat_id_, std::move(request.member_id_));
|
||||
CREATE_REQUEST_PROMISE();
|
||||
contacts_manager_->get_dialog_participant(DialogId(request.chat_id_), std::move(request.member_id_),
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::searchChatMembers &request) {
|
||||
|
@ -36,13 +36,13 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#define TRY_STATUS_PROMISE(promise_name, status) \
|
||||
{ \
|
||||
auto try_status = (status); \
|
||||
if (try_status.is_error()) { \
|
||||
promise_name.set_error(std::move(try_status)); \
|
||||
return; \
|
||||
} \
|
||||
#define TRY_STATUS_PROMISE(promise_name, status) \
|
||||
{ \
|
||||
auto try_status = (status); \
|
||||
if (try_status.is_error()) { \
|
||||
promise_name.set_error(try_status.move_as_error()); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TRY_STATUS_PROMISE_PREFIX(promise_name, status, prefix) \
|
||||
|
@ -27,10 +27,11 @@ namespace td {
|
||||
namespace {
|
||||
|
||||
void print_backtrace(void) {
|
||||
void *buffer[128];
|
||||
#if TD_PORT_WINDOWS
|
||||
void *buffer[128];
|
||||
USHORT nptrs = CaptureStackBackTrace(0, 128, buffer, nullptr);
|
||||
#elif __GLIBC__
|
||||
void *buffer[128];
|
||||
int nptrs = backtrace(buffer, 128);
|
||||
#else
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user