Merge commit '1bbcc01091c8ca92f79821790b8857edb5a1b6b4'

This commit is contained in:
Andrea Cavalli 2021-04-03 12:53:29 +02:00
commit 1ce823b0e6
37 changed files with 262 additions and 199 deletions

View File

@ -19,6 +19,7 @@
#include "td/utils/format.h"
#include "td/utils/Gzip.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/Random.h"
#include "td/utils/ScopeGuard.h"
#include "td/utils/Time.h"
@ -863,7 +864,7 @@ void SessionConnection::flush_packet() {
max_after = HTTP_MAX_AFTER;
auto time_to_disconnect =
min(ping_disconnect_delay() + last_pong_at_, read_disconnect_delay() + last_read_at_) - Time::now_cached();
max_wait = min(http_max_wait(), static_cast<int>(1000 * max(0.1, time_to_disconnect - rtt())));
max_wait = static_cast<int>(1000 * clamp(time_to_disconnect - rtt(), 0.1, http_max_wait()));
} else if (mode_ == Mode::Http) {
max_delay = HTTP_MAX_DELAY;
max_after = HTTP_MAX_AFTER;

View File

@ -151,8 +151,8 @@ class SessionConnection
return online_flag_ ? rtt() : 60;
}
int http_max_wait() const {
return 25 * 1000; // 25s. Longer could be closed by proxy
double http_max_wait() const {
return 25.0; // 25s. Longer could be closed by proxy
}
static constexpr int HTTP_MAX_AFTER = 10; // 0.01s
static constexpr int HTTP_MAX_DELAY = 30; // 0.03s

View File

@ -165,7 +165,7 @@ void AuthManager::check_bot_token(uint64 query_id, string bot_token) {
telegram_api::auth_importBotAuthorization(0, api_id_, api_hash_, bot_token_)));
}
void AuthManager::request_qr_code_authentication(uint64 query_id, vector<int32> other_user_ids) {
void AuthManager::request_qr_code_authentication(uint64 query_id, vector<UserId> other_user_ids) {
if (state_ != State::WaitPhoneNumber) {
if ((state_ == State::WaitCode || state_ == State::WaitPassword || state_ == State::WaitRegistration) &&
net_query_id_ == 0) {
@ -181,8 +181,7 @@ void AuthManager::request_qr_code_authentication(uint64 query_id, vector<int32>
"Cannot request QR code authentication after bot token was entered. You need to log out first"));
}
for (auto &other_user_id : other_user_ids) {
UserId user_id(other_user_id);
if (!user_id.is_valid()) {
if (!other_user_id.is_valid()) {
return on_query_error(query_id, Status::Error(400, "Invalid user_id among other user_ids"));
}
}
@ -200,8 +199,8 @@ void AuthManager::request_qr_code_authentication(uint64 query_id, vector<int32>
void AuthManager::send_export_login_token_query() {
poll_export_login_code_timeout_.cancel_timeout();
start_net_query(NetQueryType::RequestQrCode,
G()->net_query_creator().create_unauth(
telegram_api::auth_exportLoginToken(api_id_, api_hash_, vector<int32>(other_user_ids_))));
G()->net_query_creator().create_unauth(telegram_api::auth_exportLoginToken(
api_id_, api_hash_, UserId::get_input_user_ids(other_user_ids_))));
}
void AuthManager::set_login_token_expires_at(double login_token_expires_at) {

View File

@ -9,10 +9,10 @@
#include "td/telegram/net/NetActor.h"
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/SendCodeHelper.h"
#include "td/telegram/TermsOfService.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/TermsOfService.h"
#include "td/telegram/UserId.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
@ -38,7 +38,7 @@ class AuthManager : public NetActor {
void resend_authentication_code(uint64 query_id);
void check_code(uint64 query_id, string code);
void register_user(uint64 query_id, string first_name, string last_name);
void request_qr_code_authentication(uint64 query_id, vector<int32> other_user_ids);
void request_qr_code_authentication(uint64 query_id, vector<UserId> other_user_ids);
void check_bot_token(uint64 query_id, string bot_token);
void check_password(uint64 query_id, string password);
void request_password_recovery(uint64 query_id);
@ -113,7 +113,7 @@ class AuthManager : public NetActor {
SendCodeHelper send_code_helper_;
// WaitQrCodeConfirmation
vector<int32> other_user_ids_;
vector<UserId> other_user_ids_;
string login_token_;
double login_token_expires_at_ = 0;
@ -130,7 +130,7 @@ class AuthManager : public NetActor {
return state;
}
static DbState wait_qr_code_confirmation(int32 api_id, string api_hash, vector<int32> other_user_ids,
static DbState wait_qr_code_confirmation(int32 api_id, string api_hash, vector<UserId> other_user_ids,
string login_token, double login_token_expires_at) {
DbState state(State::WaitQrCodeConfirmation, api_id, api_hash);
state.other_user_ids_ = std::move(other_user_ids);
@ -179,7 +179,7 @@ class AuthManager : public NetActor {
string code_;
// State::WaitQrCodeConfirmation
vector<int32> other_user_ids_;
vector<UserId> other_user_ids_;
string login_token_;
double login_token_expires_at_ = 0.0;
int32 imported_dc_id_ = -1;

View File

@ -278,7 +278,7 @@ class TdReceiver {
if (is_locked) {
LOG(FATAL) << "Receive is called after Client destroy, or simultaneously from different threads";
}
auto response = receive_unlocked(timeout);
auto response = receive_unlocked(clamp(timeout, 0.0, 1000000.0));
is_locked = receive_lock_.exchange(false);
CHECK(is_locked);
VLOG(td_requests) << "End to wait for updates, returning object " << response.request_id << ' '

View File

@ -17,7 +17,7 @@
namespace td {
Contact::Contact(string phone_number, string first_name, string last_name, string vcard, int32 user_id)
Contact::Contact(string phone_number, string first_name, string last_name, string vcard, UserId user_id)
: phone_number_(std::move(phone_number))
, first_name_(std::move(first_name))
, last_name_(std::move(last_name))
@ -96,7 +96,8 @@ Result<Contact> process_input_message_contact(tl_object_ptr<td_api::InputMessage
return Status::Error(400, "vCard must be encoded in UTF-8");
}
return Contact(contact->phone_number_, contact->first_name_, contact->last_name_, contact->vcard_, contact->user_id_);
return Contact(contact->phone_number_, contact->first_name_, contact->last_name_, contact->vcard_,
UserId(contact->user_id_));
}
} // namespace td

View File

@ -40,7 +40,7 @@ class Contact {
public:
Contact() = default;
Contact(string phone_number, string first_name, string last_name, string vcard, int32 user_id);
Contact(string phone_number, string first_name, string last_name, string vcard, UserId user_id);
void set_user_id(UserId user_id);

View File

@ -5327,7 +5327,8 @@ std::pair<vector<UserId>, vector<int32>> ContactsManager::import_contacts(
td_->create_handler<ImportContactsQuery>(std::move(promise))
->send(transform(contacts,
[](const tl_object_ptr<td_api::contact> &contact) {
return Contact(contact->phone_number_, contact->first_name_, contact->last_name_, string(), 0);
return Contact(contact->phone_number_, contact->first_name_, contact->last_name_, string(),
UserId());
}),
random_id);
return {};
@ -5517,7 +5518,7 @@ std::pair<vector<UserId>, vector<int32>> ContactsManager::change_imported_contac
auto new_contacts = transform(std::move(contacts), [](tl_object_ptr<td_api::contact> &&contact) {
return Contact(std::move(contact->phone_number_), std::move(contact->first_name_), std::move(contact->last_name_),
string(), 0);
string(), UserId());
});
vector<size_t> new_contacts_unique_id(new_contacts.size());
@ -9571,7 +9572,8 @@ void ContactsManager::on_load_channel_full_from_database(ChannelId channel_id, s
td_->group_call_manager_->on_update_dialog_about(DialogId(channel_id), channel_full->description, false);
td_->messages_manager_->on_dialog_bots_updated(DialogId(channel_id), channel_full->bot_user_ids, true);
send_closure_later(G()->messages_manager(), &MessagesManager::on_dialog_bots_updated, DialogId(channel_id),
channel_full->bot_user_ids, true);
update_channel_full(channel_full, channel_id, true);
@ -9964,7 +9966,8 @@ void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id, bool
}
on_update_dialog_administrators(DialogId(chat_id), std::move(administrators), chat_full->version != -1,
from_database);
td_->messages_manager_->on_dialog_bots_updated(DialogId(chat_id), std::move(bot_user_ids), from_database);
send_closure_later(G()->messages_manager(), &MessagesManager::on_dialog_bots_updated, DialogId(chat_id),
std::move(bot_user_ids), from_database);
{
Chat *c = get_chat(chat_id);
@ -11579,7 +11582,7 @@ void ContactsManager::on_get_channel_participants(
(filter.is_contacts() && !is_user_contact(participant.user_id)) ||
(filter.is_restricted() && !participant.status.is_restricted()) ||
(filter.is_banned() && !participant.status.is_banned())) {
bool skip_error = (filter.is_administrators() && is_user_deleted(participant.user_id)) ||
bool skip_error = ((filter.is_administrators() || filter.is_bots()) && is_user_deleted(participant.user_id)) ||
(filter.is_contacts() && participant.user_id == get_my_id());
if (!skip_error) {
LOG(ERROR) << "Receive " << participant << ", while searching for " << filter << " in " << channel_id
@ -11749,7 +11752,7 @@ void ContactsManager::speculative_add_channel_participants(ChannelId channel_id,
return;
}
speculative_add_channel_participants(channel_id, delta_participant_count, by_me);
speculative_add_channel_participant_count(channel_id, delta_participant_count, by_me);
}
void ContactsManager::speculative_delete_channel_participant(ChannelId channel_id, UserId deleted_user_id, bool by_me) {
@ -11777,18 +11780,18 @@ void ContactsManager::speculative_delete_channel_participant(ChannelId channel_i
}
}
speculative_add_channel_participants(channel_id, -1, by_me);
speculative_add_channel_participant_count(channel_id, -1, by_me);
}
void ContactsManager::speculative_add_channel_participants(ChannelId channel_id, int32 delta_participant_count,
bool by_me) {
void ContactsManager::speculative_add_channel_participant_count(ChannelId channel_id, int32 delta_participant_count,
bool by_me) {
if (by_me) {
// Currently ignore all changes made by the current user, because they may be already counted
invalidate_channel_full(channel_id, false); // just in case
return;
}
auto channel_full = get_channel_full_force(channel_id, "speculative_add_channel_participants");
auto channel_full = get_channel_full_force(channel_id, "speculative_add_channel_participant_count");
auto min_count = channel_full == nullptr ? 0 : channel_full->administrator_count;
auto c = get_channel_force(channel_id);
@ -13097,7 +13100,8 @@ void ContactsManager::on_update_channel_bot_user_ids(ChannelId channel_id, vecto
auto channel_full = get_channel_full_force(channel_id, "on_update_channel_bot_user_ids");
if (channel_full == nullptr) {
td_->messages_manager_->on_dialog_bots_updated(DialogId(channel_id), std::move(bot_user_ids), false);
send_closure_later(G()->messages_manager(), &MessagesManager::on_dialog_bots_updated, DialogId(channel_id),
std::move(bot_user_ids), false);
return;
}
on_update_channel_full_bot_user_ids(channel_full, channel_id, std::move(bot_user_ids));
@ -13108,7 +13112,8 @@ void ContactsManager::on_update_channel_full_bot_user_ids(ChannelFull *channel_f
vector<UserId> &&bot_user_ids) {
CHECK(channel_full != nullptr);
if (channel_full->bot_user_ids != bot_user_ids) {
td_->messages_manager_->on_dialog_bots_updated(DialogId(channel_id), bot_user_ids, false);
send_closure_later(G()->messages_manager(), &MessagesManager::on_dialog_bots_updated, DialogId(channel_id),
bot_user_ids, false);
channel_full->bot_user_ids = std::move(bot_user_ids);
channel_full->need_save_to_database = true;
}

View File

@ -1256,7 +1256,7 @@ class ContactsManager : public Actor {
static bool speculative_add_count(int32 &count, int32 delta_count, int32 min_count = 0);
void speculative_add_channel_participants(ChannelId channel_id, int32 delta_participant_count, bool by_me);
void speculative_add_channel_participant_count(ChannelId channel_id, int32 delta_participant_count, bool by_me);
void speculative_add_channel_user(ChannelId channel_id, UserId user_id, DialogParticipantStatus new_status,
DialogParticipantStatus old_status);

View File

@ -120,7 +120,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DeviceTokenManage
}
void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> device_token_ptr,
vector<int32> other_user_ids,
vector<UserId> other_user_ids,
Promise<td_api::object_ptr<td_api::pushReceiverId>> promise) {
CHECK(device_token_ptr != nullptr);
TokenType token_type;
@ -227,8 +227,7 @@ void DeviceTokenManager::register_device(tl_object_ptr<td_api::DeviceToken> devi
return promise.set_error(Status::Error(400, "Device token must be encoded in UTF-8"));
}
for (auto &other_user_id : other_user_ids) {
UserId user_id(other_user_id);
if (!user_id.is_valid()) {
if (!other_user_id.is_valid()) {
return promise.set_error(Status::Error(400, "Invalid user_id among other user_ids"));
}
}
@ -373,12 +372,12 @@ void DeviceTokenManager::loop() {
auto other_user_ids = info.other_user_ids;
if (info.state == TokenInfo::State::Unregister) {
net_query = G()->net_query_creator().create(
telegram_api::account_unregisterDevice(token_type, info.token, std::move(other_user_ids)));
telegram_api::account_unregisterDevice(token_type, info.token, UserId::get_input_user_ids(other_user_ids)));
} else {
int32 flags = telegram_api::account_registerDevice::NO_MUTED_MASK;
net_query = G()->net_query_creator().create(
telegram_api::account_registerDevice(flags, false /*ignored*/, token_type, info.token, info.is_app_sandbox,
BufferSlice(info.encryption_key), std::move(other_user_ids)));
net_query = G()->net_query_creator().create(telegram_api::account_registerDevice(
flags, false /*ignored*/, token_type, info.token, info.is_app_sandbox, BufferSlice(info.encryption_key),
UserId::get_input_user_ids(other_user_ids)));
}
info.net_query_id = net_query->id();
G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this, token_type));

View File

@ -10,8 +10,8 @@
#include "td/actor/PromiseFuture.h"
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/td_api.h"
#include "td/telegram/UserId.h"
#include "td/utils/common.h"
#include "td/utils/Slice.h"
@ -26,7 +26,7 @@ class DeviceTokenManager : public NetQueryCallback {
public:
explicit DeviceTokenManager(ActorShared<> parent) : parent_(std::move(parent)) {
}
void register_device(tl_object_ptr<td_api::DeviceToken> device_token_ptr, vector<int32> other_user_ids,
void register_device(tl_object_ptr<td_api::DeviceToken> device_token_ptr, vector<UserId> other_user_ids,
Promise<td_api::object_ptr<td_api::pushReceiverId>> promise);
void reregister_device();
@ -55,7 +55,7 @@ class DeviceTokenManager : public NetQueryCallback {
State state = State::Sync;
string token;
uint64 net_query_id = 0;
vector<int32> other_user_ids;
vector<UserId> other_user_ids;
bool is_app_sandbox = false;
bool encrypt = false;
string encryption_key;

View File

@ -1452,12 +1452,12 @@ void GroupCallManager::on_update_group_call_participants(
continue;
}
if (participant.joined_date == 0) {
if (version > group_call->leave_version) {
if (group_call == nullptr || version > group_call->leave_version) {
diff--;
}
remove_recent_group_call_speaker(input_group_call_id, participant.dialog_id);
} else {
if (participant.is_just_joined && version >= group_call->leave_version) {
if (participant.is_just_joined && (group_call == nullptr || version >= group_call->leave_version)) {
diff++;
}
on_participant_speaking_in_group_call(input_group_call_id, participant);

View File

@ -1428,10 +1428,10 @@ void InlineQueriesManager::on_get_inline_query_results(UserId bot_user_id, uint6
auto inline_message_contact =
static_cast<const telegram_api::botInlineMessageMediaContact *>(result->send_message_.get());
Contact c(inline_message_contact->phone_number_, inline_message_contact->first_name_,
inline_message_contact->last_name_, inline_message_contact->vcard_, 0);
inline_message_contact->last_name_, inline_message_contact->vcard_, UserId());
contact->contact_ = c.get_contact_object();
} else {
Contact c(std::move(result->description_), std::move(result->title_), string(), string(), 0);
Contact c(std::move(result->description_), std::move(result->title_), string(), string(), UserId());
contact->contact_ = c.get_contact_object();
}
contact->thumbnail_ = register_thumbnail(std::move(result->thumb_));

View File

@ -21,7 +21,7 @@ namespace td {
* Interface for managing the internal logging of TDLib.
* By default TDLib writes logs to stderr or an OS specific log and uses a verbosity level of 5.
* These functions are deprecated since TDLib 1.4.0 in favor of the td::td_api::setLogVerbosityLevel,
* td::td_api::setLogStream and other synchronous requests for managing the intrenal TDLib logging.
* td::td_api::setLogStream and other synchronous requests for managing the internal TDLib logging.
*/
class Log {
public:

View File

@ -936,6 +936,7 @@ static void store(const MessageContent *content, StorerT &storer) {
bool has_telegram_payment_charge_id = !m->telegram_payment_charge_id.empty();
bool has_provider_payment_charge_id = !m->provider_payment_charge_id.empty();
bool has_invoice_message_id = m->invoice_message_id.is_valid();
bool is_correctly_stored = true;
BEGIN_STORE_FLAGS();
STORE_FLAG(has_payload);
STORE_FLAG(has_shipping_option_id);
@ -943,14 +944,15 @@ static void store(const MessageContent *content, StorerT &storer) {
STORE_FLAG(has_telegram_payment_charge_id);
STORE_FLAG(has_provider_payment_charge_id);
STORE_FLAG(has_invoice_message_id);
STORE_FLAG(is_correctly_stored);
END_STORE_FLAGS();
store(m->currency, storer);
store(m->total_amount, storer);
if (has_payload) {
store(m->total_amount, storer);
store(m->invoice_payload, storer);
}
if (has_shipping_option_id) {
store(m->invoice_payload, storer);
store(m->shipping_option_id, storer);
}
if (has_order_info) {
store(m->order_info, storer);
@ -1309,6 +1311,7 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
bool has_telegram_payment_charge_id;
bool has_provider_payment_charge_id;
bool has_invoice_message_id;
bool is_correctly_stored;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_payload);
PARSE_FLAG(has_shipping_option_id);
@ -1316,14 +1319,24 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
PARSE_FLAG(has_telegram_payment_charge_id);
PARSE_FLAG(has_provider_payment_charge_id);
PARSE_FLAG(has_invoice_message_id);
PARSE_FLAG(is_correctly_stored);
END_PARSE_FLAGS();
parse(m->currency, parser);
parse(m->total_amount, parser);
if (has_payload) {
parse(m->total_amount, parser);
}
if (has_shipping_option_id) {
parse(m->invoice_payload, parser);
if (is_correctly_stored) {
if (has_payload) {
parse(m->invoice_payload, parser);
}
if (has_shipping_option_id) {
parse(m->shipping_option_id, parser);
}
} else {
if (has_payload) {
parse(m->total_amount, parser);
}
if (has_shipping_option_id) {
parse(m->invoice_payload, parser);
}
}
if (has_order_info) {
parse(m->order_info, parser);
@ -1337,7 +1350,11 @@ static void parse(unique_ptr<MessageContent> &content, ParserT &parser) {
if (has_invoice_message_id) {
parse(m->invoice_message_id, parser);
}
content = std::move(m);
if (is_correctly_stored) {
content = std::move(m);
} else {
content = make_unique<MessageUnsupported>(0);
}
break;
}
case MessageContentType::ContactRegistered:
@ -1514,7 +1531,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id,
auto inline_message_contact = move_tl_object_as<telegram_api::botInlineMessageMediaContact>(inline_message);
result.message_content = make_unique<MessageContact>(
Contact(std::move(inline_message_contact->phone_number_), std::move(inline_message_contact->first_name_),
std::move(inline_message_contact->last_name_), std::move(inline_message_contact->vcard_), 0));
std::move(inline_message_contact->last_name_), std::move(inline_message_contact->vcard_), UserId()));
reply_markup = std::move(inline_message_contact->reply_markup_);
break;
}
@ -3915,7 +3932,7 @@ unique_ptr<MessageContent> get_secret_message_content(
}
return make_unique<MessageContact>(
Contact(std::move(message_contact->phone_number_), std::move(message_contact->first_name_),
std::move(message_contact->last_name_), string(), message_contact->user_id_));
std::move(message_contact->last_name_), string(), UserId(message_contact->user_id_)));
}
case secret_api::decryptedMessageMediaWebPage::ID: {
auto media_web_page = move_tl_object_as<secret_api::decryptedMessageMediaWebPage>(media);
@ -4082,9 +4099,10 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
td->contacts_manager_->get_user_id_object(UserId(message_contact->user_id_),
"MessageMediaContact"); // to ensure updateUser
}
return make_unique<MessageContact>(Contact(
std::move(message_contact->phone_number_), std::move(message_contact->first_name_),
std::move(message_contact->last_name_), std::move(message_contact->vcard_), message_contact->user_id_));
return make_unique<MessageContact>(
Contact(std::move(message_contact->phone_number_), std::move(message_contact->first_name_),
std::move(message_contact->last_name_), std::move(message_contact->vcard_),
UserId(message_contact->user_id_)));
}
case telegram_api::messageMediaDocument::ID: {
auto message_document = move_tl_object_as<telegram_api::messageMediaDocument>(media);

View File

@ -114,7 +114,7 @@ Status init_messages_db(SqliteDb &db, int32 version) {
LOG(INFO) << "Create new message database";
TRY_STATUS(
db.exec("CREATE TABLE IF NOT EXISTS messages (dialog_id INT8, message_id INT8, unique_message_id INT4, "
"sender_user_id INT4, random_id INT8, data BLOB, ttl_expires_at INT4, index_mask INT4, search_id INT8, "
"sender_user_id INT8, random_id INT8, data BLOB, ttl_expires_at INT4, index_mask INT4, search_id INT8, "
"text STRING, notification_id INT4, top_thread_message_id INT8, PRIMARY KEY (dialog_id, message_id))"));
TRY_STATUS(
@ -297,7 +297,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
}
if (sender_user_id.is_valid()) {
add_message_stmt_.bind_int32(4, sender_user_id.get()).ensure();
add_message_stmt_.bind_int64(4, sender_user_id.get()).ensure();
} else {
add_message_stmt_.bind_null(4).ensure();
}
@ -430,7 +430,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
delete_dialog_messages_from_user_stmt_.reset();
};
delete_dialog_messages_from_user_stmt_.bind_int64(1, dialog_id.get()).ensure();
delete_dialog_messages_from_user_stmt_.bind_int32(2, sender_user_id.get()).ensure();
delete_dialog_messages_from_user_stmt_.bind_int64(2, sender_user_id.get()).ensure();
delete_dialog_messages_from_user_stmt_.step().ensure();
return Status::OK();
}

View File

@ -6332,7 +6332,7 @@ int32 MessagesManager::get_message_index_mask(DialogId dialog_id, const Message
void MessagesManager::update_reply_count_by_message(Dialog *d, int diff, const Message *m) {
if (td_->auth_manager_->is_bot() || !m->top_thread_message_id.is_valid() ||
m->top_thread_message_id == m->message_id || !m->message_id.is_server()) {
m->top_thread_message_id == m->message_id || !m->message_id.is_valid() || !m->message_id.is_server()) {
return;
}
@ -13653,7 +13653,7 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
reply_in_dialog_id = DialogId();
}
}
if (reply_to_message_id.is_valid() && !td_->auth_manager_->is_bot()) {
if (reply_to_message_id.is_valid() && !td_->auth_manager_->is_bot() && !message_id.is_scheduled()) {
if ((message_info.reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) {
top_thread_message_id = MessageId(ServerMessageId(message_info.reply_header->reply_to_top_id_));
} else if (!is_broadcast_channel(dialog_id)) {
@ -13716,7 +13716,7 @@ std::pair<DialogId, unique_ptr<MessagesManager::Message>> MessagesManager::creat
}
MessageReplyInfo reply_info(std::move(message_info.reply_info), td_->auth_manager_->is_bot());
if (!top_thread_message_id.is_valid() && !is_broadcast_channel(dialog_id) &&
is_active_message_reply_info(dialog_id, reply_info)) {
is_active_message_reply_info(dialog_id, reply_info) && !message_id.is_scheduled()) {
top_thread_message_id = message_id;
}
if (top_thread_message_id.is_valid() && dialog_type != DialogType::Channel) {
@ -13859,10 +13859,8 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, bool f
MessageId old_message_id = find_old_message_id(dialog_id, message_id);
bool is_sent_message = false;
if (old_message_id.is_valid()) {
LOG(INFO) << "Found temporary " << old_message_id << " for " << FullMessageId{dialog_id, message_id};
}
if (old_message_id.is_valid() || old_message_id.is_valid_scheduled()) {
LOG(INFO) << "Found temporary " << old_message_id << " for " << FullMessageId{dialog_id, message_id};
Dialog *d = get_dialog(dialog_id);
if (d == nullptr) {
LOG(ERROR) << "Message " << message_id << " received from unknown dialog " << dialog_id;
@ -13975,7 +13973,7 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, bool f
update_message_count_by_index(d, +1, m);
}
if (is_sent_message || need_update) {
if (is_sent_message || (need_update && !message_id.is_scheduled())) {
update_reply_count_by_message(d, +1, m);
update_forward_count(dialog_id, m);
}
@ -19612,8 +19610,8 @@ void MessagesManager::create_new_secret_chat(UserId user_id, Promise<SecretChatI
}
auto user = move_tl_object_as<telegram_api::inputUser>(user_base);
send_closure(G()->secret_chats_manager(), &SecretChatsManager::create_chat, user->user_id_, user->access_hash_,
std::move(promise));
send_closure(G()->secret_chats_manager(), &SecretChatsManager::create_chat, UserId(user->user_id_),
user->access_hash_, std::move(promise));
}
DialogId MessagesManager::migrate_dialog_to_megagroup(DialogId dialog_id, Promise<Unit> &&promise) {
@ -22551,7 +22549,7 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
last_added_message_id = m->message_id;
}
if (old_message == nullptr) {
add_message_dependencies(dependencies, dialog_id, m);
add_message_dependencies(dependencies, m);
added_new_message = true;
} else if (m->message_id != from_message_id) {
added_new_message = true;
@ -22893,7 +22891,7 @@ void MessagesManager::on_get_scheduled_messages_from_database(DialogId dialog_id
Message *m = add_scheduled_message_to_dialog(d, std::move(message), false, &need_update,
"on_get_scheduled_messages_from_database");
if (m != nullptr) {
add_message_dependencies(dependencies, dialog_id, m);
add_message_dependencies(dependencies, m);
added_message_ids.push_back(m->message_id);
}
}
@ -23238,11 +23236,13 @@ MessagesManager::Message *MessagesManager::get_message_to_send(
m->send_date = G()->unix_time();
m->date = is_scheduled ? options.schedule_date : m->send_date;
m->reply_to_message_id = reply_to_message_id;
m->top_thread_message_id = top_thread_message_id;
if (reply_to_message_id.is_valid()) {
const Message *reply_m = get_message(d, reply_to_message_id);
if (reply_m != nullptr && reply_m->top_thread_message_id.is_valid()) {
m->top_thread_message_id = reply_m->top_thread_message_id;
if (!is_scheduled) {
m->top_thread_message_id = top_thread_message_id;
if (reply_to_message_id.is_valid()) {
const Message *reply_m = get_message(d, reply_to_message_id);
if (reply_m != nullptr && reply_m->top_thread_message_id.is_valid()) {
m->top_thread_message_id = reply_m->top_thread_message_id;
}
}
}
m->is_channel_post = is_channel_post;
@ -23745,7 +23745,7 @@ bool MessagesManager::is_message_auto_read(DialogId dialog_id, bool is_outgoing)
}
}
void MessagesManager::add_message_dependencies(Dependencies &dependencies, DialogId dialog_id, const Message *m) {
void MessagesManager::add_message_dependencies(Dependencies &dependencies, const Message *m) {
dependencies.user_ids.insert(m->sender_user_id);
add_dialog_and_dependencies(dependencies, m->sender_dialog_id);
add_dialog_and_dependencies(dependencies, m->reply_in_dialog_id);
@ -27014,7 +27014,7 @@ Result<MessageId> MessagesManager::add_local_message(
}
m->date = G()->unix_time();
m->reply_to_message_id = get_reply_to_message_id(d, MessageId(), reply_to_message_id, false);
if (m->reply_to_message_id.is_valid()) {
if (m->reply_to_message_id.is_valid() && !message_id.is_scheduled()) {
const Message *reply_m = get_message(d, m->reply_to_message_id);
if (reply_m != nullptr) {
m->top_thread_message_id = reply_m->top_thread_message_id;
@ -32222,8 +32222,8 @@ MessagesManager::Message *MessagesManager::on_get_message_from_database(DialogId
}
Dependencies dependencies;
add_message_dependencies(dependencies, d->dialog_id, m.get());
resolve_dependencies_force(td_, dependencies, "get_message");
add_message_dependencies(dependencies, m.get());
resolve_dependencies_force(td_, dependencies, "on_get_message_from_database");
m->have_previous = false;
m->have_next = false;
@ -32300,7 +32300,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
}
}
if (!message->top_thread_message_id.is_valid() && !is_broadcast_channel(dialog_id) &&
is_visible_message_reply_info(dialog_id, message.get())) {
is_visible_message_reply_info(dialog_id, message.get()) && !message_id.is_scheduled()) {
message->top_thread_message_id = message_id;
}
@ -33028,6 +33028,8 @@ MessagesManager::Message *MessagesManager::add_scheduled_message_to_dialog(Dialo
CHECK(!message->notification_id.is_valid());
CHECK(!message->removed_notification_id.is_valid());
message->top_thread_message_id = MessageId();
if (d->deleted_message_ids.count(message_id)) {
LOG(INFO) << "Skip adding deleted " << message_id << " to " << dialog_id << " from " << source;
debug_add_message_to_dialog_fail_reason_ = "adding deleted scheduled message";
@ -34197,9 +34199,9 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr<Dialog> &&d,
break;
}
case DialogType::SecretChat:
if (!d->last_new_message_id.is_valid()) {
if (d->last_new_message_id.get() <= MessageId::min().get()) {
LOG(INFO) << "Set " << d->dialog_id << " last new message in add_new_dialog";
d->last_new_message_id = MessageId::min();
d->last_new_message_id = MessageId::min().get_next_message_id(MessageType::Local);
}
if (!d->notification_settings.is_secret_chat_show_preview_fixed) {
@ -34489,8 +34491,11 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
d->debug_last_new_message_id = d->last_new_message_id;
if (last_database_message != nullptr) {
Dependencies dependencies;
add_message_dependencies(dependencies, last_database_message.get());
int32 dependent_dialog_count = 0;
auto depend_on_dialog = [&](DialogId other_dialog_id) {
for (auto &other_dialog_id : dependencies.dialog_ids) {
if (other_dialog_id.is_valid() && !have_dialog(other_dialog_id)) {
LOG(INFO) << "Postpone adding of last message in " << dialog_id << " because of cyclic dependency with "
<< other_dialog_id;
@ -34498,13 +34503,6 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
dependent_dialog_count++;
}
};
if (last_database_message->forward_info != nullptr) {
depend_on_dialog(last_database_message->forward_info->sender_dialog_id);
depend_on_dialog(last_database_message->forward_info->from_dialog_id);
}
depend_on_dialog(last_database_message->sender_dialog_id);
depend_on_dialog(last_database_message->reply_in_dialog_id);
depend_on_dialog(last_database_message->real_forward_from_dialog_id);
if (dependent_dialog_count == 0) {
add_dialog_last_database_message(d, std::move(last_database_message));
@ -34524,6 +34522,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
if (default_join_group_call_as_dialog_id != d->default_join_group_call_as_dialog_id) {
CHECK(default_join_group_call_as_dialog_id.is_valid());
CHECK(!d->default_join_group_call_as_dialog_id.is_valid());
if (!have_dialog(default_join_group_call_as_dialog_id)) {
LOG(INFO) << "Postpone adding of default join voice chat as " << default_join_group_call_as_dialog_id << " in "
<< dialog_id;
@ -34904,7 +34903,8 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen
}
auto folder_ptr = get_dialog_folder(d->folder_id);
CHECK(folder_ptr != nullptr);
LOG_CHECK(folder_ptr != nullptr) << dialog_id << ' ' << d->folder_id << ' ' << is_loaded_from_database << ' '
<< source;
auto &folder = *folder_ptr;
if (old_date == new_date) {
if (new_order == DEFAULT_ORDER) {
@ -35316,7 +35316,7 @@ unique_ptr<MessagesManager::Dialog> MessagesManager::parse_dialog(DialogId dialo
add_message_sender_dependencies(dependencies, d->default_join_group_call_as_dialog_id);
}
if (d->messages != nullptr) {
add_message_dependencies(dependencies, dialog_id, d->messages.get());
add_message_dependencies(dependencies, d->messages.get());
}
if (d->draft_message != nullptr) {
add_formatted_text_dependencies(dependencies, &d->draft_message->input_message_text.text);
@ -36365,16 +36365,16 @@ void MessagesManager::speculatively_update_channel_participants(DialogId dialog_
bool by_me = m->sender_user_id == my_user_id;
switch (m->content->get_type()) {
case MessageContentType::ChatAddUsers:
td_->contacts_manager_->speculative_add_channel_participants(
channel_id, get_message_content_added_user_ids(m->content.get()), m->sender_user_id, m->date, by_me);
send_closure_later(G()->contacts_manager(), &ContactsManager::speculative_add_channel_participants, channel_id,
get_message_content_added_user_ids(m->content.get()), m->sender_user_id, m->date, by_me);
break;
case MessageContentType::ChatJoinedByLink:
td_->contacts_manager_->speculative_add_channel_participants(channel_id, {m->sender_user_id}, m->sender_user_id,
m->date, by_me);
send_closure_later(G()->contacts_manager(), &ContactsManager::speculative_add_channel_participants, channel_id,
vector<UserId>{m->sender_user_id}, m->sender_user_id, m->date, by_me);
break;
case MessageContentType::ChatDeleteUser:
td_->contacts_manager_->speculative_delete_channel_participant(
channel_id, get_message_content_deleted_user_id(m->content.get()), by_me);
send_closure_later(G()->contacts_manager(), &ContactsManager::speculative_delete_channel_participant, channel_id,
get_message_content_deleted_user_id(m->content.get()), by_me);
break;
default:
break;
@ -36618,7 +36618,7 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
Dependencies dependencies;
add_dialog_dependencies(dependencies, dialog_id);
add_message_dependencies(dependencies, dialog_id, m.get());
add_message_dependencies(dependencies, m.get());
resolve_dependencies_force(td_, dependencies, "SendMessageLogEvent");
m->content =
@ -36648,7 +36648,7 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
Dependencies dependencies;
add_dialog_dependencies(dependencies, dialog_id);
add_message_dependencies(dependencies, dialog_id, m.get());
add_message_dependencies(dependencies, m.get());
resolve_dependencies_force(td_, dependencies, "SendBotStartMessageLogEvent");
auto bot_user_id = log_event.bot_user_id;
@ -36685,7 +36685,7 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
Dependencies dependencies;
add_dialog_dependencies(dependencies, dialog_id);
add_message_dependencies(dependencies, dialog_id, m.get());
add_message_dependencies(dependencies, m.get());
resolve_dependencies_force(td_, dependencies, "SendInlineQueryResultMessageLogEvent");
m->content = dup_message_content(td_, dialog_id, m->content.get(), MessageContentDupType::SendViaBot,
@ -36714,7 +36714,7 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
Dependencies dependencies;
add_dialog_dependencies(dependencies, dialog_id);
add_message_dependencies(dependencies, dialog_id, m.get());
add_message_dependencies(dependencies, m.get());
resolve_dependencies_force(td_, dependencies, "SendScreenshotTakenNotificationMessageLogEvent");
auto result_message = continue_send_message(dialog_id, std::move(m), event.id_);
@ -36740,7 +36740,7 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
add_dialog_dependencies(dependencies, to_dialog_id);
add_dialog_dependencies(dependencies, from_dialog_id);
for (auto &m : messages) {
add_message_dependencies(dependencies, to_dialog_id, m.get());
add_message_dependencies(dependencies, m.get());
}
resolve_dependencies_force(td_, dependencies, "ForwardMessagesLogEvent");

View File

@ -2932,7 +2932,7 @@ class MessagesManager : public Actor {
static void dump_debug_message_op(const Dialog *d, int priority = 0);
static void add_message_dependencies(Dependencies &dependencies, DialogId dialog_id, const Message *m);
static void add_message_dependencies(Dependencies &dependencies, const Message *m);
void save_send_message_log_event(DialogId dialog_id, const Message *m);

View File

@ -849,7 +849,8 @@ int32 NotificationManager::get_notification_delay_ms(DialogId dialog_id, const P
return 0;
}();
auto passed_time_ms = max(0, static_cast<int32>((G()->server_time_cached() - notification.date - 1) * 1000));
auto passed_time_ms =
static_cast<int32>(clamp(G()->server_time_cached() - notification.date - 1, 0.0, 1000000.0) * 1000);
return max(max(min_delay_ms, delay_ms) - passed_time_ms, MIN_NOTIFICATION_DELAY_MS);
}
@ -1861,7 +1862,9 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti
bool is_total_count_changed = false;
if ((!have_all_notifications && is_permanent) || (have_all_notifications && is_found)) {
if (group_it->second.total_count == 0) {
LOG(ERROR) << "Total notification count became negative in " << group_id << " after removing " << notification_id;
LOG(ERROR) << "Total notification count became negative in " << group_it->second << " after removing "
<< notification_id << " with is_permanent = " << is_permanent << ", is_found = " << is_found
<< ", force_update = " << force_update << " from " << source;
} else {
group_it->second.total_count--;
is_total_count_changed = true;
@ -3824,7 +3827,7 @@ Result<int64> NotificationManager::get_push_receiver_id(string payload) {
return Status::Error(400, "Expected user_id as a String or a Number");
}
Slice user_id_str = user_id.type() == JsonValue::Type::String ? user_id.get_string() : user_id.get_number();
auto r_user_id = to_integer_safe<int32>(user_id_str);
auto r_user_id = to_integer_safe<int64>(user_id_str);
if (r_user_id.is_error()) {
return Status::Error(400, PSLICE() << "Failed to get user_id from " << user_id_str);
}

View File

@ -158,12 +158,16 @@ static tl_object_ptr<td_api::paymentsProviderStripe> convert_payment_provider(
auto r_need_postal_code = get_json_object_bool_field(value.get_object(), "need_zip", false);
auto r_need_cardholder_name = get_json_object_bool_field(value.get_object(), "need_cardholder_name", false);
auto r_publishable_key = get_json_object_string_field(value.get_object(), "publishable_key", false);
// TODO support "gpay_parameters":{"gateway":"stripe","stripe:publishableKey":"...","stripe:version":"..."}
if (value.get_object().size() != 4 || r_need_country.is_error() || r_need_postal_code.is_error() ||
r_need_cardholder_name.is_error() || r_publishable_key.is_error()) {
LOG(WARNING) << "Unsupported JSON data \"" << native_parameters->data_ << '"';
if (r_need_country.is_error() || r_need_postal_code.is_error() || r_need_cardholder_name.is_error() ||
r_publishable_key.is_error()) {
LOG(ERROR) << "Unsupported JSON data \"" << native_parameters->data_ << '"';
return nullptr;
}
if (value.get_object().size() != 5) {
LOG(ERROR) << "Unsupported JSON data \"" << native_parameters->data_ << '"';
}
return make_tl_object<td_api::paymentsProviderStripe>(r_publishable_key.move_as_ok(), r_need_country.move_as_ok(),
r_need_postal_code.move_as_ok(),
@ -186,9 +190,9 @@ static tl_object_ptr<telegram_api::postAddress> convert_address(tl_object_ptr<td
if (address == nullptr) {
return nullptr;
}
return make_tl_object<telegram_api::postAddress>(std::move(address->country_code_), std::move(address->state_),
std::move(address->city_), std::move(address->street_line1_),
std::move(address->street_line2_), std::move(address->postal_code_));
return make_tl_object<telegram_api::postAddress>(std::move(address->street_line1_), std::move(address->street_line2_),
std::move(address->city_), std::move(address->state_),
std::move(address->country_code_), std::move(address->postal_code_));
}
static tl_object_ptr<td_api::orderInfo> convert_order_info(

View File

@ -185,7 +185,7 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const td_api::Use
break;
case td_api::userPrivacySettingRuleAllowUsers::ID:
type_ = Type::AllowUsers;
user_ids_ = static_cast<const td_api::userPrivacySettingRuleAllowUsers &>(rule).user_ids_;
user_ids_ = UserId::get_user_ids(static_cast<const td_api::userPrivacySettingRuleAllowUsers &>(rule).user_ids_);
break;
case td_api::userPrivacySettingRuleAllowChatMembers::ID:
type_ = Type::AllowChatParticipants;
@ -199,7 +199,8 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const td_api::Use
break;
case td_api::userPrivacySettingRuleRestrictUsers::ID:
type_ = Type::RestrictUsers;
user_ids_ = static_cast<const td_api::userPrivacySettingRuleRestrictUsers &>(rule).user_ids_;
user_ids_ =
UserId::get_user_ids(static_cast<const td_api::userPrivacySettingRuleRestrictUsers &>(rule).user_ids_);
break;
case td_api::userPrivacySettingRuleRestrictChatMembers::ID:
type_ = Type::RestrictChatParticipants;
@ -220,7 +221,7 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const telegram_ap
break;
case telegram_api::privacyValueAllowUsers::ID:
type_ = Type::AllowUsers;
user_ids_ = static_cast<const telegram_api::privacyValueAllowUsers &>(rule).users_;
user_ids_ = UserId::get_user_ids(static_cast<const telegram_api::privacyValueAllowUsers &>(rule).users_);
break;
case telegram_api::privacyValueAllowChatParticipants::ID:
type_ = Type::AllowChatParticipants;
@ -234,7 +235,7 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const telegram_ap
break;
case telegram_api::privacyValueDisallowUsers::ID:
type_ = Type::RestrictUsers;
user_ids_ = static_cast<const telegram_api::privacyValueDisallowUsers &>(rule).users_;
user_ids_ = UserId::get_user_ids(static_cast<const telegram_api::privacyValueDisallowUsers &>(rule).users_);
break;
case telegram_api::privacyValueDisallowChatParticipants::ID:
type_ = Type::RestrictChatParticipants;
@ -253,7 +254,7 @@ PrivacyManager::UserPrivacySettingRule::get_user_privacy_setting_rule_object() c
case Type::AllowAll:
return make_tl_object<td_api::userPrivacySettingRuleAllowAll>();
case Type::AllowUsers:
return make_tl_object<td_api::userPrivacySettingRuleAllowUsers>(vector<int32>{user_ids_});
return make_tl_object<td_api::userPrivacySettingRuleAllowUsers>(UserId::get_input_user_ids(user_ids_));
case Type::AllowChatParticipants:
return make_tl_object<td_api::userPrivacySettingRuleAllowChatMembers>(chat_ids_as_dialog_ids());
case Type::RestrictContacts:
@ -261,7 +262,7 @@ PrivacyManager::UserPrivacySettingRule::get_user_privacy_setting_rule_object() c
case Type::RestrictAll:
return make_tl_object<td_api::userPrivacySettingRuleRestrictAll>();
case Type::RestrictUsers:
return make_tl_object<td_api::userPrivacySettingRuleRestrictUsers>(vector<int32>{user_ids_});
return make_tl_object<td_api::userPrivacySettingRuleRestrictUsers>(UserId::get_input_user_ids(user_ids_));
case Type::RestrictChatParticipants:
return make_tl_object<td_api::userPrivacySettingRuleRestrictChatMembers>(chat_ids_as_dialog_ids());
default:
@ -298,7 +299,7 @@ Result<PrivacyManager::UserPrivacySettingRule> PrivacyManager::UserPrivacySettin
UserPrivacySettingRule result(*rule);
auto td = G()->td().get_actor_unsafe();
for (auto user_id : result.user_ids_) {
if (!td->contacts_manager_->have_user(UserId(user_id))) {
if (!td->contacts_manager_->have_user(user_id)) {
return Status::Error(500, "Got inaccessible user from the server");
}
}
@ -320,7 +321,7 @@ Result<PrivacyManager::UserPrivacySettingRule> PrivacyManager::UserPrivacySettin
vector<tl_object_ptr<telegram_api::InputUser>> PrivacyManager::UserPrivacySettingRule::get_input_users() const {
vector<tl_object_ptr<telegram_api::InputUser>> result;
for (auto user_id : user_ids_) {
auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(UserId(user_id));
auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(user_id);
if (input_user != nullptr) {
result.push_back(std::move(input_user));
} else {
@ -347,7 +348,7 @@ vector<int64> PrivacyManager::UserPrivacySettingRule::chat_ids_as_dialog_ids() c
return result;
}
vector<int32> PrivacyManager::UserPrivacySettingRule::get_restricted_user_ids() const {
vector<UserId> PrivacyManager::UserPrivacySettingRule::get_restricted_user_ids() const {
if (type_ == Type::RestrictUsers) {
return user_ids_;
}
@ -405,12 +406,13 @@ vector<tl_object_ptr<telegram_api::InputPrivacyRule>> PrivacyManager::UserPrivac
return result;
}
vector<int32> PrivacyManager::UserPrivacySettingRules::get_restricted_user_ids() const {
vector<int32> result;
vector<UserId> PrivacyManager::UserPrivacySettingRules::get_restricted_user_ids() const {
vector<UserId> result;
for (auto &rule : rules_) {
combine(result, rule.get_restricted_user_ids());
}
td::unique(result);
std::sort(result.begin(), result.end(), [](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); });
result.erase(std::unique(result.begin(), result.end()), result.end());
return result;
}
@ -530,12 +532,12 @@ void PrivacyManager::do_update_privacy(UserPrivacySetting user_privacy_setting,
if (old_restricted != new_restricted) {
// if a user was unrestricted, it is not received from the server anymore
// we need to reget their online status manually
std::vector<int32> unrestricted;
std::vector<UserId> unrestricted;
std::set_difference(old_restricted.begin(), old_restricted.end(), new_restricted.begin(),
new_restricted.end(), std::back_inserter(unrestricted));
new_restricted.end(), std::back_inserter(unrestricted),
[](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); });
for (auto &user_id : unrestricted) {
send_closure_later(G()->contacts_manager(), &ContactsManager::reload_user, UserId(user_id),
Promise<Unit>());
send_closure_later(G()->contacts_manager(), &ContactsManager::reload_user, user_id, Promise<Unit>());
}
}
break;

View File

@ -9,6 +9,7 @@
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
@ -83,7 +84,7 @@ class PrivacyManager : public NetQueryCallback {
return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_;
}
vector<int32> get_restricted_user_ids() const;
vector<UserId> get_restricted_user_ids() const;
private:
enum class Type : int32 {
@ -97,7 +98,7 @@ class PrivacyManager : public NetQueryCallback {
RestrictChatParticipants
} type_ = Type::RestrictAll;
vector<int32> user_ids_;
vector<UserId> user_ids_;
vector<int32> chat_ids_;
vector<tl_object_ptr<telegram_api::InputUser>> get_input_users() const;
@ -130,7 +131,7 @@ class PrivacyManager : public NetQueryCallback {
return rules_ == other.rules_;
}
vector<int32> get_restricted_user_ids() const;
vector<UserId> get_restricted_user_ids() const;
private:
vector<UserPrivacySettingRule> rules_;

View File

@ -83,7 +83,7 @@ void SecretChatActor::update_chat(telegram_api::object_ptr<telegram_api::Encrypt
loop();
}
void SecretChatActor::create_chat(int32 user_id, int64 user_access_hash, int32 random_id,
void SecretChatActor::create_chat(UserId user_id, int64 user_access_hash, int32 random_id,
Promise<SecretChatId> promise) {
if (close_flag_) {
promise.set_error(Status::Error(400, "Chat is closed"));
@ -826,7 +826,7 @@ void SecretChatActor::do_create_chat_impl(unique_ptr<log_event::CreateSecretChat
}
telegram_api::object_ptr<telegram_api::inputUser> SecretChatActor::get_input_user() {
return telegram_api::make_object<telegram_api::inputUser>(auth_state_.user_id, auth_state_.user_access_hash);
return telegram_api::make_object<telegram_api::inputUser>(auth_state_.user_id.get(), auth_state_.user_access_hash);
}
telegram_api::object_ptr<telegram_api::inputEncryptedChat> SecretChatActor::get_input_chat() {
return telegram_api::make_object<telegram_api::inputEncryptedChat>(auth_state_.id, auth_state_.access_hash);
@ -1869,7 +1869,7 @@ Status SecretChatActor::on_update_chat(telegram_api::encryptedChatRequested &upd
}
auth_state_.state = State::SendAccept;
auth_state_.x = 1;
auth_state_.user_id = update.admin_id_;
auth_state_.user_id = UserId(update.admin_id_);
auth_state_.date = context_->unix_time();
TRY_STATUS(save_common_info(update));
auth_state_.handshake.set_g_a(update.g_a_.as_slice());
@ -1963,7 +1963,7 @@ void SecretChatActor::start_up() {
auth_state_ = r_auth_state.move_as_ok();
}
if (!can_be_empty_ && auth_state_.state == State::Empty) {
LOG(WARNING) << "Close Secret chat because it is empty";
LOG(INFO) << "Skip creation of empty secret chat " << auth_state_.id;
return stop();
}
if (auth_state_.state == State::Closed) {

View File

@ -6,15 +6,6 @@
//
#pragma once
#include "td/telegram/secret_api.h"
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/mtproto/AuthKey.h"
#include "td/mtproto/DhHandshake.h"
#include "td/telegram/DhConfig.h"
#include "td/telegram/FolderId.h"
#include "td/telegram/logevent/SecretChatEvent.h"
@ -22,8 +13,16 @@
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/SecretChatDb.h"
#include "td/telegram/SecretChatId.h"
#include "td/telegram/secret_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
#include "td/mtproto/AuthKey.h"
#include "td/mtproto/DhHandshake.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/utils/buffer.h"
#include "td/utils/ChangesProcessor.h"
#include "td/utils/common.h"
@ -115,7 +114,7 @@ class SecretChatActor : public NetQueryCallback {
// First query to new chat must be one of these two
void update_chat(telegram_api::object_ptr<telegram_api::EncryptedChat> chat);
void create_chat(int32 user_id, int64 user_access_hash, int32 random_id, Promise<SecretChatId> promise);
void create_chat(UserId user_id, int64 user_access_hash, int32 random_id, Promise<SecretChatId> promise);
void cancel_chat(bool delete_history, bool is_already_discarded, Promise<> promise);
@ -374,7 +373,7 @@ class SecretChatActor : public NetQueryCallback {
int32 id = 0;
int64 access_hash = 0;
int32 user_id = 0;
UserId user_id;
int64 user_access_hash = 0;
int32 random_id = 0;
@ -408,7 +407,7 @@ class SecretChatActor : public NetQueryCallback {
storer.store_int(id);
storer.store_long(access_hash);
storer.store_int(user_id);
storer.store_int(user_id.get());
storer.store_long(user_access_hash);
storer.store_int(random_id);
if (has_date) {
@ -439,7 +438,7 @@ class SecretChatActor : public NetQueryCallback {
id = parser.fetch_int();
access_hash = parser.fetch_long();
user_id = parser.fetch_int();
user_id = UserId(parser.fetch_int());
user_access_hash = parser.fetch_long();
random_id = parser.fetch_int();
if (has_date) {
@ -701,7 +700,7 @@ class SecretChatActor : public NetQueryCallback {
return SecretChatId(auth_state_.id);
}
UserId get_user_id() {
return UserId(auth_state_.user_id);
return auth_state_.user_id;
}
void send_update_ttl(int32 ttl);
void send_update_secret_chat();

View File

@ -96,7 +96,7 @@ void SecretChatsManager::start_up() {
send_closure(G()->state_manager(), &StateManager::add_callback, make_unique<StateCallback>(actor_id(this)));
}
void SecretChatsManager::create_chat(int32 user_id, int64 user_access_hash, Promise<SecretChatId> promise) {
void SecretChatsManager::create_chat(UserId user_id, int64 user_access_hash, Promise<SecretChatId> promise) {
int32 random_id;
ActorId<SecretChatActor> actor;
do {

View File

@ -9,6 +9,7 @@
#include "td/telegram/logevent/SecretChatEvent.h"
#include "td/telegram/SecretChatActor.h"
#include "td/telegram/SecretChatId.h"
#include "td/telegram/UserId.h"
#include "td/telegram/secret_api.h"
#include "td/telegram/telegram_api.h"
@ -34,7 +35,7 @@ class SecretChatsManager : public Actor {
void on_update_chat(tl_object_ptr<telegram_api::updateEncryption> update);
void on_new_message(tl_object_ptr<telegram_api::EncryptedMessage> &&message_ptr, Promise<Unit> &&promise);
void create_chat(int32 user_id, int64 user_access_hash, Promise<SecretChatId> promise);
void create_chat(UserId user_id, int64 user_access_hash, Promise<SecretChatId> promise);
void cancel_chat(SecretChatId secret_chat_id, bool delete_history, Promise<> promise);
void send_message(SecretChatId secret_chat_id, tl_object_ptr<secret_api::decryptedMessage> message,
tl_object_ptr<telegram_api::InputEncryptedFile> file, Promise<> promise);

View File

@ -1844,11 +1844,11 @@ class CreateNewGroupChatRequest : public RequestActor<> {
}
public:
CreateNewGroupChatRequest(ActorShared<Td> td, uint64 request_id, vector<int32> user_ids, string title)
: RequestActor(std::move(td), request_id), title_(std::move(title)), random_id_(0) {
for (auto user_id : user_ids) {
user_ids_.emplace_back(user_id);
}
CreateNewGroupChatRequest(ActorShared<Td> td, uint64 request_id, vector<UserId> user_ids, string title)
: RequestActor(std::move(td), request_id)
, user_ids_(std::move(user_ids))
, title_(std::move(title))
, random_id_(0) {
}
};
@ -2062,16 +2062,14 @@ class GetChatEventLogRequest : public RequestOnceActor {
public:
GetChatEventLogRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, string &&query, int64 from_event_id,
int32 limit, tl_object_ptr<td_api::chatEventLogFilters> &&filters, vector<int32> user_ids)
int32 limit, tl_object_ptr<td_api::chatEventLogFilters> &&filters, vector<UserId> user_ids)
: RequestOnceActor(std::move(td), request_id)
, dialog_id_(dialog_id)
, query_(std::move(query))
, from_event_id_(from_event_id)
, limit_(limit)
, filters_(std::move(filters)) {
for (auto user_id : user_ids) {
user_ids_.emplace_back(user_id);
}
, filters_(std::move(filters))
, user_ids_(std::move(user_ids)) {
}
};
@ -2156,11 +2154,8 @@ class RemoveContactsRequest : public RequestActor<> {
}
public:
RemoveContactsRequest(ActorShared<Td> td, uint64 request_id, vector<int32> &&user_ids)
: RequestActor(std::move(td), request_id) {
for (auto user_id : user_ids) {
user_ids_.emplace_back(user_id);
}
RemoveContactsRequest(ActorShared<Td> td, uint64 request_id, vector<UserId> &&user_ids)
: RequestActor(std::move(td), request_id), user_ids_(std::move(user_ids)) {
set_tries(3); // load_contacts + delete_contacts
}
};
@ -4796,7 +4791,7 @@ void Td::on_request(uint64 id, td_api::registerUser &request) {
void Td::on_request(uint64 id, td_api::requestQrCodeAuthentication &request) {
send_closure(auth_manager_actor_, &AuthManager::request_qr_code_authentication, id,
std::move(request.other_user_ids_));
UserId::get_user_ids(request.other_user_ids_));
}
void Td::on_request(uint64 id, td_api::checkAuthenticationPassword &request) {
@ -4987,7 +4982,7 @@ void Td::on_request(uint64 id, td_api::registerDevice &request) {
}
CREATE_REQUEST_PROMISE();
send_closure(device_token_manager_, &DeviceTokenManager::register_device, std::move(request.device_token_),
std::move(request.other_user_ids_), std::move(promise));
UserId::get_user_ids(request.other_user_ids_), std::move(promise));
}
void Td::on_request(uint64 id, td_api::getUserPrivacySettingRules &request) {
@ -5954,7 +5949,7 @@ void Td::on_request(uint64 id, td_api::createSecretChat &request) {
void Td::on_request(uint64 id, td_api::createNewBasicGroupChat &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.title_);
CREATE_REQUEST(CreateNewGroupChatRequest, request.user_ids_, std::move(request.title_));
CREATE_REQUEST(CreateNewGroupChatRequest, UserId::get_user_ids(request.user_ids_), std::move(request.title_));
}
void Td::on_request(uint64 id, td_api::createNewSupergroupChat &request) {
@ -6096,12 +6091,8 @@ void Td::on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request)
void Td::on_request(uint64 id, const td_api::inviteGroupCallParticipants &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
vector<UserId> user_ids;
for (auto &user_id : request.user_ids_) {
user_ids.emplace_back(user_id);
}
group_call_manager_->invite_group_call_participants(GroupCallId(request.group_call_id_), std::move(user_ids),
std::move(promise));
group_call_manager_->invite_group_call_participants(GroupCallId(request.group_call_id_),
UserId::get_user_ids(request.user_ids_), std::move(promise));
}
void Td::on_request(uint64 id, const td_api::getGroupCallInviteLink &request) {
@ -6410,11 +6401,8 @@ void Td::on_request(uint64 id, const td_api::addChatMember &request) {
void Td::on_request(uint64 id, const td_api::addChatMembers &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
vector<UserId> user_ids;
for (auto &user_id : request.user_ids_) {
user_ids.emplace_back(user_id);
}
contacts_manager_->add_dialog_participants(DialogId(request.chat_id_), user_ids, std::move(promise));
contacts_manager_->add_dialog_participants(DialogId(request.chat_id_), UserId::get_user_ids(request.user_ids_),
std::move(promise));
}
void Td::on_request(uint64 id, td_api::setChatMemberStatus &request) {
@ -6561,7 +6549,7 @@ void Td::on_request(uint64 id, td_api::getChatEventLog &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.query_);
CREATE_REQUEST(GetChatEventLogRequest, request.chat_id_, std::move(request.query_), request.from_event_id_,
request.limit_, std::move(request.filters_), std::move(request.user_ids_));
request.limit_, std::move(request.filters_), UserId::get_user_ids(request.user_ids_));
}
void Td::on_request(uint64 id, const td_api::clearAllDraftMessages &request) {
@ -6801,7 +6789,7 @@ void Td::on_request(uint64 id, td_api::searchContacts &request) {
void Td::on_request(uint64 id, td_api::removeContacts &request) {
CHECK_IS_USER();
CREATE_REQUEST(RemoveContactsRequest, std::move(request.user_ids_));
CREATE_REQUEST(RemoveContactsRequest, UserId::get_user_ids(request.user_ids_));
}
void Td::on_request(uint64 id, const td_api::getImportedContactCount &request) {

View File

@ -30,6 +30,24 @@ class UserId {
template <class T, typename = std::enable_if_t<std::is_convertible<T, int32>::value>>
UserId(T user_id) = delete;
static vector<UserId> get_user_ids(const vector<int32> &input_user_ids) {
vector<UserId> user_ids;
user_ids.reserve(input_user_ids.size());
for (auto &input_user_id : input_user_ids) {
user_ids.emplace_back(input_user_id);
}
return user_ids;
}
static vector<int32> get_input_user_ids(const vector<UserId> &user_ids) {
vector<int32> input_user_ids;
input_user_ids.reserve(user_ids.size());
for (auto &user_id : user_ids) {
input_user_ids.emplace_back(user_id.get());
}
return input_user_ids;
}
bool is_valid() const {
return id > 0;
}

View File

@ -18,6 +18,7 @@
#include "td/telegram/secret_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/UserId.h"
namespace td {
namespace log_event {
@ -445,14 +446,14 @@ class CreateSecretChat : public SecretChatLogEventBase<CreateSecretChat> {
public:
static constexpr Type type = SecretChatEvent::Type::CreateSecretChat;
int32 random_id = 0;
int32 user_id = 0;
UserId user_id;
int64 user_access_hash = 0;
template <class StorerT>
void store(StorerT &storer) const {
using td::store;
store(random_id, storer);
store(user_id, storer);
store(user_id.get(), storer);
store(user_access_hash, storer);
}
@ -460,13 +461,15 @@ class CreateSecretChat : public SecretChatLogEventBase<CreateSecretChat> {
void parse(ParserT &parser) {
using td::parse;
parse(random_id, parser);
parse(user_id, parser);
int32 legacy_user_id;
parse(legacy_user_id, parser);
user_id = UserId(legacy_user_id);
parse(user_access_hash, parser);
}
StringBuilder &print(StringBuilder &sb) const override {
return sb << "[Logevent CreateSecretChat " << tag("id", log_event_id()) << tag("chat_id", random_id)
<< tag("user_id", user_id) << "]";
return sb << "[Logevent CreateSecretChat " << tag("id", log_event_id()) << tag("chat_id", random_id) << user_id
<< "]";
}
};

View File

@ -11,7 +11,7 @@
* C interface for managing the internal logging of TDLib.
* By default TDLib writes logs to stderr or an OS specific log and uses a verbosity level of 5.
* These functions are deprecated since TDLib 1.4.0 in favor of the setLogVerbosityLevel, setLogStream and
* other synchronous requests for managing the intrenal TDLib logging.
* other synchronous requests for managing the internal TDLib logging.
*/
#include "td/telegram/tdjson_export.h"

View File

@ -17,6 +17,7 @@
#include "td/utils/format.h"
#include "td/utils/List.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/ObjectPool.h"
#include "td/utils/port/thread_local.h"
#include "td/utils/ScopeGuard.h"
@ -428,7 +429,7 @@ void Scheduler::set_actor_timeout_at(ActorInfo *actor_info, double timeout_at) {
void Scheduler::run_poll(Timestamp timeout) {
// we can't wait for less than 1ms
int timeout_ms = static_cast<int32>(td::max(timeout.in(), 0.0) * 1000 + 1);
int timeout_ms = static_cast<int32>(clamp(timeout.in(), 0.0, 1000000.0) * 1000 + 1);
#if TD_PORT_WINDOWS
CHECK(inbound_queue_);
inbound_queue_->reader_get_event_fd().wait(timeout_ms);

View File

@ -74,6 +74,9 @@ Status Wget::try_init() {
TRY_STATUS(addr.init_host_port(url.host_, url.port_, prefer_ipv6_));
TRY_RESULT(fd, SocketFd::open(addr));
if (fd.empty()) {
return td::Status::Error("Sockets are not supported");
}
if (url.protocol_ == HttpUrl::Protocol::Http) {
connection_ = create_actor<HttpOutboundConnection>("Connect", std::move(fd), SslStream{},
std::numeric_limits<std::size_t>::max(), 0, 0,

View File

@ -6,6 +6,7 @@
//
#include "td/utils/buffer.h"
#include "td/utils/logging.h"
#include "td/utils/port/thread_local.h"
#include "td/utils/ThreadSafeCounter.h"
@ -106,6 +107,12 @@ void BufferAllocator::dec_ref_cnt(BufferRaw *ptr) {
}
}
size_t ChainBufferReader::advance(size_t offset, MutableSlice dest) {
LOG_CHECK(offset <= size()) << offset << " " << size() << " " << end_.offset() << " " << begin_.offset() << " "
<< sync_flag_ << " " << dest.size();
return begin_.advance(offset, dest);
}
BufferRaw *BufferAllocator::create_buffer_raw(size_t size) {
size = (size + 7) & -8;
@ -124,6 +131,7 @@ void BufferBuilder::append(BufferSlice slice) {
}
append_slow(std::move(slice));
}
void BufferBuilder::append(Slice slice) {
if (append_inplace(slice)) {
return;
@ -137,6 +145,7 @@ void BufferBuilder::prepend(BufferSlice slice) {
}
prepend_slow(std::move(slice));
}
void BufferBuilder::prepend(Slice slice) {
if (prepend_inplace(slice)) {
return;
@ -177,9 +186,11 @@ bool BufferBuilder::append_inplace(Slice slice) {
buffer_writer_.confirm_append(slice.size());
return true;
}
void BufferBuilder::append_slow(BufferSlice slice) {
to_append_.push_back(std::move(slice));
}
bool BufferBuilder::prepend_inplace(Slice slice) {
if (!to_prepend_.empty()) {
return false;
@ -193,7 +204,9 @@ bool BufferBuilder::prepend_inplace(Slice slice) {
buffer_writer_.confirm_prepend(slice.size());
return true;
}
void BufferBuilder::prepend_slow(BufferSlice slice) {
to_prepend_.push_back(std::move(slice));
}
} // namespace td

View File

@ -610,10 +610,7 @@ class ChainBufferReader {
begin_.confirm_read(size);
}
size_t advance(size_t offset, MutableSlice dest = MutableSlice()) {
CHECK(offset <= size());
return begin_.advance(offset, dest);
}
size_t advance(size_t offset, MutableSlice dest = MutableSlice());
size_t size() const {
return end_.offset() - begin_.offset();

View File

@ -629,29 +629,36 @@ bool SocketFd::empty() const {
}
PollableFdInfo &SocketFd::get_poll_info() {
CHECK(!empty());
return impl_->get_poll_info();
}
const PollableFdInfo &SocketFd::get_poll_info() const {
CHECK(!empty());
return impl_->get_poll_info();
}
const NativeFd &SocketFd::get_native_fd() const {
CHECK(!empty());
return impl_->get_native_fd();
}
Status SocketFd::get_pending_error() {
CHECK(!empty());
return impl_->get_pending_error();
}
Result<size_t> SocketFd::write(Slice slice) {
CHECK(!empty());
return impl_->write(slice);
}
Result<size_t> SocketFd::writev(Span<IoSlice> slices) {
CHECK(!empty());
return impl_->writev(slices);
}
Result<size_t> SocketFd::read(MutableSlice slice) {
CHECK(!empty());
return impl_->read(slice);
}

View File

@ -53,7 +53,7 @@ auto skip_eintr_timeout(F &&f, int32 timeout_ms) {
break;
}
left_timeout_ms =
td::max(static_cast<int32>((start.at() - Timestamp::now().at()) * 1000 + timeout_ms + 1 - 1e-9), 0);
static_cast<int32>(td::max((start.at() - Timestamp::now().at()) * 1000 + timeout_ms + 1 - 1e-9, 0.0));
}
return res;
}

View File

@ -765,7 +765,7 @@ class Master : public Actor {
auto old_context = set_context(std::make_shared<Global>());
alice_ = create_actor<SecretChatProxy>("SecretChatProxy alice", "alice", actor_shared(this, 1));
bob_ = create_actor<SecretChatProxy>("SecretChatProxy bob", "bob", actor_shared(this, 2));
send_closure(alice_->get_actor_unsafe()->actor_, &SecretChatActor::create_chat, 2, 0, 123,
send_closure(alice_->get_actor_unsafe()->actor_, &SecretChatActor::create_chat, UserId(2), 0, 123,
PromiseCreator::lambda([actor_id = actor_id(this)](Result<SecretChatId> res) {
send_closure(actor_id, &Master::got_secret_chat_id, std::move(res), 0);
}));