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);
|
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() {
|
void AuthKeyHandshake::clear() {
|
||||||
last_query_ = BufferSlice();
|
last_query_ = BufferSlice();
|
||||||
state_ = Start;
|
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 {
|
bool AuthKeyHandshake::is_ready_for_finish() const {
|
||||||
return state_ == Finish;
|
return state_ == Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthKeyHandshake::on_finish() {
|
void AuthKeyHandshake::on_finish() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
@ -105,7 +104,6 @@ Status AuthKeyHandshake::on_res_pq(Slice message, Callback *connection, PublicRs
|
|||||||
dc_id_, expires_in_));
|
dc_id_, expires_in_));
|
||||||
expires_at_ = Time::now() + expires_in_;
|
expires_at_ = Time::now() + expires_in_;
|
||||||
break;
|
break;
|
||||||
case Mode::Unknown:
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -266,17 +264,6 @@ void AuthKeyHandshake::do_send(Callback *connection, const Storer &storer) {
|
|||||||
return connection->send_no_crypto(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) {
|
void AuthKeyHandshake::resume(Callback *connection) {
|
||||||
if (state_ == Start) {
|
if (state_ == Start) {
|
||||||
return on_start(connection).ignore();
|
return on_start(connection).ignore();
|
||||||
@ -289,7 +276,7 @@ void AuthKeyHandshake::resume(Callback *connection) {
|
|||||||
LOG(ERROR) << "Last query empty! UNREACHABLE " << state_;
|
LOG(ERROR) << "Last query empty! UNREACHABLE " << state_;
|
||||||
return clear();
|
return clear();
|
||||||
}
|
}
|
||||||
LOG(INFO) << "RESUME";
|
LOG(INFO) << "Resume handshake";
|
||||||
do_send(connection, create_storer(last_query_.as_slice()));
|
do_send(connection, create_storer(last_query_.as_slice()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@ class AuthKeyHandshakeContext {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class AuthKeyHandshake {
|
class AuthKeyHandshake {
|
||||||
enum class Mode { Unknown, Main, Temp };
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Callback {
|
class Callback {
|
||||||
public:
|
public:
|
||||||
@ -45,44 +43,16 @@ class AuthKeyHandshake {
|
|||||||
virtual void send_no_crypto(const Storer &storer) = 0;
|
virtual void send_no_crypto(const Storer &storer) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
AuthKeyHandshake(int32 dc_id, int32 expires_in) {
|
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;
|
|
||||||
|
|
||||||
bool is_ready_for_finish() const;
|
bool is_ready_for_finish() const;
|
||||||
|
|
||||||
void on_finish();
|
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);
|
void resume(Callback *connection);
|
||||||
|
|
||||||
Status on_message(Slice message, Callback *connection, AuthKeyHandshakeContext *context) TD_WARN_UNUSED_RESULT;
|
Status on_message(Slice message, Callback *connection, AuthKeyHandshakeContext *context) TD_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
bool is_ready() const {
|
|
||||||
return is_ready_for_finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
const AuthKey &get_auth_key() const {
|
const AuthKey &get_auth_key() const {
|
||||||
@ -102,9 +72,10 @@ class AuthKeyHandshake {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using State = enum { Start, ResPQ, ServerDHParams, DHGenResponse, Finish };
|
enum State : int32 { Start, ResPQ, ServerDHParams, DHGenResponse, Finish };
|
||||||
State state_ = Start;
|
State state_ = Start;
|
||||||
Mode mode_ = Mode::Unknown;
|
enum class Mode : int32 { Main, Temp };
|
||||||
|
Mode mode_ = Mode::Main;
|
||||||
int32 dc_id_ = 0;
|
int32 dc_id_ = 0;
|
||||||
int32 expires_in_ = 0;
|
int32 expires_in_ = 0;
|
||||||
double expires_at_ = 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) {
|
G()->td_db()->get_sqlite_pmc()->get(get_user_database_key(user_id), PromiseCreator::lambda([user_id](string value) {
|
||||||
send_closure(G()->contacts_manager(),
|
send_closure(G()->contacts_manager(),
|
||||||
&ContactsManager::on_load_user_from_database, user_id,
|
&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) {
|
void ContactsManager::on_load_user_from_database(UserId user_id, string value, bool force) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag() && !force) {
|
||||||
|
// the user is in Binlog and will be saved after restart
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8554,7 +8555,7 @@ ContactsManager::User *ContactsManager::get_user_force_impl(UserId user_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Trying to load " << user_id << " from database";
|
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);
|
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) {
|
G()->td_db()->get_sqlite_pmc()->get(get_chat_database_key(chat_id), PromiseCreator::lambda([chat_id](string value) {
|
||||||
send_closure(G()->contacts_manager(),
|
send_closure(G()->contacts_manager(),
|
||||||
&ContactsManager::on_load_chat_from_database, chat_id,
|
&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) {
|
void ContactsManager::on_load_chat_from_database(ChatId chat_id, string value, bool force) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag() && !force) {
|
||||||
|
// the chat is in Binlog and will be saved after restart
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8791,7 +8793,7 @@ ContactsManager::Chat *ContactsManager::get_chat_force(ChatId chat_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Trying to load " << chat_id << " from database";
|
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);
|
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(
|
G()->td_db()->get_sqlite_pmc()->get(
|
||||||
get_channel_database_key(channel_id), PromiseCreator::lambda([channel_id](string value) {
|
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,
|
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) {
|
void ContactsManager::on_load_channel_from_database(ChannelId channel_id, string value, bool force) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag() && !force) {
|
||||||
|
// the channel is in Binlog and will be saved after restart
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9044,7 +9047,7 @@ ContactsManager::Channel *ContactsManager::get_channel_force(ChannelId channel_i
|
|||||||
|
|
||||||
LOG(INFO) << "Trying to load " << channel_id << " from database";
|
LOG(INFO) << "Trying to load " << channel_id << " from database";
|
||||||
on_load_channel_from_database(channel_id,
|
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);
|
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(
|
G()->td_db()->get_sqlite_pmc()->get(
|
||||||
get_secret_chat_database_key(secret_chat_id), PromiseCreator::lambda([secret_chat_id](string value) {
|
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,
|
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) {
|
void ContactsManager::on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value, bool force) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag() && !force) {
|
||||||
|
// the secret chat is in Binlog and will be saved after restart
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9285,7 +9289,7 @@ ContactsManager::SecretChat *ContactsManager::get_secret_chat_force(SecretChatId
|
|||||||
|
|
||||||
LOG(INFO) << "Trying to load " << secret_chat_id << " from database";
|
LOG(INFO) << "Trying to load " << secret_chat_id << " from database";
|
||||||
on_load_secret_chat_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);
|
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,
|
void ContactsManager::get_dialog_participant(DialogId dialog_id,
|
||||||
const tl_object_ptr<td_api::MessageSender> &participant_id,
|
const tl_object_ptr<td_api::MessageSender> &participant_id,
|
||||||
int64 &random_id, bool force, Promise<Unit> &&promise) {
|
Promise<td_api::object_ptr<td_api::chatMember>> &&promise) {
|
||||||
// TODO TRY_RESULT_PROMISE(promise, participant_dialog_id, get_participant_dialog_id(participant_id));
|
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();
|
|
||||||
|
|
||||||
LOG(INFO) << "Receive GetChatMember request to get " << participant_dialog_id << " in " << dialog_id
|
auto new_promise = PromiseCreator::lambda(
|
||||||
<< " with random_id " << random_id;
|
[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")) {
|
if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_dialog_participant")) {
|
||||||
promise.set_error(Status::Error(3, "Chat not found"));
|
return promise.set_error(Status::Error(3, "Chat not found"));
|
||||||
return DialogParticipant();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (dialog_id.get_type()) {
|
switch (dialog_id.get_type()) {
|
||||||
case DialogType::User:
|
case DialogType::User:
|
||||||
if (participant_dialog_id == DialogId(get_my_id())) {
|
if (participant_dialog_id == DialogId(get_my_id())) {
|
||||||
promise.set_value(Unit());
|
return promise.set_value(
|
||||||
return {participant_dialog_id, dialog_id.get_user_id(), 0, DialogParticipantStatus::Member()};
|
DialogParticipant{participant_dialog_id, dialog_id.get_user_id(), 0, DialogParticipantStatus::Member()});
|
||||||
}
|
}
|
||||||
if (participant_dialog_id == dialog_id) {
|
if (participant_dialog_id == dialog_id) {
|
||||||
promise.set_value(Unit());
|
return promise.set_value(
|
||||||
return {participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()};
|
DialogParticipant{participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()});
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.set_error(Status::Error(3, "Member not found"));
|
return promise.set_error(Status::Error(3, "Member not found"));
|
||||||
break;
|
|
||||||
case DialogType::Chat:
|
case DialogType::Chat:
|
||||||
if (participant_dialog_id.get_type() != DialogType::User) {
|
if (participant_dialog_id.get_type() != DialogType::User) {
|
||||||
promise.set_value(Unit());
|
return promise.set_value(DialogParticipant::left(participant_dialog_id));
|
||||||
return DialogParticipant::left(participant_dialog_id);
|
|
||||||
}
|
}
|
||||||
return get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), force,
|
return get_chat_participant(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), std::move(promise));
|
||||||
std::move(promise));
|
|
||||||
case DialogType::Channel:
|
case DialogType::Channel:
|
||||||
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, random_id, force,
|
return get_channel_participant(dialog_id.get_channel_id(), participant_dialog_id, std::move(promise));
|
||||||
std::move(promise));
|
|
||||||
case DialogType::SecretChat: {
|
case DialogType::SecretChat: {
|
||||||
auto peer_user_id = get_secret_chat_user_id(dialog_id.get_secret_chat_id());
|
auto peer_user_id = get_secret_chat_user_id(dialog_id.get_secret_chat_id());
|
||||||
if (participant_dialog_id == DialogId(get_my_id())) {
|
if (participant_dialog_id == DialogId(get_my_id())) {
|
||||||
promise.set_value(Unit());
|
return promise.set_value(DialogParticipant{participant_dialog_id,
|
||||||
return {participant_dialog_id, peer_user_id.is_valid() ? peer_user_id : get_my_id(), 0,
|
peer_user_id.is_valid() ? peer_user_id : get_my_id(), 0,
|
||||||
DialogParticipantStatus::Member()};
|
DialogParticipantStatus::Member()});
|
||||||
}
|
}
|
||||||
if (participant_dialog_id == DialogId(peer_user_id)) {
|
if (participant_dialog_id == DialogId(peer_user_id)) {
|
||||||
promise.set_value(Unit());
|
return promise.set_value(
|
||||||
return {participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()};
|
DialogParticipant{participant_dialog_id, get_my_id(), 0, DialogParticipantStatus::Member()});
|
||||||
}
|
}
|
||||||
|
|
||||||
promise.set_error(Status::Error(3, "Member not found"));
|
return promise.set_error(Status::Error(3, "Member not found"));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case DialogType::None:
|
case DialogType::None:
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
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,
|
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,
|
void ContactsManager::get_chat_participant(ChatId chat_id, UserId user_id, Promise<DialogParticipant> &&promise) {
|
||||||
Promise<Unit> &&promise) {
|
|
||||||
LOG(INFO) << "Trying to get " << user_id << " as member of " << chat_id;
|
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);
|
auto c = get_chat(chat_id);
|
||||||
if (result == nullptr) {
|
if (c == nullptr) {
|
||||||
return DialogParticipant::left(DialogId(user_id));
|
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,
|
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,
|
void ContactsManager::get_channel_participant(ChannelId channel_id, DialogId participant_dialog_id,
|
||||||
int64 &random_id, bool force, Promise<Unit> &&promise) {
|
Promise<DialogParticipant> &&promise) {
|
||||||
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_id << " with random_id "
|
LOG(INFO) << "Trying to get " << participant_dialog_id << " as member of " << channel_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto input_peer = td_->messages_manager_->get_input_peer(participant_dialog_id, AccessRights::Read);
|
auto input_peer = td_->messages_manager_->get_input_peer(participant_dialog_id, AccessRights::Read);
|
||||||
if (input_peer == nullptr) {
|
if (input_peer == nullptr) {
|
||||||
promise.set_error(Status::Error(6, "User not found"));
|
return promise.set_error(Status::Error(6, "User not found"));
|
||||||
return DialogParticipant();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_channel_participant_cache(channel_id)) {
|
if (have_channel_participant_cache(channel_id)) {
|
||||||
auto *participant = get_channel_participant_from_cache(channel_id, participant_dialog_id);
|
auto *participant = get_channel_participant_from_cache(channel_id, participant_dialog_id);
|
||||||
if (participant != nullptr) {
|
if (participant != nullptr) {
|
||||||
promise.set_value(Unit());
|
return promise.set_value(DialogParticipant{*participant});
|
||||||
return *participant;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
auto on_result_promise = PromiseCreator::lambda([actor_id = actor_id(this), channel_id, promise = std::move(promise)](
|
||||||
random_id = Random::secure_int64();
|
Result<DialogParticipant> r_dialog_participant) mutable {
|
||||||
} while (random_id == 0 || received_channel_participant_.find(random_id) != received_channel_participant_.end());
|
TRY_RESULT_PROMISE(promise, dialog_participant, std::move(r_dialog_participant));
|
||||||
received_channel_participant_[random_id]; // reserve place for result
|
send_closure(actor_id, &ContactsManager::finish_get_channel_participant, channel_id, std::move(dialog_participant),
|
||||||
|
std::move(promise));
|
||||||
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));
|
|
||||||
});
|
|
||||||
|
|
||||||
td_->create_handler<GetChannelParticipantQuery>(std::move(on_result_promise))
|
td_->create_handler<GetChannelParticipantQuery>(std::move(on_result_promise))
|
||||||
->send(channel_id, participant_dialog_id, std::move(input_peer));
|
->send(channel_id, participant_dialog_id, std::move(input_peer));
|
||||||
return DialogParticipant();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::on_get_channel_participant(ChannelId channel_id, int64 random_id,
|
void ContactsManager::finish_get_channel_participant(ChannelId channel_id, DialogParticipant &&dialog_participant,
|
||||||
Result<DialogParticipant> r_dialog_participant,
|
Promise<DialogParticipant> &&promise) {
|
||||||
Promise<Unit> &&promise) {
|
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag()) {
|
||||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
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);
|
dialog_participant.status.update_restrictions();
|
||||||
CHECK(it != received_channel_participant_.end());
|
if (have_channel_participant_cache(channel_id)) {
|
||||||
|
add_channel_participant_to_cache(channel_id, dialog_participant, false);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
promise.set_value(std::move(dialog_participant));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::get_channel_participants(ChannelId channel_id,
|
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,
|
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);
|
int32 banned_until_date, bool revoke_messages, Promise<Unit> &&promise);
|
||||||
|
|
||||||
DialogParticipant get_dialog_participant(DialogId dialog_id,
|
void get_dialog_participant(DialogId dialog_id, const tl_object_ptr<td_api::MessageSender> &participant_id,
|
||||||
const tl_object_ptr<td_api::MessageSender> &participant_id, int64 &random_id,
|
Promise<td_api::object_ptr<td_api::chatMember>> &&promise);
|
||||||
bool force, Promise<Unit> &&promise);
|
|
||||||
|
|
||||||
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter,
|
void search_dialog_participants(DialogId dialog_id, const string &query, int32 limit, DialogParticipantsFilter filter,
|
||||||
Promise<DialogParticipants> &&promise);
|
Promise<DialogParticipants> &&promise);
|
||||||
@ -1275,7 +1274,7 @@ class ContactsManager final : public Actor {
|
|||||||
void on_save_user_to_database(UserId user_id, bool success);
|
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(User *u, UserId user_id, Promise<Unit> promise);
|
||||||
void load_user_from_database_impl(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);
|
void save_chat(Chat *c, ChatId chat_id, bool from_binlog);
|
||||||
static string get_chat_database_key(ChatId chat_id);
|
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 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(Chat *c, ChatId chat_id, Promise<Unit> promise);
|
||||||
void load_chat_from_database_impl(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);
|
void save_channel(Channel *c, ChannelId channel_id, bool from_binlog);
|
||||||
static string get_channel_database_key(ChannelId channel_id);
|
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 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(Channel *c, ChannelId channel_id, Promise<Unit> promise);
|
||||||
void load_channel_from_database_impl(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);
|
void save_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog);
|
||||||
static string get_secret_chat_database_key(SecretChatId secret_chat_id);
|
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 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(SecretChat *c, SecretChatId secret_chat_id, Promise<Unit> promise);
|
||||||
void load_secret_chat_from_database_impl(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);
|
void save_user_full(const UserFull *user_full, UserId user_id);
|
||||||
static string get_user_full_database_key(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,
|
DialogParticipants search_private_chat_participants(UserId my_user_id, UserId peer_user_id, const string &query,
|
||||||
int32 limit, DialogParticipantsFilter filter) const;
|
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,
|
void finish_get_dialog_participant(DialogParticipant &&dialog_participant,
|
||||||
bool force, Promise<Unit> &&promise);
|
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);
|
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 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,
|
void search_chat_participants(ChatId chat_id, const string &query, int32 limit, DialogParticipantsFilter filter,
|
||||||
Promise<DialogParticipants> &&promise);
|
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, 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_;
|
std::unordered_map<ChannelId, vector<DialogParticipant>, ChannelIdHash> cached_channel_participants_;
|
||||||
|
|
||||||
// bot-administrators only
|
// 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);
|
added_dialog_ids.push_back(dialog_id);
|
||||||
Dialog *d = get_dialog_force(dialog_id, "on_get_dialogs");
|
Dialog *d = get_dialog_force(dialog_id, "on_get_dialogs");
|
||||||
bool need_update_dialog_pos = false;
|
bool need_update_dialog_pos = false;
|
||||||
|
CHECK(!being_added_dialog_id_.is_valid());
|
||||||
being_added_dialog_id_ = dialog_id;
|
being_added_dialog_id_ = dialog_id;
|
||||||
if (d == nullptr) {
|
if (d == nullptr) {
|
||||||
d = add_dialog(dialog_id, "on_get_dialogs");
|
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) {
|
if (from_the_end) {
|
||||||
from_message_id = MessageId();
|
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));
|
limit - static_cast<int32>(messages.size()), left_tries, only_local, std::move(promise));
|
||||||
return nullptr;
|
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)) {
|
if (limit > 0 && (d->last_message_id == MessageId() || max_message_id < d->last_message_id)) {
|
||||||
// need to preload some new messages
|
// need to preload some new messages
|
||||||
LOG(INFO) << "Preloading newer after " << max_message_id;
|
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) {
|
if (limit > 0) {
|
||||||
// need to preload some old messages
|
// need to preload some old messages
|
||||||
LOG(INFO) << "Preloading older before " << min_message_id;
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, int32 offset,
|
void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId from_message_id,
|
||||||
int32 limit, bool from_the_end, bool only_local,
|
MessageId old_last_database_message_id, int32 offset, int32 limit,
|
||||||
vector<BufferSlice> &&messages, Promise<Unit> &&promise) {
|
bool from_the_end, bool only_local, vector<BufferSlice> &&messages,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
CHECK(-limit < offset && offset <= 0);
|
CHECK(-limit < offset && offset <= 0);
|
||||||
CHECK(offset < 0 || from_the_end);
|
CHECK(offset < 0 || from_the_end);
|
||||||
CHECK(!from_message_id.is_scheduled());
|
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
|
<< d->first_database_message_id << ", last database message is " << d->last_database_message_id
|
||||||
<< ", have_full_history = " << d->have_full_history;
|
<< ", 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 (messages.empty() && from_the_end && d->messages == nullptr) {
|
||||||
if (d->have_full_history) {
|
if (d->have_full_history) {
|
||||||
set_dialog_is_empty(d, "on_get_history_from_database empty");
|
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) {
|
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");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit > 1) {
|
if (limit > 1) {
|
||||||
// we expected to have messages [first_database_message_id, last_database_message_id] in the database, but
|
// 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,
|
// 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
|
// pretending that the database has no usable messages
|
||||||
LOG(ERROR) << "Receive unusable messages up to " << last_received_message_id << " in " << dialog_id
|
if (last_received_message_id == MessageId::max()) {
|
||||||
<< " from database from the end, but expected messages from " << d->last_database_message_id
|
LOG(ERROR) << "Receive no usable messages in " << dialog_id
|
||||||
<< " up to " << d->first_database_message_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_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");
|
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) {
|
if (from_the_end) {
|
||||||
from_message_id = MessageId();
|
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;
|
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,
|
void MessagesManager::get_history_from_the_end(DialogId dialog_id, bool from_database, bool only_local,
|
||||||
Promise<Unit> &&promise) {
|
Promise<Unit> &&promise) {
|
||||||
CHECK(dialog_id.is_valid());
|
get_history_from_the_end_impl(get_dialog(dialog_id), from_database, only_local, std::move(promise));
|
||||||
if (G()->close_flag()) {
|
}
|
||||||
return promise.set_error(Status::Error(500, "Request aborted"));
|
|
||||||
}
|
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)) {
|
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||||
// can't get history in dialogs without read access
|
// can't get history in dialogs without read access
|
||||||
return promise.set_value(Unit());
|
return promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
if (G()->close_flag()) {
|
||||||
|
return promise.set_error(Status::Error(500, "Request aborted"));
|
||||||
|
}
|
||||||
int32 limit = MAX_GET_HISTORY;
|
int32 limit = MAX_GET_HISTORY;
|
||||||
if (from_database && G()->parameters().use_message_db) {
|
if (from_database && G()->parameters().use_message_db) {
|
||||||
if (!promise) {
|
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.from_message_id = MessageId::max();
|
||||||
db_query.limit = limit;
|
db_query.limit = limit;
|
||||||
G()->td_db()->get_messages_db_async()->get_messages(
|
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 {
|
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,
|
send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, MessageId::max(),
|
||||||
true, only_local, std::move(messages), std::move(promise));
|
old_last_database_message_id, 0, limit, true, only_local, std::move(messages),
|
||||||
|
std::move(promise));
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
if (only_local || dialog_id.get_type() == DialogType::SecretChat) {
|
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,
|
void MessagesManager::get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit,
|
||||||
bool from_database, bool only_local, Promise<Unit> &&promise) {
|
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());
|
CHECK(from_message_id.is_valid());
|
||||||
|
|
||||||
|
auto dialog_id = d->dialog_id;
|
||||||
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
if (!have_input_peer(dialog_id, AccessRights::Read)) {
|
||||||
// can't get history in dialogs without read access
|
// can't get history in dialogs without read access
|
||||||
return promise.set_value(Unit());
|
return promise.set_value(Unit());
|
||||||
@ -22553,10 +22589,12 @@ void MessagesManager::get_history(DialogId dialog_id, MessageId from_message_id,
|
|||||||
db_query.limit = limit;
|
db_query.limit = limit;
|
||||||
G()->td_db()->get_messages_db_async()->get_messages(
|
G()->td_db()->get_messages_db_async()->get_messages(
|
||||||
db_query,
|
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 {
|
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,
|
send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, from_message_id,
|
||||||
limit, false, only_local, std::move(messages), std::move(promise));
|
old_last_database_message_id, offset, limit, false, only_local, std::move(messages),
|
||||||
|
std::move(promise));
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
if (only_local || dialog_id.get_type() == DialogType::SecretChat) {
|
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,
|
void MessagesManager::load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit,
|
||||||
int left_tries, bool only_local, Promise<Unit> &&promise) {
|
int left_tries, bool only_local, Promise<Unit> &&promise) {
|
||||||
LOG(INFO) << "Load " << (only_local ? "local " : "") << "messages in " << dialog_id << " from " << from_message_id
|
load_messages_impl(get_dialog(dialog_id), from_message_id, offset, limit, left_tries, only_local, std::move(promise));
|
||||||
<< " with offset = " << offset << " and limit = " << limit << ". " << left_tries << " tries left";
|
}
|
||||||
|
|
||||||
|
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(offset <= 0);
|
||||||
CHECK(left_tries > 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;
|
only_local |= dialog_id.get_type() == DialogType::SecretChat;
|
||||||
if (!only_local) {
|
if (!only_local && d->have_full_history) {
|
||||||
Dialog *d = get_dialog(dialog_id);
|
LOG(INFO) << "Have full history in " << dialog_id << ", so don't need to get chat history from server";
|
||||||
if (d != nullptr && d->have_full_history) {
|
only_local = true;
|
||||||
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;
|
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 ||
|
// 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
|
// !d->first_database_message_id.is_valid()) && !d->have_full_history
|
||||||
|
|
||||||
if (from_message_id == MessageId()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (offset >= -1) {
|
if (offset >= -1) {
|
||||||
@ -22603,7 +22645,7 @@ void MessagesManager::load_messages(DialogId dialog_id, MessageId from_message_i
|
|||||||
offset -= max_add;
|
offset -= max_add;
|
||||||
limit = MAX_GET_HISTORY;
|
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,
|
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);
|
Dialog *d = get_dialog_force(dialog_id, source);
|
||||||
if (d == nullptr) {
|
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");
|
d = add_dialog(dialog_id, "add_message_to_dialog");
|
||||||
*need_update_dialog_pos = true;
|
*need_update_dialog_pos = true;
|
||||||
|
being_added_by_new_message_dialog_id_ = DialogId();
|
||||||
} else {
|
} else {
|
||||||
CHECK(d->dialog_id == dialog_id);
|
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) {
|
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));
|
CHECK(!have_dialog(dialog_id));
|
||||||
|
|
||||||
if (G()->parameters().use_message_db) {
|
if (G()->parameters().use_message_db) {
|
||||||
// TODO preload dialog asynchronously, remove loading from this function
|
// TODO preload dialog asynchronously, remove loading from this function
|
||||||
auto r_value = G()->td_db()->get_dialog_db_sync()->get_dialog(dialog_id);
|
auto r_value = G()->td_db()->get_dialog_db_sync()->get_dialog(dialog_id);
|
||||||
if (r_value.is_ok()) {
|
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);
|
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:
|
case DialogType::SecretChat:
|
||||||
if (d->last_new_message_id.get() <= MessageId::min().get()) {
|
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);
|
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;
|
d->pending_read_channel_inbox_pts = 0;
|
||||||
}
|
}
|
||||||
if (need_get_history && !td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ &&
|
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))) {
|
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
||||||
get_history_from_the_end(dialog_id, true, false, Auto());
|
(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)) {
|
if (d->need_repair_server_unread_count && need_unread_counter(d->order)) {
|
||||||
CHECK(dialog_type != DialogType::SecretChat);
|
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->left == nullptr);
|
||||||
CHECK(last_database_message->right == nullptr);
|
CHECK(last_database_message->right == nullptr);
|
||||||
|
|
||||||
|
auto dialog_id = d->dialog_id;
|
||||||
auto message_id = last_database_message->message_id;
|
auto message_id = last_database_message->message_id;
|
||||||
CHECK(message_id.is_valid());
|
CHECK(message_id.is_valid());
|
||||||
LOG_CHECK(d->last_database_message_id == message_id)
|
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;
|
bool need_update_dialog_pos = false;
|
||||||
const Message *m = nullptr;
|
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;
|
bool need_update = false;
|
||||||
last_database_message->have_previous = false;
|
last_database_message->have_previous = false;
|
||||||
last_database_message->have_next = 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,
|
m = add_message_to_dialog(d, std::move(last_database_message), false, &need_update, &need_update_dialog_pos,
|
||||||
"add_dialog_last_database_message 1");
|
"add_dialog_last_database_message 1");
|
||||||
if (need_update_dialog_pos) {
|
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) {
|
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();
|
d->pending_last_message_id = MessageId();
|
||||||
need_update_dialog_pos = true;
|
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_ &&
|
if (!td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ &&
|
||||||
have_input_peer(d->dialog_id, AccessRights::Read) && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
||||||
get_history_from_the_end(d->dialog_id, true, false, Auto());
|
(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_has_query_ = true;
|
||||||
d->suffix_load_query_message_id_ = from_message_id;
|
d->suffix_load_query_message_id_ = from_message_id;
|
||||||
if (from_message_id.is_valid()) {
|
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 {
|
} else {
|
||||||
CHECK(from_message_id == MessageId());
|
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 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,
|
bool from_the_end, bool only_local, vector<BufferSlice> &&messages,
|
||||||
Promise<Unit> &&promise);
|
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(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,
|
void get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, bool from_database,
|
||||||
bool only_local, Promise<Unit> &&promise);
|
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,
|
void load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, int left_tries,
|
||||||
bool only_local, Promise<Unit> &&promise);
|
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 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);
|
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_;
|
FullMessageId being_readded_message_id_;
|
||||||
|
|
||||||
DialogId being_added_dialog_id_;
|
DialogId being_added_dialog_id_;
|
||||||
|
DialogId being_added_by_new_message_dialog_id_;
|
||||||
|
|
||||||
DialogId debug_channel_difference_dialog_;
|
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 out_seq_no = my_out_seq_no * 2 - 1 - auth_state_.x;
|
||||||
|
|
||||||
auto layer = current_layer();
|
auto layer = current_layer();
|
||||||
BufferSlice random_bytes(32);
|
BufferSlice random_bytes(31);
|
||||||
Random::secure_bytes(random_bytes.as_slice().ubegin(), random_bytes.size());
|
Random::secure_bytes(random_bytes.as_slice().ubegin(), random_bytes.size());
|
||||||
auto message_with_layer = secret_api::make_object<secret_api::decryptedMessageLayer>(
|
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));
|
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;
|
info.is_creator = auth_state_.x == 0;
|
||||||
r_read_result = mtproto::Transport::read(data, *auth_key, &info);
|
r_read_result = mtproto::Transport::read(data, *auth_key, &info);
|
||||||
if (i + 1 != versions.size() && r_read_result.is_error()) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1933,13 +1935,13 @@ void SecretChatActor::get_dh_config() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto version = auth_state_.dh_config.version;
|
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));
|
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);
|
context_->send_net_query(std::move(query), actor_shared(this), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status SecretChatActor::on_dh_config(NetQueryPtr query) {
|
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)));
|
TRY_RESULT(config, fetch_result<telegram_api::messages_getDhConfig>(std::move(query)));
|
||||||
downcast_call(*config, [&](auto &obj) { this->on_dh_config(obj); });
|
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,
|
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<> {
|
class GetChatAdministratorsRequest final : public RequestActor<> {
|
||||||
DialogId dialog_id_;
|
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) {
|
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) {
|
void Td::on_request(uint64 id, td_api::searchChatMembers &request) {
|
||||||
|
@ -36,13 +36,13 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRY_STATUS_PROMISE(promise_name, status) \
|
#define TRY_STATUS_PROMISE(promise_name, status) \
|
||||||
{ \
|
{ \
|
||||||
auto try_status = (status); \
|
auto try_status = (status); \
|
||||||
if (try_status.is_error()) { \
|
if (try_status.is_error()) { \
|
||||||
promise_name.set_error(std::move(try_status)); \
|
promise_name.set_error(try_status.move_as_error()); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRY_STATUS_PROMISE_PREFIX(promise_name, status, prefix) \
|
#define TRY_STATUS_PROMISE_PREFIX(promise_name, status, prefix) \
|
||||||
|
@ -27,10 +27,11 @@ namespace td {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void print_backtrace(void) {
|
void print_backtrace(void) {
|
||||||
void *buffer[128];
|
|
||||||
#if TD_PORT_WINDOWS
|
#if TD_PORT_WINDOWS
|
||||||
|
void *buffer[128];
|
||||||
USHORT nptrs = CaptureStackBackTrace(0, 128, buffer, nullptr);
|
USHORT nptrs = CaptureStackBackTrace(0, 128, buffer, nullptr);
|
||||||
#elif __GLIBC__
|
#elif __GLIBC__
|
||||||
|
void *buffer[128];
|
||||||
int nptrs = backtrace(buffer, 128);
|
int nptrs = backtrace(buffer, 128);
|
||||||
#else
|
#else
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user