Merge remote-tracking branch 'td/master'
This commit is contained in:
commit
b396f9ccea
@ -49,8 +49,9 @@ bool TD_TL_writer::is_combinator_supported(const tl::tl_combinator *constructor)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TD_TL_writer::is_default_constructor_generated(const tl::tl_combinator *t, bool is_function) const {
|
||||
return tl_name == "td_api" || tl_name == "TdApi" || (t->var_count > 0 && !is_function);
|
||||
bool TD_TL_writer::is_default_constructor_generated(const tl::tl_combinator *t, bool can_be_parsed,
|
||||
bool can_be_stored) const {
|
||||
return tl_name == "td_api" || tl_name == "TdApi" || (t->var_count > 0 && can_be_parsed);
|
||||
}
|
||||
|
||||
int TD_TL_writer::get_storer_type(const tl::tl_combinator *t, const std::string &storer_name) const {
|
||||
|
@ -35,7 +35,8 @@ class TD_TL_writer : public tl::TL_writer {
|
||||
bool is_built_in_complex_type(const std::string &name) const override;
|
||||
bool is_type_bare(const tl::tl_type *t) const override;
|
||||
bool is_combinator_supported(const tl::tl_combinator *constructor) const override;
|
||||
bool is_default_constructor_generated(const tl::tl_combinator *t, bool is_function) const override;
|
||||
bool is_default_constructor_generated(const tl::tl_combinator *t, bool can_be_parsed,
|
||||
bool can_be_stored) const override;
|
||||
|
||||
int get_storer_type(const tl::tl_combinator *t, const std::string &storer_name) const override;
|
||||
Mode get_parser_mode(int type) const override;
|
||||
|
@ -9506,7 +9506,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
if (messages.size() > 1) {
|
||||
// check that messages are received in decreasing message_id order
|
||||
MessageId cur_message_id = MessageId::max();
|
||||
for (const auto &message : messages) {
|
||||
@ -35917,19 +35917,110 @@ void MessagesManager::do_get_channel_difference(DialogId dialog_id, int32 pts, b
|
||||
}
|
||||
|
||||
void MessagesManager::process_get_channel_difference_updates(
|
||||
DialogId dialog_id, vector<tl_object_ptr<telegram_api::Message>> &&new_messages,
|
||||
DialogId dialog_id, int32 new_pts, vector<tl_object_ptr<telegram_api::Message>> &&new_messages,
|
||||
vector<tl_object_ptr<telegram_api::Update>> &&other_updates) {
|
||||
LOG(INFO) << "In get channel difference for " << dialog_id << " receive " << new_messages.size() << " messages and "
|
||||
<< other_updates.size() << " other updates";
|
||||
CHECK(!debug_channel_difference_dialog_.is_valid());
|
||||
debug_channel_difference_dialog_ = dialog_id;
|
||||
for (auto &update : other_updates) {
|
||||
if (update->get_id() == telegram_api::updateMessageID::ID) {
|
||||
// in channels.getDifference updateMessageID can't be received for scheduled messages
|
||||
auto sent_message_update = move_tl_object_as<telegram_api::updateMessageID>(update);
|
||||
on_update_message_id(sent_message_update->random_id_, MessageId(ServerMessageId(sent_message_update->id_)),
|
||||
"get_channel_difference");
|
||||
update = nullptr;
|
||||
|
||||
// identifiers of edited and deleted messages
|
||||
std::unordered_set<MessageId, MessageIdHash> changed_message_ids;
|
||||
for (auto &update_ptr : other_updates) {
|
||||
bool is_good_update = true;
|
||||
switch (update_ptr->get_id()) {
|
||||
case telegram_api::updateMessageID::ID: {
|
||||
// in channels.getDifference updateMessageID can't be received for scheduled messages
|
||||
auto sent_message_update = move_tl_object_as<telegram_api::updateMessageID>(update_ptr);
|
||||
on_update_message_id(sent_message_update->random_id_, MessageId(ServerMessageId(sent_message_update->id_)),
|
||||
"get_channel_difference");
|
||||
update_ptr = nullptr;
|
||||
break;
|
||||
}
|
||||
case telegram_api::updateDeleteChannelMessages::ID: {
|
||||
auto *update = static_cast<const telegram_api::updateDeleteChannelMessages *>(update_ptr.get());
|
||||
if (DialogId(ChannelId(update->channel_id_)) != dialog_id) {
|
||||
is_good_update = false;
|
||||
} else {
|
||||
for (auto &message : update->messages_) {
|
||||
changed_message_ids.insert(MessageId(ServerMessageId(message)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case telegram_api::updateEditChannelMessage::ID: {
|
||||
auto *update = static_cast<const telegram_api::updateEditChannelMessage *>(update_ptr.get());
|
||||
auto full_message_id = get_full_message_id(update->message_, false);
|
||||
if (full_message_id.get_dialog_id() != dialog_id) {
|
||||
is_good_update = false;
|
||||
} else {
|
||||
changed_message_ids.insert(full_message_id.get_message_id());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case telegram_api::updatePinnedChannelMessages::ID: {
|
||||
auto *update = static_cast<const telegram_api::updatePinnedChannelMessages *>(update_ptr.get());
|
||||
if (DialogId(ChannelId(update->channel_id_)) != dialog_id) {
|
||||
is_good_update = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
is_good_update = false;
|
||||
break;
|
||||
}
|
||||
if (!is_good_update) {
|
||||
LOG(ERROR) << "Receive wrong update in channelDifference of " << dialog_id << ": " << to_string(update_ptr);
|
||||
update_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto is_edited_message = [](const tl_object_ptr<telegram_api::Message> &message) {
|
||||
if (message->get_id() != telegram_api::message::ID) {
|
||||
return false;
|
||||
}
|
||||
return static_cast<const telegram_api::message *>(message.get())->edit_date_ > 0;
|
||||
};
|
||||
|
||||
for (auto &message : new_messages) {
|
||||
if (is_edited_message(message)) {
|
||||
changed_message_ids.insert(get_message_id(message, false));
|
||||
}
|
||||
}
|
||||
|
||||
// extract awaited sent messages, which were edited or deleted after that
|
||||
auto postponed_updates_it = postponed_channel_updates_.find(dialog_id);
|
||||
std::map<MessageId, tl_object_ptr<telegram_api::Message>> awaited_messages;
|
||||
if (postponed_updates_it != postponed_channel_updates_.end()) {
|
||||
auto &updates = postponed_updates_it->second;
|
||||
while (!updates.empty()) {
|
||||
auto it = updates.begin();
|
||||
auto update_pts = it->second.pts;
|
||||
if (update_pts > new_pts) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto update = std::move(it->second.update);
|
||||
auto promise = std::move(it->second.promise);
|
||||
updates.erase(it);
|
||||
|
||||
if (!promise && update->get_id() == telegram_api::updateNewChannelMessage::ID) {
|
||||
auto update_new_channel_message = static_cast<telegram_api::updateNewChannelMessage *>(update.get());
|
||||
auto message_id = get_message_id(update_new_channel_message->message_, false);
|
||||
FullMessageId full_message_id(dialog_id, message_id);
|
||||
if (update_message_ids_.find(full_message_id) != update_message_ids_.end() &&
|
||||
changed_message_ids.find(message_id) != changed_message_ids.end()) {
|
||||
changed_message_ids.erase(message_id);
|
||||
awaited_messages.emplace(message_id, std::move(update_new_channel_message->message_));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << "Skip to be applied from getChannelDifference " << to_string(update);
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
if (updates.empty()) {
|
||||
postponed_channel_updates_.erase(postponed_updates_it);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35937,22 +36028,31 @@ void MessagesManager::process_get_channel_difference_updates(
|
||||
bool need_repair_unread_count =
|
||||
!new_messages.empty() && get_message_date(new_messages[0]) < G()->unix_time() - 2 * 86400;
|
||||
|
||||
auto it = awaited_messages.begin();
|
||||
for (auto &message : new_messages) {
|
||||
auto message_id = get_message_id(message, false);
|
||||
while (it != awaited_messages.end() && it->first < message_id) {
|
||||
on_get_message(std::move(it->second), true, true, false, true, true, "postponed channel update");
|
||||
++it;
|
||||
}
|
||||
if (it != awaited_messages.end() && it->first == message_id) {
|
||||
if (is_edited_message(message)) {
|
||||
// the new message is edited, apply postponed one and move this to updateEditChannelMessage
|
||||
other_updates.push_back(make_tl_object<telegram_api::updateEditChannelMessage>(std::move(message), new_pts, 0));
|
||||
message = std::move(it->second);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
on_get_message(std::move(message), true, true, false, true, true, "get channel difference");
|
||||
}
|
||||
while (it != awaited_messages.end()) {
|
||||
on_get_message(std::move(it->second), true, true, false, true, true, "postponed channel update 2");
|
||||
++it;
|
||||
}
|
||||
|
||||
for (auto &update : other_updates) {
|
||||
if (update != nullptr) {
|
||||
switch (update->get_id()) {
|
||||
case telegram_api::updateDeleteChannelMessages::ID:
|
||||
case telegram_api::updateEditChannelMessage::ID:
|
||||
case telegram_api::updatePinnedChannelMessages::ID:
|
||||
process_channel_update(std::move(update));
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unsupported update received in getChannelDifference: " << oneline(to_string(update));
|
||||
break;
|
||||
}
|
||||
process_channel_update(std::move(update));
|
||||
}
|
||||
}
|
||||
LOG_CHECK(!running_get_channel_difference(dialog_id)) << '"' << active_get_channel_differencies_[dialog_id] << '"';
|
||||
@ -36184,7 +36284,24 @@ void MessagesManager::on_get_channel_difference(
|
||||
new_pts = request_pts + 1;
|
||||
}
|
||||
|
||||
process_get_channel_difference_updates(dialog_id, std::move(difference->new_messages_),
|
||||
if (difference->new_messages_.size() > 1) {
|
||||
// check that new messages are received in increasing message_id order
|
||||
MessageId cur_message_id;
|
||||
for (const auto &message : difference->new_messages_) {
|
||||
auto message_id = get_message_id(message, false);
|
||||
if (message_id <= cur_message_id) {
|
||||
// TODO move to ERROR
|
||||
LOG(FATAL) << "Receive " << cur_message_id << " after " << message_id << " in channelDifference of "
|
||||
<< dialog_id << " with pts " << request_pts << " and limit " << request_limit << ": "
|
||||
<< to_string(difference);
|
||||
after_get_channel_difference(dialog_id, false);
|
||||
return;
|
||||
}
|
||||
cur_message_id = message_id;
|
||||
}
|
||||
}
|
||||
|
||||
process_get_channel_difference_updates(dialog_id, new_pts, std::move(difference->new_messages_),
|
||||
std::move(difference->other_updates_));
|
||||
|
||||
set_channel_pts(d, new_pts, "channel difference");
|
||||
@ -36296,9 +36413,9 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ
|
||||
auto d = get_dialog(dialog_id);
|
||||
bool have_access = have_input_peer(dialog_id, AccessRights::Read);
|
||||
auto pts = d != nullptr ? d->pts : load_channel_pts(dialog_id);
|
||||
auto updates_it = postponed_channel_updates_.find(dialog_id);
|
||||
if (updates_it != postponed_channel_updates_.end()) {
|
||||
auto &updates = updates_it->second;
|
||||
auto postponed_updates_it = postponed_channel_updates_.find(dialog_id);
|
||||
if (postponed_updates_it != postponed_channel_updates_.end()) {
|
||||
auto &updates = postponed_updates_it->second;
|
||||
LOG(INFO) << "Begin to apply " << updates.size() << " postponed channel updates";
|
||||
while (!updates.empty()) {
|
||||
auto it = updates.begin();
|
||||
@ -36339,7 +36456,7 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ
|
||||
}
|
||||
}
|
||||
if (updates.empty()) {
|
||||
postponed_channel_updates_.erase(updates_it);
|
||||
postponed_channel_updates_.erase(postponed_updates_it);
|
||||
}
|
||||
LOG(INFO) << "Finish to apply postponed channel updates";
|
||||
}
|
||||
|
@ -2793,7 +2793,7 @@ class MessagesManager final : public Actor {
|
||||
void do_get_channel_difference(DialogId dialog_id, int32 pts, bool force,
|
||||
tl_object_ptr<telegram_api::InputChannel> &&input_channel, const char *source);
|
||||
|
||||
void process_get_channel_difference_updates(DialogId dialog_id,
|
||||
void process_get_channel_difference_updates(DialogId dialog_id, int32 new_pts,
|
||||
vector<tl_object_ptr<telegram_api::Message>> &&new_messages,
|
||||
vector<tl_object_ptr<telegram_api::Update>> &&other_updates);
|
||||
|
||||
|
@ -635,13 +635,16 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
||||
Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_input_settings(
|
||||
const UpdateSettings &update_settings, bool has_password, const NewPasswordState &state,
|
||||
const PasswordPrivateState *private_state) {
|
||||
auto settings = make_tl_object<telegram_api::account_passwordInputSettings>();
|
||||
bool have_secret = private_state != nullptr && private_state->secret;
|
||||
auto update_secure_secret = update_settings.update_secure_secret;
|
||||
int32 flags = 0;
|
||||
BufferSlice new_password_hash;
|
||||
tl_object_ptr<telegram_api::PasswordKdfAlgo> new_algo;
|
||||
string new_hint;
|
||||
if (update_settings.update_password) {
|
||||
settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_PASSWORD_HASH_MASK;
|
||||
settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_ALGO_MASK;
|
||||
settings->flags_ |= telegram_api::account_passwordInputSettings::HINT_MASK;
|
||||
flags |= telegram_api::account_passwordInputSettings::NEW_PASSWORD_HASH_MASK;
|
||||
flags |= telegram_api::account_passwordInputSettings::NEW_ALGO_MASK;
|
||||
flags |= telegram_api::account_passwordInputSettings::HINT_MASK;
|
||||
if (!update_settings.new_password.empty()) {
|
||||
auto new_client_salt = create_salt(state.client_salt);
|
||||
|
||||
@ -650,16 +653,15 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
||||
if (new_hash.is_error()) {
|
||||
return Status::Error(400, "Unable to change password, because it may be unsafe");
|
||||
}
|
||||
settings->new_password_hash_ = new_hash.move_as_ok();
|
||||
settings->new_algo_ =
|
||||
make_tl_object<telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow>(
|
||||
std::move(new_client_salt), BufferSlice(state.server_salt), state.srp_g, BufferSlice(state.srp_p));
|
||||
settings->hint_ = std::move(update_settings.new_hint);
|
||||
new_password_hash = new_hash.move_as_ok();
|
||||
new_algo = make_tl_object<telegram_api::passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow>(
|
||||
std::move(new_client_salt), BufferSlice(state.server_salt), state.srp_g, BufferSlice(state.srp_p));
|
||||
new_hint = std::move(update_settings.new_hint);
|
||||
if (have_secret) {
|
||||
update_secure_secret = true;
|
||||
}
|
||||
} else {
|
||||
settings->new_algo_ = make_tl_object<telegram_api::passwordKdfAlgoUnknown>();
|
||||
new_algo = make_tl_object<telegram_api::passwordKdfAlgoUnknown>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -673,6 +675,7 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
||||
update_secure_secret = false;
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::secureSecretSettings> new_secure_settings;
|
||||
if (update_secure_secret) {
|
||||
auto secret = have_secret ? std::move(private_state->secret.value()) : secure_storage::Secret::create_new();
|
||||
auto algorithm =
|
||||
@ -681,15 +684,16 @@ Result<PasswordManager::PasswordInputSettings> PasswordManager::get_password_inp
|
||||
update_settings.update_password ? update_settings.new_password : update_settings.current_password,
|
||||
algorithm->salt_.as_slice(), secure_storage::EnryptionAlgorithm::Pbkdf2);
|
||||
|
||||
settings->flags_ |= telegram_api::account_passwordInputSettings::NEW_SECURE_SETTINGS_MASK;
|
||||
settings->new_secure_settings_ = make_tl_object<telegram_api::secureSecretSettings>(
|
||||
flags |= telegram_api::account_passwordInputSettings::NEW_SECURE_SETTINGS_MASK;
|
||||
new_secure_settings = make_tl_object<telegram_api::secureSecretSettings>(
|
||||
std::move(algorithm), BufferSlice(encrypted_secret.as_slice()), secret.get_hash());
|
||||
}
|
||||
if (update_settings.update_recovery_email_address) {
|
||||
settings->flags_ |= telegram_api::account_passwordInputSettings::EMAIL_MASK;
|
||||
settings->email_ = std::move(update_settings.recovery_email_address);
|
||||
flags |= telegram_api::account_passwordInputSettings::EMAIL_MASK;
|
||||
}
|
||||
return std::move(settings);
|
||||
return make_tl_object<telegram_api::account_passwordInputSettings>(
|
||||
flags, std::move(new_algo), std::move(new_password_hash), new_hint, update_settings.recovery_email_address,
|
||||
std::move(new_secure_settings));
|
||||
}
|
||||
|
||||
void PasswordManager::do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state,
|
||||
|
@ -253,7 +253,7 @@ static void write_function(tl_outputer &out, const tl_combinator *t, const std::
|
||||
std::vector<var_description> vars(t->var_count);
|
||||
out.append(w.gen_function_vars(t, vars));
|
||||
|
||||
if (w.is_default_constructor_generated(t, true)) {
|
||||
if (w.is_default_constructor_generated(t, false, true)) {
|
||||
write_class_constructor(out, t, class_name, true, w);
|
||||
}
|
||||
if (required_args) {
|
||||
@ -306,7 +306,35 @@ static void write_constructor(tl_outputer &out, const tl_combinator *t, const st
|
||||
int required_args = gen_field_definitions(out, t, class_name, w);
|
||||
out.append(w.gen_flags_definitions(t));
|
||||
|
||||
if (w.is_default_constructor_generated(t, false)) {
|
||||
bool can_be_parsed = false;
|
||||
bool is_can_be_parsed_inited = false;
|
||||
std::vector<std::string> parsers = w.get_parsers();
|
||||
for (std::size_t i = 0; i < parsers.size(); i++) {
|
||||
int parser_type = w.get_parser_type(t, parsers[i]);
|
||||
if (w.get_parser_mode(parser_type) != TL_writer::All) {
|
||||
can_be_parsed |= is_reachable_for_parser(parser_type, t->name, request_types, result_types, w);
|
||||
is_can_be_parsed_inited = true;
|
||||
}
|
||||
}
|
||||
if (!is_can_be_parsed_inited) {
|
||||
can_be_parsed = true;
|
||||
}
|
||||
|
||||
bool can_be_stored = false;
|
||||
bool is_can_be_stored_inited = false;
|
||||
std::vector<std::string> storers = w.get_storers();
|
||||
for (std::size_t i = 0; i < storers.size(); i++) {
|
||||
int storer_type = w.get_storer_type(t, storers[i]);
|
||||
if (w.get_storer_mode(storer_type) != TL_writer::All) {
|
||||
can_be_stored |= is_reachable_for_storer(storer_type, t->name, request_types, result_types, w);
|
||||
is_can_be_stored_inited = true;
|
||||
}
|
||||
}
|
||||
if (!is_can_be_stored_inited) {
|
||||
can_be_stored = true;
|
||||
}
|
||||
|
||||
if (w.is_default_constructor_generated(t, can_be_parsed, can_be_stored)) {
|
||||
write_class_constructor(out, t, class_name, true, w);
|
||||
}
|
||||
if (required_args) {
|
||||
@ -319,7 +347,6 @@ static void write_constructor(tl_outputer &out, const tl_combinator *t, const st
|
||||
assert(t->result->get_type() == NODE_TYPE_TYPE);
|
||||
const tl_tree_type *result_type = static_cast<const tl_tree_type *>(t->result);
|
||||
|
||||
std::vector<std::string> parsers = w.get_parsers();
|
||||
for (std::size_t i = 0; i < parsers.size(); i++) {
|
||||
write_constructor_fetch(out, parsers[i], t, class_name, parent_class, result_type,
|
||||
required_args == 1 && result_type->type->simple_constructors == 1, request_types,
|
||||
@ -327,7 +354,6 @@ static void write_constructor(tl_outputer &out, const tl_combinator *t, const st
|
||||
}
|
||||
|
||||
// STORER
|
||||
std::vector<std::string> storers = w.get_storers();
|
||||
for (std::size_t i = 0; i < storers.size(); i++) {
|
||||
write_constructor_store(out, storers[i], t, class_name, result_type,
|
||||
required_args == 1 && result_type->type->simple_constructors == 1, request_types,
|
||||
|
@ -135,7 +135,7 @@ bool TL_writer::is_documentation_generated() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TL_writer::is_default_constructor_generated(const tl_combinator *t, bool is_function) const {
|
||||
bool TL_writer::is_default_constructor_generated(const tl_combinator *t, bool can_be_parsed, bool can_be_stored) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ class TL_writer {
|
||||
virtual bool is_type_bare(const tl_type *t) const = 0;
|
||||
virtual bool is_combinator_supported(const tl_combinator *constructor) const;
|
||||
virtual bool is_documentation_generated() const;
|
||||
virtual bool is_default_constructor_generated(const tl_combinator *t, bool is_function) const;
|
||||
virtual bool is_default_constructor_generated(const tl_combinator *t, bool can_be_parsed, bool can_be_stored) const;
|
||||
|
||||
virtual int get_parser_type(const tl_combinator *t, const std::string &parser_name) const;
|
||||
virtual int get_storer_type(const tl_combinator *t, const std::string &storer_name) const;
|
||||
|
Loading…
Reference in New Issue
Block a user