Merge remote-tracking branch 'td/master'
This commit is contained in:
commit
f73adb408a
@ -143,8 +143,7 @@ void set_menu_button(Td *td, UserId user_id, td_api::object_ptr<td_api::botMenuB
|
|||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(menu_button->url_, true, !G()->is_test_dc());
|
auto r_url = LinkManager::check_link(menu_button->url_, true, !G()->is_test_dc());
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
return promise.set_error(Status::Error(400, PSLICE() << "Menu button web app URL '" << menu_button->url_
|
return promise.set_error(Status::Error(400, PSLICE() << "Menu button Web App " << r_url.error().message()));
|
||||||
<< "' is invalid: " << r_url.error().message()));
|
|
||||||
}
|
}
|
||||||
input_bot_menu_button = telegram_api::make_object<telegram_api::botMenuButton>(menu_button->text_, r_url.ok());
|
input_bot_menu_button = telegram_api::make_object<telegram_api::botMenuButton>(menu_button->text_, r_url.ok());
|
||||||
}
|
}
|
||||||
|
@ -15808,6 +15808,10 @@ void ContactsManager::on_update_dialog_administrators(DialogId dialog_id, vector
|
|||||||
void ContactsManager::reload_dialog_administrators(DialogId dialog_id,
|
void ContactsManager::reload_dialog_administrators(DialogId dialog_id,
|
||||||
const vector<DialogAdministrator> &dialog_administrators,
|
const vector<DialogAdministrator> &dialog_administrators,
|
||||||
Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise) {
|
Promise<td_api::object_ptr<td_api::chatAdministrators>> &&promise) {
|
||||||
|
auto dialog_type = dialog_id.get_type();
|
||||||
|
if (dialog_type == DialogType::Chat && !get_chat_permissions(dialog_id.get_chat_id()).is_member()) {
|
||||||
|
return promise.set_value(td_api::object_ptr<td_api::chatAdministrators>());
|
||||||
|
}
|
||||||
auto query_promise = PromiseCreator::lambda(
|
auto query_promise = PromiseCreator::lambda(
|
||||||
[actor_id = actor_id(this), dialog_id, promise = std::move(promise)](Result<Unit> &&result) mutable {
|
[actor_id = actor_id(this), dialog_id, promise = std::move(promise)](Result<Unit> &&result) mutable {
|
||||||
if (promise) {
|
if (promise) {
|
||||||
@ -15818,7 +15822,7 @@ void ContactsManager::reload_dialog_administrators(DialogId dialog_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
switch (dialog_id.get_type()) {
|
switch (dialog_type) {
|
||||||
case DialogType::Chat:
|
case DialogType::Chat:
|
||||||
load_chat_full(dialog_id.get_chat_id(), false, std::move(query_promise), "reload_dialog_administrators");
|
load_chat_full(dialog_id.get_chat_id(), false, std::move(query_promise), "reload_dialog_administrators");
|
||||||
break;
|
break;
|
||||||
|
@ -4675,14 +4675,15 @@ bool GroupCallManager::set_group_call_participant_count(GroupCall *group_call, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG(DEBUG) << "Set " << group_call->group_call_id << " participant count to " << count << " from " << source;
|
LOG(DEBUG) << "Set " << group_call->group_call_id << " participant count to " << count << " from " << source;
|
||||||
|
auto input_group_call_id = get_input_group_call_id(group_call->group_call_id).ok();
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
LOG(ERROR) << "Participant count became negative in " << group_call->group_call_id << " in "
|
LOG(ERROR) << "Participant count became negative in " << group_call->group_call_id << " in "
|
||||||
<< group_call->dialog_id << " from " << source;
|
<< group_call->dialog_id << " from " << source;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
reload_group_call(input_group_call_id, Auto());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
auto input_group_call_id = get_input_group_call_id(group_call->group_call_id).ok();
|
|
||||||
if (need_group_call_participants(input_group_call_id, group_call)) {
|
if (need_group_call_participants(input_group_call_id, group_call)) {
|
||||||
auto known_participant_count =
|
auto known_participant_count =
|
||||||
static_cast<int32>(add_group_call_participants(input_group_call_id)->participants.size());
|
static_cast<int32>(add_group_call_participants(input_group_call_id)->participants.size());
|
||||||
@ -4738,6 +4739,8 @@ bool GroupCallManager::set_group_call_unmuted_video_count(GroupCall *group_call,
|
|||||||
LOG(ERROR) << "Video participant count became negative in " << group_call->group_call_id << " in "
|
LOG(ERROR) << "Video participant count became negative in " << group_call->group_call_id << " in "
|
||||||
<< group_call->dialog_id << " from " << source;
|
<< group_call->dialog_id << " from " << source;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
auto input_group_call_id = get_input_group_call_id(group_call->group_call_id).ok();
|
||||||
|
reload_group_call(input_group_call_id, Auto());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group_call->unmuted_video_count == count) {
|
if (group_call->unmuted_video_count == count) {
|
||||||
|
@ -708,7 +708,28 @@ static bool tolower_begins_with(Slice str, Slice prefix) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<string> LinkManager::check_link(Slice link, bool http_only, bool https_only) {
|
Result<string> LinkManager::check_link(CSlice link, bool http_only, bool https_only) {
|
||||||
|
auto result = check_link_impl(link, http_only, https_only);
|
||||||
|
if (result.is_ok()) {
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
auto error = result.move_as_error();
|
||||||
|
if (check_utf8(link)) {
|
||||||
|
return Status::Error(400, PSLICE() << "URL '" << link << "' is invalid: " << error.message());
|
||||||
|
} else {
|
||||||
|
return Status::Error(400, PSLICE() << "URL is invalid: " << error.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string LinkManager::get_checked_link(Slice link, bool http_only, bool https_only) {
|
||||||
|
auto result = check_link_impl(link, http_only, https_only);
|
||||||
|
if (result.is_ok()) {
|
||||||
|
return result.move_as_ok();
|
||||||
|
}
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<string> LinkManager::check_link_impl(Slice link, bool http_only, bool https_only) {
|
||||||
bool is_tg = false;
|
bool is_tg = false;
|
||||||
bool is_ton = false;
|
bool is_ton = false;
|
||||||
if (tolower_begins_with(link, "tg:")) {
|
if (tolower_begins_with(link, "tg:")) {
|
||||||
|
@ -47,7 +47,10 @@ class LinkManager final : public Actor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// checks whether the link is a valid tg, ton or HTTP(S) URL and returns it in a canonical form
|
// checks whether the link is a valid tg, ton or HTTP(S) URL and returns it in a canonical form
|
||||||
static Result<string> check_link(Slice link, bool http_only = false, bool https_only = false);
|
static Result<string> check_link(CSlice link, bool http_only = false, bool https_only = false);
|
||||||
|
|
||||||
|
// same as check_link, but returns an empty string instead of an error
|
||||||
|
static string get_checked_link(Slice link, bool http_only = false, bool https_only = false);
|
||||||
|
|
||||||
// checks whether the link is a supported tg or t.me link and parses it
|
// checks whether the link is a supported tg or t.me link and parses it
|
||||||
static unique_ptr<InternalLink> parse_internal_link(Slice link);
|
static unique_ptr<InternalLink> parse_internal_link(Slice link);
|
||||||
@ -128,6 +131,8 @@ class LinkManager final : public Actor {
|
|||||||
|
|
||||||
static unique_ptr<InternalLink> get_internal_link_message_draft(Slice url, Slice text);
|
static unique_ptr<InternalLink> get_internal_link_message_draft(Slice url, Slice text);
|
||||||
|
|
||||||
|
static Result<string> check_link_impl(Slice link, bool http_only, bool https_only);
|
||||||
|
|
||||||
Td *td_;
|
Td *td_;
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
|
|
||||||
|
@ -1723,7 +1723,7 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
td->animations_manager_->create_animation(
|
td->animations_manager_->create_animation(
|
||||||
file_id, string(), thumbnail, AnimationSize(), has_stickers, std::move(sticker_file_ids),
|
file_id, string(), thumbnail, AnimationSize(), has_stickers, std::move(sticker_file_ids),
|
||||||
std::move(file_name), std::move(mime_type), input_animation->duration_,
|
std::move(file_name), std::move(mime_type), input_animation->duration_,
|
||||||
get_dimensions(input_animation->width_, input_animation->height_, "inputMessageAnimation"), false);
|
get_dimensions(input_animation->width_, input_animation->height_, nullptr), false);
|
||||||
|
|
||||||
content = make_unique<MessageAnimation>(file_id, std::move(caption));
|
content = make_unique<MessageAnimation>(file_id, std::move(caption));
|
||||||
break;
|
break;
|
||||||
@ -1792,7 +1792,7 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
|
|
||||||
PhotoSize s;
|
PhotoSize s;
|
||||||
s.type = type;
|
s.type = type;
|
||||||
s.dimensions = get_dimensions(input_photo->width_, input_photo->height_, "inputMessagePhoto");
|
s.dimensions = get_dimensions(input_photo->width_, input_photo->height_, nullptr);
|
||||||
s.size = static_cast<int32>(file_view.size());
|
s.size = static_cast<int32>(file_view.size());
|
||||||
s.file_id = file_id;
|
s.file_id = file_id;
|
||||||
|
|
||||||
@ -1815,10 +1815,9 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
|
|
||||||
emoji = std::move(input_sticker->emoji_);
|
emoji = std::move(input_sticker->emoji_);
|
||||||
|
|
||||||
td->stickers_manager_->create_sticker(
|
td->stickers_manager_->create_sticker(file_id, string(), thumbnail,
|
||||||
file_id, string(), thumbnail,
|
get_dimensions(input_sticker->width_, input_sticker->height_, nullptr),
|
||||||
get_dimensions(input_sticker->width_, input_sticker->height_, "inputMessageSticker"), nullptr,
|
nullptr, StickerFormat::Unknown, nullptr);
|
||||||
StickerFormat::Unknown, nullptr);
|
|
||||||
|
|
||||||
content = make_unique<MessageSticker>(file_id);
|
content = make_unique<MessageSticker>(file_id);
|
||||||
break;
|
break;
|
||||||
@ -1829,11 +1828,10 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
ttl = input_video->ttl_;
|
ttl = input_video->ttl_;
|
||||||
|
|
||||||
bool has_stickers = !sticker_file_ids.empty();
|
bool has_stickers = !sticker_file_ids.empty();
|
||||||
td->videos_manager_->create_video(file_id, string(), thumbnail, AnimationSize(), has_stickers,
|
td->videos_manager_->create_video(
|
||||||
std::move(sticker_file_ids), std::move(file_name), std::move(mime_type),
|
file_id, string(), thumbnail, AnimationSize(), has_stickers, std::move(sticker_file_ids),
|
||||||
input_video->duration_,
|
std::move(file_name), std::move(mime_type), input_video->duration_,
|
||||||
get_dimensions(input_video->width_, input_video->height_, "inputMessageVideo"),
|
get_dimensions(input_video->width_, input_video->height_, nullptr), input_video->supports_streaming_, false);
|
||||||
input_video->supports_streaming_, false);
|
|
||||||
|
|
||||||
content = make_unique<MessageVideo>(file_id, std::move(caption));
|
content = make_unique<MessageVideo>(file_id, std::move(caption));
|
||||||
break;
|
break;
|
||||||
@ -1847,7 +1845,7 @@ static Result<InputMessageContent> create_input_message_content(
|
|||||||
}
|
}
|
||||||
|
|
||||||
td->video_notes_manager_->create_video_note(file_id, string(), thumbnail, input_video_note->duration_,
|
td->video_notes_manager_->create_video_note(file_id, string(), thumbnail, input_video_note->duration_,
|
||||||
get_dimensions(length, length, "inputMessageVideoNote"), false);
|
get_dimensions(length, length, nullptr), false);
|
||||||
|
|
||||||
content = make_unique<MessageVideoNote>(file_id, false);
|
content = make_unique<MessageVideoNote>(file_id, false);
|
||||||
break;
|
break;
|
||||||
@ -2083,7 +2081,7 @@ Result<InputMessageContent> get_input_message_content(
|
|||||||
LOG(WARNING) << "Ignore thumbnail file: " << r_thumbnail_file_id.error().message();
|
LOG(WARNING) << "Ignore thumbnail file: " << r_thumbnail_file_id.error().message();
|
||||||
} else {
|
} else {
|
||||||
thumbnail.type = 't';
|
thumbnail.type = 't';
|
||||||
thumbnail.dimensions = get_dimensions(input_thumbnail->width_, input_thumbnail->height_, "inputThumbnail");
|
thumbnail.dimensions = get_dimensions(input_thumbnail->width_, input_thumbnail->height_, nullptr);
|
||||||
thumbnail.file_id = r_thumbnail_file_id.ok();
|
thumbnail.file_id = r_thumbnail_file_id.ok();
|
||||||
CHECK(thumbnail.file_id.is_valid());
|
CHECK(thumbnail.file_id.is_valid());
|
||||||
|
|
||||||
@ -4334,8 +4332,8 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
|
|||||||
}
|
}
|
||||||
case telegram_api::messageMediaPoll::ID: {
|
case telegram_api::messageMediaPoll::ID: {
|
||||||
auto media_poll = move_tl_object_as<telegram_api::messageMediaPoll>(media);
|
auto media_poll = move_tl_object_as<telegram_api::messageMediaPoll>(media);
|
||||||
auto poll_id =
|
auto poll_id = td->poll_manager_->on_get_poll(PollId(), std::move(media_poll->poll_),
|
||||||
td->poll_manager_->on_get_poll(PollId(), std::move(media_poll->poll_), std::move(media_poll->results_));
|
std::move(media_poll->results_), "messageMediaPoll");
|
||||||
if (!poll_id.is_valid()) {
|
if (!poll_id.is_valid()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1876,9 +1876,9 @@ Result<vector<MessageEntity>> parse_markdown(string &text) {
|
|||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
entities.emplace_back(entity_offset, entity_length, user_id);
|
entities.emplace_back(entity_offset, entity_length, user_id);
|
||||||
} else {
|
} else {
|
||||||
auto r_url = LinkManager::check_link(url);
|
url = LinkManager::get_checked_link(url);
|
||||||
if (r_url.is_ok()) {
|
if (!url.empty()) {
|
||||||
entities.emplace_back(MessageEntity::Type::TextUrl, entity_offset, entity_length, r_url.move_as_ok());
|
entities.emplace_back(MessageEntity::Type::TextUrl, entity_offset, entity_length, std::move(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2092,11 +2092,11 @@ static Result<vector<MessageEntity>> do_parse_markdown_v2(CSlice text, string &r
|
|||||||
}
|
}
|
||||||
user_id = LinkManager::get_link_user_id(url);
|
user_id = LinkManager::get_link_user_id(url);
|
||||||
if (!user_id.is_valid()) {
|
if (!user_id.is_valid()) {
|
||||||
auto r_url = LinkManager::check_link(url);
|
url = LinkManager::get_checked_link(url);
|
||||||
if (r_url.is_error()) {
|
if (url.empty()) {
|
||||||
skip_entity = true;
|
skip_entity = true;
|
||||||
} else {
|
} else {
|
||||||
argument = r_url.move_as_ok();
|
argument = std::move(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2169,7 +2169,7 @@ static vector<Slice> find_text_url_entities_v3(Slice text) {
|
|||||||
|
|
||||||
if (url_end < size) {
|
if (url_end < size) {
|
||||||
Slice url = text.substr(url_begin + 1, url_end - url_begin - 1);
|
Slice url = text.substr(url_begin + 1, url_end - url_begin - 1);
|
||||||
if (LinkManager::check_link(url).is_ok()) {
|
if (!LinkManager::get_checked_link(url).empty()) {
|
||||||
result.push_back(text.substr(text_begin, text_end - text_begin + 1));
|
result.push_back(text.substr(text_begin, text_end - text_begin + 1));
|
||||||
result.push_back(text.substr(url_begin, url_end - url_begin + 1));
|
result.push_back(text.substr(url_begin, url_end - url_begin + 1));
|
||||||
}
|
}
|
||||||
@ -2241,7 +2241,7 @@ static FormattedText parse_text_url_entities_v3(Slice text, const vector<Message
|
|||||||
Slice url = parsed_part_text.substr(url_begin_pos + 1, url_end_pos - url_begin_pos - 1);
|
Slice url = parsed_part_text.substr(url_begin_pos + 1, url_end_pos - url_begin_pos - 1);
|
||||||
auto url_utf16_length = text_length(url);
|
auto url_utf16_length = text_length(url);
|
||||||
result.entities.emplace_back(MessageEntity::Type::TextUrl, result_text_utf16_length, text_url_utf16_length,
|
result.entities.emplace_back(MessageEntity::Type::TextUrl, result_text_utf16_length, text_url_utf16_length,
|
||||||
LinkManager::check_link(url).move_as_ok());
|
LinkManager::get_checked_link(url));
|
||||||
result.text.append(text_url.begin(), text_url.size());
|
result.text.append(text_url.begin(), text_url.size());
|
||||||
result_text_utf16_length += text_url_utf16_length;
|
result_text_utf16_length += text_url_utf16_length;
|
||||||
|
|
||||||
@ -3075,9 +3075,9 @@ static Result<vector<MessageEntity>> do_parse_html(CSlice text, string &result)
|
|||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
entities.emplace_back(entity_offset, entity_length, user_id);
|
entities.emplace_back(entity_offset, entity_length, user_id);
|
||||||
} else {
|
} else {
|
||||||
auto r_url = LinkManager::check_link(url);
|
url = LinkManager::get_checked_link(url);
|
||||||
if (r_url.is_ok()) {
|
if (!url.empty()) {
|
||||||
entities.emplace_back(MessageEntity::Type::TextUrl, entity_offset, entity_length, r_url.move_as_ok());
|
entities.emplace_back(MessageEntity::Type::TextUrl, entity_offset, entity_length, std::move(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tag_name == "pre") {
|
} else if (tag_name == "pre") {
|
||||||
@ -3284,7 +3284,7 @@ Result<vector<MessageEntity>> get_message_entities(const ContactsManager *contac
|
|||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(entity->url_);
|
auto r_url = LinkManager::check_link(entity->url_);
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
return Status::Error(400, PSTRING() << "Wrong URL entity specified: " << r_url.error().message());
|
return Status::Error(400, PSTRING() << "Entity " << r_url.error().message());
|
||||||
}
|
}
|
||||||
entities.emplace_back(MessageEntity::Type::TextUrl, offset, length, r_url.move_as_ok());
|
entities.emplace_back(MessageEntity::Type::TextUrl, offset, length, r_url.move_as_ok());
|
||||||
break;
|
break;
|
||||||
@ -3418,8 +3418,7 @@ vector<MessageEntity> get_message_entities(const ContactsManager *contacts_manag
|
|||||||
auto entity = static_cast<const telegram_api::messageEntityTextUrl *>(server_entity.get());
|
auto entity = static_cast<const telegram_api::messageEntityTextUrl *>(server_entity.get());
|
||||||
auto r_url = LinkManager::check_link(entity->url_);
|
auto r_url = LinkManager::check_link(entity->url_);
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
LOG(ERROR) << "Wrong URL entity: \"" << entity->url_ << "\": " << r_url.error().message() << " from "
|
LOG(ERROR) << "Entity " << r_url.error().message() << " from " << source;
|
||||||
<< source;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
|
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
|
||||||
@ -3540,7 +3539,7 @@ vector<MessageEntity> get_message_entities(vector<tl_object_ptr<secret_api::Mess
|
|||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(entity->url_);
|
auto r_url = LinkManager::check_link(entity->url_);
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
LOG(WARNING) << "Wrong URL entity: \"" << entity->url_ << "\": " << r_url.error().message();
|
LOG(WARNING) << "Entity " << r_url.error().message();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
|
entities.emplace_back(MessageEntity::Type::TextUrl, entity->offset_, entity->length_, r_url.move_as_ok());
|
||||||
|
@ -871,6 +871,9 @@ class SearchPublicDialogsQuery final : public Td::ResultHandler {
|
|||||||
|
|
||||||
void on_error(Status status) final {
|
void on_error(Status status) final {
|
||||||
if (!G()->is_expected_error(status)) {
|
if (!G()->is_expected_error(status)) {
|
||||||
|
if (status.message() == "QUERY_TOO_SHORT") {
|
||||||
|
return td_->messages_manager_->on_get_public_dialogs_search_result(query_, {}, {});
|
||||||
|
}
|
||||||
LOG(ERROR) << "Receive error for SearchPublicDialogsQuery: " << status;
|
LOG(ERROR) << "Receive error for SearchPublicDialogsQuery: " << status;
|
||||||
}
|
}
|
||||||
td_->messages_manager_->on_failed_public_dialogs_search(query_, std::move(status));
|
td_->messages_manager_->on_failed_public_dialogs_search(query_, std::move(status));
|
||||||
@ -9683,7 +9686,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
|
|||||||
// new server messages were added to the dialog since the request was sent, but weren't received
|
// new server messages were added to the dialog since the request was sent, but weren't received
|
||||||
// they should have been received, so we must repeat the request to get them
|
// they should have been received, so we must repeat the request to get them
|
||||||
if (from_the_end) {
|
if (from_the_end) {
|
||||||
get_history_from_the_end_impl(d, false, false, std::move(promise));
|
get_history_from_the_end_impl(d, false, false, std::move(promise), "on_get_history");
|
||||||
} else {
|
} else {
|
||||||
get_history_impl(d, from_message_id, offset, limit, false, false, std::move(promise));
|
get_history_impl(d, from_message_id, offset, limit, false, false, std::move(promise));
|
||||||
}
|
}
|
||||||
@ -9786,14 +9789,15 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto &message : messages) {
|
for (auto &message : messages) {
|
||||||
if (!have_next && from_the_end && get_message_id(message, false) < d->last_message_id) {
|
auto expected_message_id = get_message_id(message, false);
|
||||||
|
if (!have_next && from_the_end && expected_message_id < d->last_message_id) {
|
||||||
// last message in the dialog should be attached to the next message if there is some
|
// last message in the dialog should be attached to the next message if there is some
|
||||||
have_next = true;
|
have_next = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto message_dialog_id = get_message_dialog_id(message);
|
auto message_dialog_id = get_message_dialog_id(message);
|
||||||
if (message_dialog_id != dialog_id) {
|
if (message_dialog_id != dialog_id) {
|
||||||
LOG(ERROR) << "Receive " << get_message_id(message, false) << " in wrong " << message_dialog_id << " instead of "
|
LOG(ERROR) << "Receive " << expected_message_id << " in wrong " << message_dialog_id << " instead of "
|
||||||
<< dialog_id << ": " << oneline(to_string(message));
|
<< dialog_id << ": " << oneline(to_string(message));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -9802,6 +9806,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_
|
|||||||
on_get_message(std::move(message), false, is_channel_message, false, false, have_next, "get history");
|
on_get_message(std::move(message), false, is_channel_message, false, false, have_next, "get history");
|
||||||
auto message_id = full_message_id.get_message_id();
|
auto message_id = full_message_id.get_message_id();
|
||||||
if (message_id.is_valid()) {
|
if (message_id.is_valid()) {
|
||||||
|
CHECK(message_id == expected_message_id);
|
||||||
if (!last_added_message_id.is_valid()) {
|
if (!last_added_message_id.is_valid()) {
|
||||||
last_added_message_id = message_id;
|
last_added_message_id = message_id;
|
||||||
}
|
}
|
||||||
@ -12666,7 +12671,7 @@ void MessagesManager::set_dialog_max_unavailable_message_id(DialogId dialog_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (max_unavailable_message_id.is_valid() && max_unavailable_message_id.is_yet_unsent()) {
|
if (max_unavailable_message_id.is_valid() && max_unavailable_message_id.is_yet_unsent()) {
|
||||||
LOG(ERROR) << "Tried to update " << dialog_id << " last read outbox message with " << max_unavailable_message_id
|
LOG(ERROR) << "Tried to update " << dialog_id << " max unavailable message with " << max_unavailable_message_id
|
||||||
<< " from " << source;
|
<< " from " << source;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -17373,7 +17378,9 @@ void MessagesManager::synchronize_dialog_filters() {
|
|||||||
vector<DialogId> MessagesManager::search_public_dialogs(const string &query, Promise<Unit> &&promise) {
|
vector<DialogId> MessagesManager::search_public_dialogs(const string &query, Promise<Unit> &&promise) {
|
||||||
LOG(INFO) << "Search public chats with query = \"" << query << '"';
|
LOG(INFO) << "Search public chats with query = \"" << query << '"';
|
||||||
|
|
||||||
if (utf8_length(query) < MIN_SEARCH_PUBLIC_DIALOG_PREFIX_LEN) {
|
auto query_length = utf8_length(query);
|
||||||
|
if (query_length < MIN_SEARCH_PUBLIC_DIALOG_PREFIX_LEN ||
|
||||||
|
(query_length == MIN_SEARCH_PUBLIC_DIALOG_PREFIX_LEN && query[0] == '@')) {
|
||||||
string username = clean_username(query);
|
string username = clean_username(query);
|
||||||
if (username[0] == '@') {
|
if (username[0] == '@') {
|
||||||
username = username.substr(1);
|
username = username.substr(1);
|
||||||
@ -23631,7 +23638,7 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
|||||||
// new messages where added to the database since the request was sent
|
// 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
|
// they should have been received from the database, so we must repeat the request to get them
|
||||||
if (from_the_end) {
|
if (from_the_end) {
|
||||||
get_history_from_the_end_impl(d, true, only_local, std::move(promise));
|
get_history_from_the_end_impl(d, true, only_local, std::move(promise), "on_get_history_from_database 20");
|
||||||
} else {
|
} else {
|
||||||
get_history_impl(d, from_message_id, offset, limit, true, only_local, std::move(promise));
|
get_history_impl(d, from_message_id, offset, limit, true, only_local, std::move(promise));
|
||||||
}
|
}
|
||||||
@ -23660,7 +23667,8 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
|||||||
auto debug_first_database_message_id = d->first_database_message_id;
|
auto debug_first_database_message_id = d->first_database_message_id;
|
||||||
auto debug_last_message_id = d->last_message_id;
|
auto debug_last_message_id = d->last_message_id;
|
||||||
auto debug_last_new_message_id = d->last_new_message_id;
|
auto debug_last_new_message_id = d->last_new_message_id;
|
||||||
auto last_received_message_id = MessageId::max();
|
auto first_received_message_id = MessageId::max();
|
||||||
|
MessageId last_received_message_id;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
for (auto &message_slice : messages) {
|
for (auto &message_slice : messages) {
|
||||||
if (!d->first_database_message_id.is_valid() && !d->have_full_history) {
|
if (!d->first_database_message_id.is_valid() && !d->have_full_history) {
|
||||||
@ -23675,13 +23683,16 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (message->message_id >= last_received_message_id) {
|
if (message->message_id >= first_received_message_id) {
|
||||||
LOG(ERROR) << "Receive " << message->message_id << " after " << last_received_message_id
|
LOG(ERROR) << "Receive " << message->message_id << " after " << first_received_message_id
|
||||||
<< " from database in the history of " << dialog_id << " from " << from_message_id << " with offset "
|
<< " from database in the history of " << dialog_id << " from " << from_message_id << " with offset "
|
||||||
<< offset << ", limit " << limit << ", from_the_end = " << from_the_end;
|
<< offset << ", limit " << limit << ", from_the_end = " << from_the_end;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
last_received_message_id = message->message_id;
|
first_received_message_id = message->message_id;
|
||||||
|
if (!last_received_message_id.is_valid()) {
|
||||||
|
last_received_message_id = message->message_id;
|
||||||
|
}
|
||||||
|
|
||||||
if (message->message_id < d->first_database_message_id) {
|
if (message->message_id < d->first_database_message_id) {
|
||||||
if (d->have_full_history) {
|
if (d->have_full_history) {
|
||||||
@ -23718,10 +23729,11 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
|||||||
}
|
}
|
||||||
if (next_message != nullptr && !next_message->have_previous) {
|
if (next_message != nullptr && !next_message->have_previous) {
|
||||||
LOG_CHECK(m->message_id < next_message->message_id)
|
LOG_CHECK(m->message_id < next_message->message_id)
|
||||||
<< m->message_id << ' ' << next_message->message_id << ' ' << last_received_message_id << ' ' << dialog_id
|
<< m->message_id << ' ' << next_message->message_id << ' ' << first_received_message_id << ' '
|
||||||
<< ' ' << from_message_id << ' ' << offset << ' ' << limit << ' ' << from_the_end << ' ' << only_local
|
<< last_received_message_id << ' ' << dialog_id << ' ' << from_message_id << ' ' << offset << ' ' << limit
|
||||||
<< ' ' << messages.size() << ' ' << debug_first_database_message_id << ' ' << last_added_message_id << ' '
|
<< ' ' << from_the_end << ' ' << only_local << ' ' << messages.size() << ' '
|
||||||
<< added_new_message << ' ' << pos << ' ' << m << ' ' << next_message << ' ' << old_message << ' '
|
<< debug_first_database_message_id << ' ' << last_added_message_id << ' ' << added_new_message << ' ' << pos
|
||||||
|
<< ' ' << m << ' ' << next_message << ' ' << old_message << ' '
|
||||||
<< to_string(get_message_object(dialog_id, m, "on_get_history_from_database"))
|
<< to_string(get_message_object(dialog_id, m, "on_get_history_from_database"))
|
||||||
<< to_string(get_message_object(dialog_id, next_message, "on_get_history_from_database"));
|
<< to_string(get_message_object(dialog_id, next_message, "on_get_history_from_database"));
|
||||||
LOG(INFO) << "Fix have_previous for " << next_message->message_id;
|
LOG(INFO) << "Fix have_previous for " << next_message->message_id;
|
||||||
@ -23744,35 +23756,39 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
|||||||
|
|
||||||
if (from_the_end && !last_added_message_id.is_valid() && d->first_database_message_id.is_valid() &&
|
if (from_the_end && !last_added_message_id.is_valid() && d->first_database_message_id.is_valid() &&
|
||||||
!d->have_full_history) {
|
!d->have_full_history) {
|
||||||
if (last_received_message_id <= d->first_database_message_id) {
|
if (first_received_message_id <= d->first_database_message_id) {
|
||||||
// database definitely has no messages from first_database_message_id to last_database_message_id; drop them
|
// database definitely has no messages from first_database_message_id to last_database_message_id; drop them
|
||||||
set_dialog_first_database_message_id(d, MessageId(), "on_get_history_from_database 8");
|
set_dialog_first_database_message_id(d, MessageId(), "on_get_history_from_database 8");
|
||||||
set_dialog_last_database_message_id(d, MessageId(), "on_get_history_from_database 9");
|
set_dialog_last_database_message_id(d, MessageId(), "on_get_history_from_database 9");
|
||||||
} else {
|
} else {
|
||||||
CHECK(last_received_message_id.is_valid());
|
CHECK(first_received_message_id.is_valid());
|
||||||
// if a message was received, but wasn't added, then it is likely to be already deleted
|
// if a message was received, but wasn't added, then it is likely to be already deleted
|
||||||
// if it is less than d->last_database_message_id, then we can adjust d->last_database_message_id and
|
// if it is less than d->last_database_message_id, then we can adjust d->last_database_message_id and
|
||||||
// try again database search without chance to loop
|
// try again database search without chance to loop
|
||||||
if (last_received_message_id < d->last_database_message_id) {
|
if (first_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, first_received_message_id, "on_get_history_from_database 12");
|
||||||
|
|
||||||
get_history_from_the_end_impl(d, true, only_local, std::move(promise));
|
get_history_from_the_end_impl(d, true, only_local, std::move(promise), "on_get_history_from_database 21");
|
||||||
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 no messages or newer messages [last_received_message_id, ...], none of which can be added
|
// received messages [first_received_message_id, 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
|
||||||
if (last_received_message_id == MessageId::max()) {
|
if (first_received_message_id == MessageId::max()) {
|
||||||
|
CHECK(last_received_message_id == MessageId());
|
||||||
LOG(ERROR) << "Receive no usable messages in " << dialog_id
|
LOG(ERROR) << "Receive no usable messages in " << dialog_id
|
||||||
<< " from database from the end, but expected messages from " << d->last_database_message_id
|
<< " from database from the end, but expected messages from " << d->first_database_message_id
|
||||||
<< " up to " << d->first_database_message_id;
|
<< " up to " << d->last_database_message_id
|
||||||
|
<< ". Have old last_database_message_id = " << old_last_database_message_id << " and "
|
||||||
|
<< messages.size() << " received messages";
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Receive " << messages.size() << " unusable messages up to " << last_received_message_id
|
LOG(ERROR) << "Receive " << messages.size() << " unusable messages [" << first_received_message_id << " ... "
|
||||||
<< " in " << dialog_id << " from database from the end, but expected messages from "
|
<< last_received_message_id << "] in " << dialog_id
|
||||||
<< d->last_database_message_id << " up to " << d->first_database_message_id;
|
<< " from database from the end, but expected messages from " << d->first_database_message_id
|
||||||
|
<< " up to " << d->last_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");
|
||||||
@ -23821,7 +23837,7 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (first_added_message_id.is_valid() && first_added_message_id != d->first_database_message_id &&
|
if (first_added_message_id.is_valid() && first_added_message_id != d->first_database_message_id &&
|
||||||
last_received_message_id < d->first_database_message_id && d->last_new_message_id.is_valid() &&
|
first_received_message_id < d->first_database_message_id && d->last_new_message_id.is_valid() &&
|
||||||
!d->have_full_history) {
|
!d->have_full_history) {
|
||||||
CHECK(first_added_message_id > d->first_database_message_id);
|
CHECK(first_added_message_id > d->first_database_message_id);
|
||||||
set_dialog_first_database_message_id(d, first_added_message_id, "on_get_history_from_database 10");
|
set_dialog_first_database_message_id(d, first_added_message_id, "on_get_history_from_database 10");
|
||||||
@ -23839,11 +23855,12 @@ 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) {
|
||||||
get_history_from_the_end_impl(get_dialog(dialog_id), from_database, only_local, std::move(promise));
|
get_history_from_the_end_impl(get_dialog(dialog_id), from_database, only_local, std::move(promise),
|
||||||
|
"get_history_from_the_end");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local,
|
void MessagesManager::get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local,
|
||||||
Promise<Unit> &&promise) {
|
Promise<Unit> &&promise, const char *source) {
|
||||||
CHECK(d != nullptr);
|
CHECK(d != nullptr);
|
||||||
TRY_STATUS_PROMISE(promise, G()->close_status());
|
TRY_STATUS_PROMISE(promise, G()->close_status());
|
||||||
|
|
||||||
@ -23861,7 +23878,7 @@ void MessagesManager::get_history_from_the_end_impl(const Dialog *d, bool from_d
|
|||||||
// repair last database message ID
|
// repair last database message ID
|
||||||
limit = 10;
|
limit = 10;
|
||||||
}
|
}
|
||||||
LOG(INFO) << "Get history from the end of " << dialog_id << " from database";
|
LOG(INFO) << "Get history from the end of " << dialog_id << " from database from " << source;
|
||||||
MessagesDbMessagesQuery db_query;
|
MessagesDbMessagesQuery db_query;
|
||||||
db_query.dialog_id = dialog_id;
|
db_query.dialog_id = dialog_id;
|
||||||
db_query.from_message_id = MessageId::max();
|
db_query.from_message_id = MessageId::max();
|
||||||
@ -23885,7 +23902,7 @@ void MessagesManager::get_history_from_the_end_impl(const Dialog *d, bool from_d
|
|||||||
limit = 10;
|
limit = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Get history from the end of " << dialog_id << " from server";
|
LOG(INFO) << "Get history from the end of " << dialog_id << " from server from " << source;
|
||||||
td_->create_handler<GetHistoryQuery>(std::move(promise))
|
td_->create_handler<GetHistoryQuery>(std::move(promise))
|
||||||
->send_get_from_the_end(dialog_id, d->last_new_message_id, limit);
|
->send_get_from_the_end(dialog_id, d->last_new_message_id, limit);
|
||||||
}
|
}
|
||||||
@ -23962,7 +23979,7 @@ void MessagesManager::load_messages_impl(const Dialog *d, MessageId from_message
|
|||||||
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;
|
||||||
|
|
||||||
if (from_message_id == MessageId()) {
|
if (from_message_id == MessageId()) {
|
||||||
get_history_from_the_end_impl(d, from_database, only_local, std::move(promise));
|
get_history_from_the_end_impl(d, from_database, only_local, std::move(promise), "load_messages_impl");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((!d->first_database_message_id.is_valid() || from_message_id <= d->first_database_message_id) &&
|
if ((!d->first_database_message_id.is_valid() || from_message_id <= d->first_database_message_id) &&
|
||||||
@ -32906,7 +32923,7 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CHECK(m->message_id.is_yet_unsent());
|
CHECK(m->message_id.is_yet_unsent());
|
||||||
if (m->forward_info != nullptr || m->had_forward_info || m->message_id.is_scheduled() ||
|
if (m->forward_info != nullptr || m->had_forward_info || m->is_copy || m->message_id.is_scheduled() ||
|
||||||
m->sender_dialog_id.is_valid()) {
|
m->sender_dialog_id.is_valid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -36380,7 +36397,8 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
|
|||||||
d->last_new_message_id = MessageId();
|
d->last_new_message_id = MessageId();
|
||||||
}
|
}
|
||||||
if (last_message_id.is_valid()) {
|
if (last_message_id.is_valid()) {
|
||||||
if ((last_message_id.is_server() || dialog_type == DialogType::SecretChat) && !d->last_new_message_id.is_valid()) {
|
if ((last_message_id.is_server() || dialog_type == DialogType::SecretChat) && !last_message_id.is_yet_unsent() &&
|
||||||
|
!d->last_new_message_id.is_valid()) {
|
||||||
LOG(ERROR) << "Bugfixing wrong last_new_message_id to " << last_message_id << " in " << dialog_id;
|
LOG(ERROR) << "Bugfixing wrong last_new_message_id to " << last_message_id << " in " << dialog_id;
|
||||||
// must be called before set_dialog_first_database_message_id and set_dialog_last_database_message_id
|
// must be called before set_dialog_first_database_message_id and set_dialog_last_database_message_id
|
||||||
set_dialog_last_new_message_id(d, last_message_id, "fix_new_dialog 1");
|
set_dialog_last_new_message_id(d, last_message_id, "fix_new_dialog 1");
|
||||||
@ -36418,19 +36436,24 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto last_message_date = last_database_message->date;
|
||||||
if (dependent_dialog_count == 0) {
|
if (dependent_dialog_count == 0) {
|
||||||
add_dialog_last_database_message(d, std::move(last_database_message));
|
if (!add_dialog_last_database_message(d, std::move(last_database_message))) {
|
||||||
|
// failed to add last message; keep the current position and get history from the database
|
||||||
|
d->pending_last_message_date = last_message_date;
|
||||||
|
d->pending_last_message_id = last_message_id;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// can't add message immediately, because need to notify first about adding of dependent dialogs
|
// can't add message immediately, because need to notify first about adding of dependent dialogs
|
||||||
d->pending_last_message_date = last_database_message->date;
|
d->pending_last_message_date = last_message_date;
|
||||||
d->pending_last_message_id = last_database_message->message_id;
|
d->pending_last_message_id = last_message_id;
|
||||||
pending_add_dialog_last_database_message_[dialog_id] = {dependent_dialog_count, std::move(last_database_message)};
|
pending_add_dialog_last_database_message_[dialog_id] = {dependent_dialog_count, std::move(last_database_message)};
|
||||||
}
|
}
|
||||||
} else if (last_database_message_id.is_valid()) {
|
} else if (last_database_message_id.is_valid()) {
|
||||||
auto date = DialogDate(order, dialog_id).get_date();
|
auto date = DialogDate(order, dialog_id).get_date();
|
||||||
if (date < MIN_PINNED_DIALOG_DATE) {
|
if (date < MIN_PINNED_DIALOG_DATE) {
|
||||||
d->pending_last_message_date = date;
|
d->pending_last_message_date = date;
|
||||||
d->pending_last_message_id = last_database_message_id;
|
d->pending_last_message_id = last_message_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36558,7 +36581,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
|
|||||||
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_ &&
|
||||||
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
||||||
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||||
get_history_from_the_end_impl(d, true, false, Auto());
|
get_history_from_the_end_impl(d, true, false, Auto(), "fix_new_dialog");
|
||||||
}
|
}
|
||||||
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);
|
||||||
@ -36569,7 +36592,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_datab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Message> &&last_database_message) {
|
bool MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Message> &&last_database_message) {
|
||||||
CHECK(d != nullptr);
|
CHECK(d != nullptr);
|
||||||
CHECK(last_database_message != nullptr);
|
CHECK(last_database_message != nullptr);
|
||||||
CHECK(last_database_message->left == nullptr);
|
CHECK(last_database_message->left == nullptr);
|
||||||
@ -36608,13 +36631,14 @@ void MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr<Mes
|
|||||||
if (!td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ &&
|
if (!td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ &&
|
||||||
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
dialog_id != being_added_by_new_message_dialog_id_ && have_input_peer(dialog_id, AccessRights::Read) &&
|
||||||
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||||
get_history_from_the_end_impl(d, true, false, Auto());
|
get_history_from_the_end_impl(d, true, false, Auto(), "add_dialog_last_database_message 5");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_update_dialog_pos) {
|
if (need_update_dialog_pos) {
|
||||||
update_dialog_pos(d, "add_dialog_last_database_message 5");
|
update_dialog_pos(d, "add_dialog_last_database_message 6");
|
||||||
}
|
}
|
||||||
|
return m != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesManager::update_dialogs_hints(const Dialog *d) {
|
void MessagesManager::update_dialogs_hints(const Dialog *d) {
|
||||||
@ -38192,10 +38216,13 @@ void MessagesManager::on_get_channel_difference(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bots can receive channelDifferenceEmpty with pts bigger than known pts
|
// bots can receive channelDifferenceEmpty with pts bigger than known pts
|
||||||
LOG_IF(ERROR, request_pts != difference->pts_ && !td_->auth_manager_->is_bot())
|
// also, this can happen for deleted channels
|
||||||
<< "Receive channelDifferenceEmpty as result of getChannelDifference with pts = " << request_pts
|
if (request_pts != difference->pts_ && !td_->auth_manager_->is_bot() &&
|
||||||
<< " and limit = " << request_limit << " in " << dialog_id << ", but pts has changed from " << request_pts
|
have_input_peer(dialog_id, AccessRights::Read)) {
|
||||||
<< " to " << difference->pts_;
|
LOG(ERROR) << "Receive channelDifferenceEmpty as result of getChannelDifference with pts = " << request_pts
|
||||||
|
<< " and limit = " << request_limit << " in " << dialog_id << ", but pts has changed to "
|
||||||
|
<< difference->pts_;
|
||||||
|
}
|
||||||
set_channel_pts(d, difference->pts_, "channel difference empty");
|
set_channel_pts(d, difference->pts_, "channel difference empty");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -38429,7 +38456,7 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ
|
|||||||
|
|
||||||
if (d != nullptr && !td_->auth_manager_->is_bot() && have_access && !d->last_message_id.is_valid() && !d->is_empty &&
|
if (d != nullptr && !td_->auth_manager_->is_bot() && have_access && !d->last_message_id.is_valid() && !d->is_empty &&
|
||||||
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
(d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) {
|
||||||
get_history_from_the_end_impl(d, true, false, Auto());
|
get_history_from_the_end_impl(d, true, false, Auto(), "after_get_channel_difference");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39501,7 +39528,7 @@ void MessagesManager::suffix_load_loop(Dialog *d) {
|
|||||||
get_history_impl(d, 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_impl(d, true, true, std::move(promise));
|
get_history_from_the_end_impl(d, true, true, std::move(promise), "suffix_load_loop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2235,7 +2235,8 @@ class MessagesManager final : public Actor {
|
|||||||
|
|
||||||
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_from_the_end_impl(const Dialog *d, bool from_database, bool only_local, Promise<Unit> &&promise,
|
||||||
|
const char *source);
|
||||||
|
|
||||||
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);
|
||||||
@ -2694,7 +2695,7 @@ class MessagesManager final : public Actor {
|
|||||||
DialogId default_join_group_call_as_dialog_id, DialogId default_send_message_as_dialog_id,
|
DialogId default_join_group_call_as_dialog_id, DialogId default_send_message_as_dialog_id,
|
||||||
bool need_drop_default_send_message_as_dialog_id, bool is_loaded_from_database);
|
bool need_drop_default_send_message_as_dialog_id, bool is_loaded_from_database);
|
||||||
|
|
||||||
void add_dialog_last_database_message(Dialog *d, unique_ptr<Message> &&last_database_message);
|
bool add_dialog_last_database_message(Dialog *d, unique_ptr<Message> &&last_database_message);
|
||||||
|
|
||||||
void fix_dialog_action_bar(const Dialog *d, DialogActionBar *action_bar);
|
void fix_dialog_action_bar(const Dialog *d, DialogActionBar *action_bar);
|
||||||
|
|
||||||
|
@ -3205,7 +3205,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo
|
|||||||
return Status::Error("Receive wrong chat type");
|
return Status::Error("Receive wrong chat type");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (begins_with(loc_key, "CHAT_MESSAGE") || loc_key == "CHAT_ALBUM") {
|
if (begins_with(loc_key, "CHAT_MESSAGE") || begins_with(loc_key, "CHAT_REACT") || loc_key == "CHAT_ALBUM") {
|
||||||
loc_key = loc_key.substr(5);
|
loc_key = loc_key.substr(5);
|
||||||
}
|
}
|
||||||
if (loc_args.empty()) {
|
if (loc_args.empty()) {
|
||||||
@ -3236,6 +3236,11 @@ Status NotificationManager::process_push_notification_payload(string payload, bo
|
|||||||
return Status::Error(406, "Phone call notification is not supported");
|
return Status::Error(406, "Phone call notification is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (begins_with(loc_key, "REACT_")) {
|
||||||
|
// TODO REACT_* notifications
|
||||||
|
return Status::Error(406, "Reaction notifications are unsupported");
|
||||||
|
}
|
||||||
|
|
||||||
loc_key = convert_loc_key(loc_key);
|
loc_key = convert_loc_key(loc_key);
|
||||||
if (loc_key.empty()) {
|
if (loc_key.empty()) {
|
||||||
return Status::Error("Push type is unknown");
|
return Status::Error("Push type is unknown");
|
||||||
|
@ -1458,22 +1458,6 @@ void NotificationSettingsManager::get_notify_settings_exceptions(NotificationSet
|
|||||||
td_->create_handler<GetNotifySettingsExceptionsQuery>(std::move(promise))->send(scope, filter_scope, compare_sound);
|
td_->create_handler<GetNotifySettingsExceptionsQuery>(std::move(promise))->send(scope, filter_scope, compare_sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationSettingsManager::after_get_difference() {
|
|
||||||
if (td_->auth_manager_->is_bot()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!users_notification_settings_.is_synchronized) {
|
|
||||||
send_get_scope_notification_settings_query(NotificationSettingsScope::Private, Promise<>());
|
|
||||||
}
|
|
||||||
if (!chats_notification_settings_.is_synchronized) {
|
|
||||||
send_get_scope_notification_settings_query(NotificationSettingsScope::Group, Promise<>());
|
|
||||||
}
|
|
||||||
if (!channels_notification_settings_.is_synchronized) {
|
|
||||||
send_get_scope_notification_settings_query(NotificationSettingsScope::Channel, Promise<>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationSettingsManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
void NotificationSettingsManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag()) {
|
||||||
return;
|
return;
|
||||||
|
@ -95,8 +95,6 @@ class NotificationSettingsManager final : public Actor {
|
|||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void after_get_difference();
|
|
||||||
|
|
||||||
void on_binlog_events(vector<BinlogEvent> &&events);
|
void on_binlog_events(vector<BinlogEvent> &&events);
|
||||||
|
|
||||||
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
|
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
|
||||||
|
@ -734,8 +734,7 @@ Result<InputInvoice> process_input_message_invoice(
|
|||||||
|
|
||||||
PhotoSize s;
|
PhotoSize s;
|
||||||
s.type = 'n';
|
s.type = 'n';
|
||||||
s.dimensions =
|
s.dimensions = get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, nullptr);
|
||||||
get_dimensions(input_invoice->photo_width_, input_invoice->photo_height_, "process_input_message_invoice");
|
|
||||||
s.size = input_invoice->photo_size_; // TODO use invoice_file_id size
|
s.size = input_invoice->photo_size_; // TODO use invoice_file_id size
|
||||||
s.file_id = invoice_file_id;
|
s.file_id = invoice_file_id;
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr<EncryptedFi
|
|||||||
|
|
||||||
PhotoSize s;
|
PhotoSize s;
|
||||||
s.type = 'i';
|
s.type = 'i';
|
||||||
s.dimensions = get_dimensions(photo->w_, photo->h_, "get_encrypted_file_photo");
|
s.dimensions = get_dimensions(photo->w_, photo->h_, nullptr);
|
||||||
s.size = photo->size_;
|
s.size = photo->size_;
|
||||||
s.file_id = file_id;
|
s.file_id = file_id;
|
||||||
res.photos.push_back(s);
|
res.photos.push_back(s);
|
||||||
|
@ -25,7 +25,9 @@ namespace td {
|
|||||||
|
|
||||||
static uint16 get_dimension(int32 size, const char *source) {
|
static uint16 get_dimension(int32 size, const char *source) {
|
||||||
if (size < 0 || size > 65535) {
|
if (size < 0 || size > 65535) {
|
||||||
LOG(ERROR) << "Wrong image dimension = " << size << " from " << source;
|
if (source != nullptr) {
|
||||||
|
LOG(ERROR) << "Wrong image dimension = " << size << " from " << source;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return narrow_cast<uint16>(size);
|
return narrow_cast<uint16>(size);
|
||||||
@ -179,7 +181,7 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice
|
|||||||
}
|
}
|
||||||
PhotoSize res;
|
PhotoSize res;
|
||||||
res.type = 't';
|
res.type = 't';
|
||||||
res.dimensions = get_dimensions(width, height, "get_secret_thumbnail_photo_size");
|
res.dimensions = get_dimensions(width, height, nullptr);
|
||||||
res.size = narrow_cast<int32>(bytes.size());
|
res.size = narrow_cast<int32>(bytes.size());
|
||||||
|
|
||||||
// generate some random remote location to save
|
// generate some random remote location to save
|
||||||
|
@ -1292,6 +1292,9 @@ void PollManager::on_unload_poll_timeout(PollId poll_id) {
|
|||||||
if (!can_unload_poll(poll_id)) {
|
if (!can_unload_poll(poll_id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!have_poll(poll_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Unload " << poll_id;
|
LOG(INFO) << "Unload " << poll_id;
|
||||||
|
|
||||||
@ -1303,6 +1306,7 @@ void PollManager::on_unload_poll_timeout(PollId poll_id) {
|
|||||||
|
|
||||||
poll_voters_.erase(poll_id);
|
poll_voters_.erase(poll_id);
|
||||||
loaded_from_database_polls_.erase(poll_id);
|
loaded_from_database_polls_.erase(poll_id);
|
||||||
|
unload_poll_timeout_.cancel_timeout(poll_id.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollManager::on_get_poll_results(PollId poll_id, uint64 generation,
|
void PollManager::on_get_poll_results(PollId poll_id, uint64 generation,
|
||||||
@ -1422,38 +1426,41 @@ vector<PollManager::PollOption> PollManager::get_poll_options(
|
|||||||
}
|
}
|
||||||
|
|
||||||
PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll> &&poll_server,
|
PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll> &&poll_server,
|
||||||
tl_object_ptr<telegram_api::pollResults> &&poll_results) {
|
tl_object_ptr<telegram_api::pollResults> &&poll_results, const char *source) {
|
||||||
bool is_bot = td_->auth_manager_->is_bot();
|
bool is_bot = td_->auth_manager_->is_bot();
|
||||||
bool need_update_poll = poll_id.is_valid() && is_bot;
|
bool need_update_poll = poll_id.is_valid() && is_bot;
|
||||||
if (!poll_id.is_valid() && poll_server != nullptr) {
|
if (!poll_id.is_valid() && poll_server != nullptr) {
|
||||||
poll_id = PollId(poll_server->id_);
|
poll_id = PollId(poll_server->id_);
|
||||||
}
|
}
|
||||||
if (!poll_id.is_valid() || is_local_poll_id(poll_id)) {
|
if (!poll_id.is_valid() || is_local_poll_id(poll_id)) {
|
||||||
LOG(ERROR) << "Receive " << poll_id << " from server: " << oneline(to_string(poll_server)) << " "
|
LOG(ERROR) << "Receive " << poll_id << " from " << source << ": " << oneline(to_string(poll_server)) << " "
|
||||||
<< oneline(to_string(poll_results));
|
<< oneline(to_string(poll_results));
|
||||||
return PollId();
|
return PollId();
|
||||||
}
|
}
|
||||||
if (poll_server != nullptr && poll_server->id_ != poll_id.get()) {
|
if (poll_server != nullptr && poll_server->id_ != poll_id.get()) {
|
||||||
LOG(ERROR) << "Receive poll " << poll_server->id_ << " instead of " << poll_id;
|
LOG(ERROR) << "Receive poll " << poll_server->id_ << " instead of " << poll_id << " from " << source;
|
||||||
return PollId();
|
return PollId();
|
||||||
}
|
}
|
||||||
constexpr size_t MAX_POLL_OPTIONS = 10; // server-side limit
|
constexpr size_t MAX_POLL_OPTIONS = 10; // server-side limit
|
||||||
if (poll_server != nullptr &&
|
if (poll_server != nullptr &&
|
||||||
(poll_server->answers_.size() <= 1 || poll_server->answers_.size() > 10 * MAX_POLL_OPTIONS)) {
|
(poll_server->answers_.size() <= 1 || poll_server->answers_.size() > 10 * MAX_POLL_OPTIONS)) {
|
||||||
LOG(ERROR) << "Receive " << poll_id << " with wrong number of answers: " << to_string(poll_server);
|
LOG(ERROR) << "Receive " << poll_id << " from " << source
|
||||||
|
<< " with wrong number of answers: " << to_string(poll_server);
|
||||||
return PollId();
|
return PollId();
|
||||||
}
|
}
|
||||||
if (poll_server != nullptr) {
|
if (poll_server != nullptr) {
|
||||||
FlatHashSet<Slice, SliceHash> option_data;
|
FlatHashSet<Slice, SliceHash> option_data;
|
||||||
for (auto &answer : poll_server->answers_) {
|
for (auto &answer : poll_server->answers_) {
|
||||||
if (answer->option_.empty()) {
|
if (answer->option_.empty()) {
|
||||||
LOG(ERROR) << "Receive " << poll_id << " with an empty option data: " << to_string(poll_server);
|
LOG(ERROR) << "Receive " << poll_id << " from " << source
|
||||||
|
<< " with an empty option data: " << to_string(poll_server);
|
||||||
return PollId();
|
return PollId();
|
||||||
}
|
}
|
||||||
option_data.insert(answer->option_.as_slice());
|
option_data.insert(answer->option_.as_slice());
|
||||||
}
|
}
|
||||||
if (option_data.size() != poll_server->answers_.size()) {
|
if (option_data.size() != poll_server->answers_.size()) {
|
||||||
LOG(ERROR) << "Receive " << poll_id << " with duplicate options: " << to_string(poll_server);
|
LOG(ERROR) << "Receive " << poll_id << " from " << source
|
||||||
|
<< " with duplicate options: " << to_string(poll_server);
|
||||||
return PollId();
|
return PollId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1571,7 +1578,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
bool allow_multiple_answers = (poll_server->flags_ & telegram_api::poll::MULTIPLE_CHOICE_MASK) != 0;
|
bool allow_multiple_answers = (poll_server->flags_ & telegram_api::poll::MULTIPLE_CHOICE_MASK) != 0;
|
||||||
bool is_quiz = (poll_server->flags_ & telegram_api::poll::QUIZ_MASK) != 0;
|
bool is_quiz = (poll_server->flags_ & telegram_api::poll::QUIZ_MASK) != 0;
|
||||||
if (is_quiz && allow_multiple_answers) {
|
if (is_quiz && allow_multiple_answers) {
|
||||||
LOG(ERROR) << "Receive quiz " << poll_id << " allowing multiple answers";
|
LOG(ERROR) << "Receive quiz " << poll_id << " from " << source << " allowing multiple answers";
|
||||||
allow_multiple_answers = false;
|
allow_multiple_answers = false;
|
||||||
}
|
}
|
||||||
if (allow_multiple_answers != poll->allow_multiple_answers) {
|
if (allow_multiple_answers != poll->allow_multiple_answers) {
|
||||||
@ -1590,7 +1597,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
if (has_total_voters && poll_results->total_voters_ != poll->total_voter_count) {
|
if (has_total_voters && poll_results->total_voters_ != poll->total_voter_count) {
|
||||||
poll->total_voter_count = poll_results->total_voters_;
|
poll->total_voter_count = poll_results->total_voters_;
|
||||||
if (poll->total_voter_count < 0) {
|
if (poll->total_voter_count < 0) {
|
||||||
LOG(ERROR) << "Receive " << poll->total_voter_count << " voters in " << poll_id;
|
LOG(ERROR) << "Receive " << poll->total_voter_count << " voters in " << poll_id << " from " << source;
|
||||||
poll->total_voter_count = 0;
|
poll->total_voter_count = 0;
|
||||||
}
|
}
|
||||||
is_changed = true;
|
is_changed = true;
|
||||||
@ -1614,7 +1621,8 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
bool is_correct = poll_result->correct_;
|
bool is_correct = poll_result->correct_;
|
||||||
if (is_correct) {
|
if (is_correct) {
|
||||||
if (correct_option_id != -1) {
|
if (correct_option_id != -1) {
|
||||||
LOG(ERROR) << "Receive more than 1 correct answers " << correct_option_id << " and " << option_index;
|
LOG(ERROR) << "Receive more than 1 correct answers " << correct_option_id << " and " << option_index
|
||||||
|
<< " in " << poll_id << " from " << source;
|
||||||
}
|
}
|
||||||
correct_option_id = static_cast<int32>(option_index);
|
correct_option_id = static_cast<int32>(option_index);
|
||||||
}
|
}
|
||||||
@ -1623,21 +1631,23 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (poll_result->voters_ < 0) {
|
if (poll_result->voters_ < 0) {
|
||||||
LOG(ERROR) << "Receive " << poll_result->voters_ << " voters for an option in " << poll_id;
|
LOG(ERROR) << "Receive " << poll_result->voters_ << " voters for an option in " << poll_id << " from "
|
||||||
|
<< source;
|
||||||
poll_result->voters_ = 0;
|
poll_result->voters_ = 0;
|
||||||
}
|
}
|
||||||
if (option.is_chosen && poll_result->voters_ == 0) {
|
if (option.is_chosen && poll_result->voters_ == 0) {
|
||||||
LOG(ERROR) << "Receive 0 voters for the chosen option in " << poll_id;
|
LOG(ERROR) << "Receive 0 voters for the chosen option in " << poll_id << " from " << source;
|
||||||
poll_result->voters_ = 1;
|
poll_result->voters_ = 1;
|
||||||
}
|
}
|
||||||
if (poll_result->voters_ > poll->total_voter_count) {
|
if (poll_result->voters_ > poll->total_voter_count) {
|
||||||
LOG(ERROR) << "Have only " << poll->total_voter_count << " poll voters, but there are " << poll_result->voters_
|
LOG(ERROR) << "Have only " << poll->total_voter_count << " poll voters, but there are " << poll_result->voters_
|
||||||
<< " voters for an option in " << poll_id;
|
<< " voters for an option in " << poll_id << " from " << source;
|
||||||
poll->total_voter_count = poll_result->voters_;
|
poll->total_voter_count = poll_result->voters_;
|
||||||
}
|
}
|
||||||
auto max_voter_count = std::numeric_limits<int32>::max() / narrow_cast<int32>(poll->options.size()) - 2;
|
auto max_voter_count = std::numeric_limits<int32>::max() / narrow_cast<int32>(poll->options.size()) - 2;
|
||||||
if (poll_result->voters_ > max_voter_count) {
|
if (poll_result->voters_ > max_voter_count) {
|
||||||
LOG(ERROR) << "Have too many " << poll_result->voters_ << " poll voters for an option in " << poll_id;
|
LOG(ERROR) << "Have too many " << poll_result->voters_ << " poll voters for an option in " << poll_id
|
||||||
|
<< " from " << source;
|
||||||
poll_result->voters_ = max_voter_count;
|
poll_result->voters_ = max_voter_count;
|
||||||
}
|
}
|
||||||
if (poll_result->voters_ != option.voter_count) {
|
if (poll_result->voters_ != option.voter_count) {
|
||||||
@ -1654,13 +1664,13 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
}
|
}
|
||||||
if (poll->total_voter_count > max_total_voter_count && max_total_voter_count != 0) {
|
if (poll->total_voter_count > max_total_voter_count && max_total_voter_count != 0) {
|
||||||
LOG(ERROR) << "Have only " << max_total_voter_count << " total poll voters, but there are "
|
LOG(ERROR) << "Have only " << max_total_voter_count << " total poll voters, but there are "
|
||||||
<< poll->total_voter_count << " voters in " << poll_id;
|
<< poll->total_voter_count << " voters in " << poll_id << " from " << source;
|
||||||
poll->total_voter_count = max_total_voter_count;
|
poll->total_voter_count = max_total_voter_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto entities =
|
auto entities =
|
||||||
get_message_entities(td_->contacts_manager_.get(), std::move(poll_results->solution_entities_), "on_get_poll");
|
get_message_entities(td_->contacts_manager_.get(), std::move(poll_results->solution_entities_), source);
|
||||||
auto status = fix_formatted_text(poll_results->solution_, entities, true, true, true, true, false);
|
auto status = fix_formatted_text(poll_results->solution_, entities, true, true, true, true, false);
|
||||||
if (status.is_error()) {
|
if (status.is_error()) {
|
||||||
if (!clean_input_string(poll_results->solution_)) {
|
if (!clean_input_string(poll_results->solution_)) {
|
||||||
@ -1674,7 +1684,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
if (poll->correct_option_id != correct_option_id) {
|
if (poll->correct_option_id != correct_option_id) {
|
||||||
if (correct_option_id == -1 && poll->correct_option_id != -1) {
|
if (correct_option_id == -1 && poll->correct_option_id != -1) {
|
||||||
LOG(ERROR) << "Can't change correct option of " << poll_id << " from " << poll->correct_option_id << " to "
|
LOG(ERROR) << "Can't change correct option of " << poll_id << " from " << poll->correct_option_id << " to "
|
||||||
<< correct_option_id;
|
<< correct_option_id << " from " << source;
|
||||||
} else {
|
} else {
|
||||||
poll->correct_option_id = correct_option_id;
|
poll->correct_option_id = correct_option_id;
|
||||||
is_changed = true;
|
is_changed = true;
|
||||||
@ -1682,7 +1692,7 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
}
|
}
|
||||||
if (poll->explanation != explanation && (!is_min || poll_server_is_closed)) {
|
if (poll->explanation != explanation && (!is_min || poll_server_is_closed)) {
|
||||||
if (explanation.text.empty() && !poll->explanation.text.empty()) {
|
if (explanation.text.empty() && !poll->explanation.text.empty()) {
|
||||||
LOG(ERROR) << "Can't change known " << poll_id << " explanation to empty";
|
LOG(ERROR) << "Can't change known " << poll_id << " explanation to empty from " << source ;
|
||||||
} else {
|
} else {
|
||||||
poll->explanation = std::move(explanation);
|
poll->explanation = std::move(explanation);
|
||||||
is_changed = true;
|
is_changed = true;
|
||||||
@ -1690,10 +1700,10 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (correct_option_id != -1) {
|
if (correct_option_id != -1) {
|
||||||
LOG(ERROR) << "Receive correct option " << correct_option_id << " in non-quiz " << poll_id;
|
LOG(ERROR) << "Receive correct option " << correct_option_id << " in non-quiz " << poll_id << " from " << source;
|
||||||
}
|
}
|
||||||
if (!explanation.text.empty()) {
|
if (!explanation.text.empty()) {
|
||||||
LOG(ERROR) << "Receive explanation " << explanation << " in non-quiz " << poll_id;
|
LOG(ERROR) << "Receive explanation " << explanation << " in non-quiz " << poll_id << " from " << source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1704,12 +1714,13 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll
|
|||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
recent_voter_user_ids.push_back(user_id);
|
recent_voter_user_ids.push_back(user_id);
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Receive " << user_id << " as recent voter in " << poll_id;
|
LOG(ERROR) << "Receive " << user_id << " as recent voter in " << poll_id << " from " << source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (poll->is_anonymous && !recent_voter_user_ids.empty()) {
|
if (poll->is_anonymous && !recent_voter_user_ids.empty()) {
|
||||||
LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_user_ids;
|
LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_user_ids << " from "
|
||||||
|
<< source;
|
||||||
recent_voter_user_ids.clear();
|
recent_voter_user_ids.clear();
|
||||||
}
|
}
|
||||||
if (recent_voter_user_ids != poll->recent_voter_user_ids) {
|
if (recent_voter_user_ids != poll->recent_voter_user_ids) {
|
||||||
|
@ -79,7 +79,7 @@ class PollManager final : public Actor {
|
|||||||
tl_object_ptr<telegram_api::InputMedia> get_input_media(PollId poll_id) const;
|
tl_object_ptr<telegram_api::InputMedia> get_input_media(PollId poll_id) const;
|
||||||
|
|
||||||
PollId on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll> &&poll_server,
|
PollId on_get_poll(PollId poll_id, tl_object_ptr<telegram_api::poll> &&poll_server,
|
||||||
tl_object_ptr<telegram_api::pollResults> &&poll_results);
|
tl_object_ptr<telegram_api::pollResults> &&poll_results, const char *source);
|
||||||
|
|
||||||
void on_get_poll_vote(PollId poll_id, UserId user_id, vector<BufferSlice> &&options);
|
void on_get_poll_vote(PollId poll_id, UserId user_id, vector<BufferSlice> &&options);
|
||||||
|
|
||||||
|
@ -442,18 +442,17 @@ static Result<KeyboardButton> get_keyboard_button(tl_object_ptr<td_api::keyboard
|
|||||||
}
|
}
|
||||||
case td_api::keyboardButtonTypeWebApp::ID: {
|
case td_api::keyboardButtonTypeWebApp::ID: {
|
||||||
if (!request_buttons_allowed) {
|
if (!request_buttons_allowed) {
|
||||||
return Status::Error(400, "Web app can be used in private chats only");
|
return Status::Error(400, "Web App buttons can be used in private chats only");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto button_type = move_tl_object_as<td_api::keyboardButtonTypeWebApp>(button->type_);
|
auto button_type = move_tl_object_as<td_api::keyboardButtonTypeWebApp>(button->type_);
|
||||||
auto user_id = LinkManager::get_link_user_id(button_type->url_);
|
auto user_id = LinkManager::get_link_user_id(button_type->url_);
|
||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
return Status::Error(400, "Link to a user can't be used in web app URL buttons");
|
return Status::Error(400, "Link to a user can't be used in Web App URL buttons");
|
||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(button_type->url_, true, !G()->is_test_dc());
|
auto r_url = LinkManager::check_link(button_type->url_, true, !G()->is_test_dc());
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
return Status::Error(400, PSLICE() << "Inline keyboard button web app URL '" << button_type->url_
|
return Status::Error(400, PSLICE() << "Keyboard button Web App " << r_url.error().message());
|
||||||
<< "' is invalid: " << r_url.error().message());
|
|
||||||
}
|
}
|
||||||
current_button.type = KeyboardButton::Type::WebView;
|
current_button.type = KeyboardButton::Type::WebView;
|
||||||
current_button.url = std::move(button_type->url_);
|
current_button.url = std::move(button_type->url_);
|
||||||
@ -491,8 +490,7 @@ static Result<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_
|
|||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(button_type->url_);
|
auto r_url = LinkManager::check_link(button_type->url_);
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
return Status::Error(400, PSLICE() << "Inline keyboard button URL '" << button_type->url_
|
return Status::Error(400, PSLICE() << "Inline keyboard button " << r_url.error().message());
|
||||||
<< "' is invalid: " << r_url.error().message());
|
|
||||||
}
|
}
|
||||||
current_button.type = InlineKeyboardButton::Type::Url;
|
current_button.type = InlineKeyboardButton::Type::Url;
|
||||||
current_button.data = r_url.move_as_ok();
|
current_button.data = r_url.move_as_ok();
|
||||||
@ -541,8 +539,7 @@ static Result<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_
|
|||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(button_type->url_, true);
|
auto r_url = LinkManager::check_link(button_type->url_, true);
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
return Status::Error(400, PSLICE() << "Inline keyboard button login URL '" << button_type->url_
|
return Status::Error(400, PSLICE() << "Inline keyboard button login " << r_url.error().message());
|
||||||
<< "' is invalid: " << r_url.error().message());
|
|
||||||
}
|
}
|
||||||
current_button.type = InlineKeyboardButton::Type::UrlAuth;
|
current_button.type = InlineKeyboardButton::Type::UrlAuth;
|
||||||
current_button.data = r_url.move_as_ok();
|
current_button.data = r_url.move_as_ok();
|
||||||
@ -573,17 +570,16 @@ static Result<InlineKeyboardButton> get_inline_keyboard_button(tl_object_ptr<td_
|
|||||||
auto button_type = move_tl_object_as<td_api::inlineKeyboardButtonTypeWebApp>(button->type_);
|
auto button_type = move_tl_object_as<td_api::inlineKeyboardButtonTypeWebApp>(button->type_);
|
||||||
auto user_id = LinkManager::get_link_user_id(button_type->url_);
|
auto user_id = LinkManager::get_link_user_id(button_type->url_);
|
||||||
if (user_id.is_valid()) {
|
if (user_id.is_valid()) {
|
||||||
return Status::Error(400, "Link to a user can't be used in web app URL buttons");
|
return Status::Error(400, "Link to a user can't be used in Web App URL buttons");
|
||||||
}
|
}
|
||||||
auto r_url = LinkManager::check_link(button_type->url_, true, !G()->is_test_dc());
|
auto r_url = LinkManager::check_link(button_type->url_, true, !G()->is_test_dc());
|
||||||
if (r_url.is_error()) {
|
if (r_url.is_error()) {
|
||||||
return Status::Error(400, PSLICE() << "Inline keyboard button web app URL '" << button_type->url_
|
return Status::Error(400, PSLICE() << "Inline keyboard button Web App " << r_url.error().message());
|
||||||
<< "' is invalid: " << r_url.error().message());
|
|
||||||
}
|
}
|
||||||
current_button.type = InlineKeyboardButton::Type::WebView;
|
current_button.type = InlineKeyboardButton::Type::WebView;
|
||||||
current_button.data = r_url.move_as_ok();
|
current_button.data = r_url.move_as_ok();
|
||||||
if (!clean_input_string(current_button.data)) {
|
if (!clean_input_string(current_button.data)) {
|
||||||
return Status::Error(400, "Inline keyboard button web app URL must be encoded in UTF-8");
|
return Status::Error(400, "Inline keyboard button Web App URL must be encoded in UTF-8");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -950,6 +950,9 @@ Status SecretChatActor::do_inbound_message_decrypted_unchecked(unique_ptr<log_ev
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Receive message encrypted with MTProto " << mtproto_version << ": "
|
||||||
|
<< to_string(message->decrypted_message_layer);
|
||||||
|
|
||||||
if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessageService8::ID) {
|
if (message->decrypted_message_layer->message_->get_id() == secret_api::decryptedMessageService8::ID) {
|
||||||
auto old = move_tl_object_as<secret_api::decryptedMessageService8>(message->decrypted_message_layer->message_);
|
auto old = move_tl_object_as<secret_api::decryptedMessageService8>(message->decrypted_message_layer->message_);
|
||||||
message->decrypted_message_layer->message_ =
|
message->decrypted_message_layer->message_ =
|
||||||
@ -985,9 +988,6 @@ Status SecretChatActor::do_inbound_message_decrypted_unchecked(unique_ptr<log_ev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Receive message encrypted with MTProto " << mtproto_version << ": "
|
|
||||||
<< to_string(message->decrypted_message_layer);
|
|
||||||
|
|
||||||
if (status.is_error()) {
|
if (status.is_error()) {
|
||||||
CHECK(status.code() == 2); // gap found
|
CHECK(status.code() == 2); // gap found
|
||||||
do_inbound_message_decrypted_pending(std::move(message));
|
do_inbound_message_decrypted_pending(std::move(message));
|
||||||
|
@ -713,7 +713,7 @@ static Result<int32> to_int32(Slice str) {
|
|||||||
int32 integer_value = 0;
|
int32 integer_value = 0;
|
||||||
for (auto c : str) {
|
for (auto c : str) {
|
||||||
if (!is_digit(c)) {
|
if (!is_digit(c)) {
|
||||||
return Status::Error(PSLICE() << "Can't parse \"" << str << "\" as number");
|
return Status::Error(400, PSLICE() << "Can't parse \"" << utf8_encode(str.str()) << "\" as number");
|
||||||
}
|
}
|
||||||
integer_value = integer_value * 10 + c - '0';
|
integer_value = integer_value * 10 + c - '0';
|
||||||
}
|
}
|
||||||
@ -725,12 +725,12 @@ static Result<td_api::object_ptr<td_api::date>> get_date_object(Slice date) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (date.size() > 10u || date.size() < 8u) {
|
if (date.size() > 10u || date.size() < 8u) {
|
||||||
return Status::Error(400, PSLICE() << "Date \"" << date << "\" has wrong length");
|
return Status::Error(400, PSLICE() << "Date \"" << utf8_encode(date.str()) << "\" has wrong length");
|
||||||
}
|
}
|
||||||
auto parts = full_split(date, '.');
|
auto parts = full_split(date, '.');
|
||||||
if (parts.size() != 3 || parts[0].size() > 2 || parts[1].size() > 2 || parts[2].size() != 4 || parts[0].empty() ||
|
if (parts.size() != 3 || parts[0].size() > 2 || parts[1].size() > 2 || parts[2].size() != 4 || parts[0].empty() ||
|
||||||
parts[1].empty()) {
|
parts[1].empty()) {
|
||||||
return Status::Error(400, PSLICE() << "Date \"" << date << "\" has wrong parts");
|
return Status::Error(400, PSLICE() << "Date \"" << utf8_encode(date.str()) << "\" has wrong parts");
|
||||||
}
|
}
|
||||||
TRY_RESULT(day, to_int32(parts[0]));
|
TRY_RESULT(day, to_int32(parts[0]));
|
||||||
TRY_RESULT(month, to_int32(parts[1]));
|
TRY_RESULT(month, to_int32(parts[1]));
|
||||||
@ -1196,7 +1196,7 @@ Result<SecureValueWithCredentials> decrypt_secure_value(FileManager *file_manage
|
|||||||
res_credentials.hash = encrypted_secure_value.hash;
|
res_credentials.hash = encrypted_secure_value.hash;
|
||||||
switch (encrypted_secure_value.type) {
|
switch (encrypted_secure_value.type) {
|
||||||
case SecureValueType::None:
|
case SecureValueType::None:
|
||||||
return Status::Error("Receive invalid Telegram Passport element");
|
return Status::Error(400, "Receive invalid Telegram Passport element");
|
||||||
case SecureValueType::EmailAddress:
|
case SecureValueType::EmailAddress:
|
||||||
case SecureValueType::PhoneNumber:
|
case SecureValueType::PhoneNumber:
|
||||||
res.data = encrypted_secure_value.data.data;
|
res.data = encrypted_secure_value.data.data;
|
||||||
|
@ -5647,8 +5647,7 @@ Result<std::tuple<FileId, bool, bool, StickerFormat>> StickersManager::prepare_i
|
|||||||
|
|
||||||
if (format == StickerFormat::Tgs) {
|
if (format == StickerFormat::Tgs) {
|
||||||
int32 width = for_thumbnail ? 100 : 512;
|
int32 width = for_thumbnail ? 100 : 512;
|
||||||
create_sticker(file_id, string(), PhotoSize(), get_dimensions(width, width, "prepare_input_file"), nullptr, format,
|
create_sticker(file_id, string(), PhotoSize(), get_dimensions(width, width, nullptr), nullptr, format, nullptr);
|
||||||
nullptr);
|
|
||||||
} else if (format == StickerFormat::Webm) {
|
} else if (format == StickerFormat::Webm) {
|
||||||
td_->documents_manager_->create_document(file_id, string(), PhotoSize(), "sticker.webm", "video/webm", false);
|
td_->documents_manager_->create_document(file_id, string(), PhotoSize(), "sticker.webm", "video/webm", false);
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "td/telegram/net/DcOptions.h"
|
#include "td/telegram/net/DcOptions.h"
|
||||||
#include "td/telegram/net/NetQuery.h"
|
#include "td/telegram/net/NetQuery.h"
|
||||||
#include "td/telegram/NotificationManager.h"
|
#include "td/telegram/NotificationManager.h"
|
||||||
|
#include "td/telegram/NotificationSettings.h"
|
||||||
#include "td/telegram/NotificationSettingsManager.h"
|
#include "td/telegram/NotificationSettingsManager.h"
|
||||||
#include "td/telegram/Payments.h"
|
#include "td/telegram/Payments.h"
|
||||||
#include "td/telegram/PollId.h"
|
#include "td/telegram/PollId.h"
|
||||||
@ -1601,7 +1602,6 @@ void UpdatesManager::after_get_difference() {
|
|||||||
td_->download_manager_->after_get_difference();
|
td_->download_manager_->after_get_difference();
|
||||||
td_->inline_queries_manager_->after_get_difference();
|
td_->inline_queries_manager_->after_get_difference();
|
||||||
td_->messages_manager_->after_get_difference();
|
td_->messages_manager_->after_get_difference();
|
||||||
td_->notification_settings_manager_->after_get_difference();
|
|
||||||
send_closure_later(td_->notification_manager_actor_, &NotificationManager::after_get_difference);
|
send_closure_later(td_->notification_manager_actor_, &NotificationManager::after_get_difference);
|
||||||
send_closure(G()->state_manager(), &StateManager::on_synchronized, true);
|
send_closure(G()->state_manager(), &StateManager::on_synchronized, true);
|
||||||
get_difference_start_time_ = 0.0;
|
get_difference_start_time_ = 0.0;
|
||||||
@ -1648,6 +1648,12 @@ void UpdatesManager::try_reload_data() {
|
|||||||
td_->contacts_manager_->reload_created_public_dialogs(PublicDialogType::HasUsername, Auto());
|
td_->contacts_manager_->reload_created_public_dialogs(PublicDialogType::HasUsername, Auto());
|
||||||
td_->contacts_manager_->reload_created_public_dialogs(PublicDialogType::IsLocationBased, Auto());
|
td_->contacts_manager_->reload_created_public_dialogs(PublicDialogType::IsLocationBased, Auto());
|
||||||
td_->notification_settings_manager_->reload_saved_ringtones(Auto());
|
td_->notification_settings_manager_->reload_saved_ringtones(Auto());
|
||||||
|
td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Private,
|
||||||
|
Auto());
|
||||||
|
td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Group,
|
||||||
|
Auto());
|
||||||
|
td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Channel,
|
||||||
|
Auto());
|
||||||
td_->stickers_manager_->reload_reactions();
|
td_->stickers_manager_->reload_reactions();
|
||||||
td_->stickers_manager_->get_installed_sticker_sets(false, Auto());
|
td_->stickers_manager_->get_installed_sticker_sets(false, Auto());
|
||||||
td_->stickers_manager_->get_installed_sticker_sets(true, Auto());
|
td_->stickers_manager_->get_installed_sticker_sets(true, Auto());
|
||||||
@ -1773,6 +1779,7 @@ void UpdatesManager::on_pending_updates(vector<tl_object_ptr<telegram_api::Updat
|
|||||||
|
|
||||||
size_t ordinary_new_message_count = 0;
|
size_t ordinary_new_message_count = 0;
|
||||||
size_t scheduled_new_message_count = 0;
|
size_t scheduled_new_message_count = 0;
|
||||||
|
size_t update_message_id_count = 0;
|
||||||
for (auto &update : updates) {
|
for (auto &update : updates) {
|
||||||
if (update != nullptr) {
|
if (update != nullptr) {
|
||||||
auto constructor_id = update->get_id();
|
auto constructor_id = update->get_id();
|
||||||
@ -1781,11 +1788,13 @@ void UpdatesManager::on_pending_updates(vector<tl_object_ptr<telegram_api::Updat
|
|||||||
ordinary_new_message_count++;
|
ordinary_new_message_count++;
|
||||||
} else if (constructor_id == telegram_api::updateNewScheduledMessage::ID) {
|
} else if (constructor_id == telegram_api::updateNewScheduledMessage::ID) {
|
||||||
scheduled_new_message_count++;
|
scheduled_new_message_count++;
|
||||||
|
} else if (constructor_id == telegram_api::updateMessageID::ID) {
|
||||||
|
update_message_id_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ordinary_new_message_count != 0 && scheduled_new_message_count != 0) {
|
if (update_message_id_count != 0 && ordinary_new_message_count != 0 && scheduled_new_message_count != 0) {
|
||||||
LOG(ERROR) << "Receive mixed message types in updates:";
|
LOG(ERROR) << "Receive mixed message types in updates:";
|
||||||
for (auto &update : updates) {
|
for (auto &update : updates) {
|
||||||
LOG(ERROR) << "Update: " << oneline(to_string(update));
|
LOG(ERROR) << "Update: " << oneline(to_string(update));
|
||||||
@ -3341,7 +3350,8 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateGeoLiveViewed>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateMessagePoll> update, Promise<Unit> &&promise) {
|
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateMessagePoll> update, Promise<Unit> &&promise) {
|
||||||
td_->poll_manager_->on_get_poll(PollId(update->poll_id_), std::move(update->poll_), std::move(update->results_));
|
td_->poll_manager_->on_get_poll(PollId(update->poll_id_), std::move(update->poll_), std::move(update->results_),
|
||||||
|
"updateMessagePoll");
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +39,8 @@ class FileData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline StringBuilder &operator<<(StringBuilder &sb, const FileData &file_data) {
|
inline StringBuilder &operator<<(StringBuilder &sb, const FileData &file_data) {
|
||||||
sb << "[" << tag("remote_name", file_data.remote_name_) << " " << file_data.owner_dialog_id_ << " "
|
sb << "[" << tag("remote_name", file_data.remote_name_) << " " << tag("size", file_data.size_)
|
||||||
<< tag("size", file_data.size_) << tag("expected_size", file_data.expected_size_) << " "
|
<< tag("expected_size", file_data.expected_size_) << " " << file_data.encryption_key_;
|
||||||
<< file_data.encryption_key_;
|
|
||||||
if (!file_data.url_.empty()) {
|
if (!file_data.url_.empty()) {
|
||||||
sb << tag("url", file_data.url_);
|
sb << tag("url", file_data.url_);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "td/utils/Time.h"
|
#include "td/utils/Time.h"
|
||||||
#include "td/utils/tl_helpers.h"
|
#include "td/utils/tl_helpers.h"
|
||||||
#include "td/utils/tl_parsers.h"
|
#include "td/utils/tl_parsers.h"
|
||||||
|
#include "td/utils/utf8.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -990,27 +991,29 @@ Status FileManager::check_local_location(FullLocalFileLocation &location, int64
|
|||||||
} else if (!are_modification_times_equal(location.mtime_nsec_, stat.mtime_nsec_)) {
|
} else if (!are_modification_times_equal(location.mtime_nsec_, stat.mtime_nsec_)) {
|
||||||
VLOG(file_loader) << "File \"" << location.path_ << "\" was modified: old mtime = " << location.mtime_nsec_
|
VLOG(file_loader) << "File \"" << location.path_ << "\" was modified: old mtime = " << location.mtime_nsec_
|
||||||
<< ", new mtime = " << stat.mtime_nsec_;
|
<< ", new mtime = " << stat.mtime_nsec_;
|
||||||
return Status::Error(400, PSLICE() << "File \"" << location.path_ << "\" was modified");
|
return Status::Error(400, PSLICE() << "File \"" << utf8_encode(location.path_) << "\" was modified");
|
||||||
}
|
}
|
||||||
if (skip_file_size_checks) {
|
if (skip_file_size_checks) {
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto get_file_size_error = [&](Slice reason) {
|
||||||
|
return Status::Error(400, PSLICE() << "File \"" << utf8_encode(location.path_) << "\" of size " << size
|
||||||
|
<< " bytes is too big" << reason);
|
||||||
|
};
|
||||||
if ((location.file_type_ == FileType::Thumbnail || location.file_type_ == FileType::EncryptedThumbnail) &&
|
if ((location.file_type_ == FileType::Thumbnail || location.file_type_ == FileType::EncryptedThumbnail) &&
|
||||||
size > MAX_THUMBNAIL_SIZE && !begins_with(PathView(location.path_).file_name(), "map")) {
|
size > MAX_THUMBNAIL_SIZE && !begins_with(PathView(location.path_).file_name(), "map")) {
|
||||||
return Status::Error(400, PSLICE() << "File \"" << location.path_ << "\" is too big for a thumbnail "
|
return get_file_size_error(" for a thumbnail");
|
||||||
<< tag("size", format::as_size(size)));
|
|
||||||
}
|
}
|
||||||
if (size > MAX_FILE_SIZE) {
|
if (size > MAX_FILE_SIZE) {
|
||||||
return Status::Error(400, PSLICE() << "File \"" << location.path_ << "\" of size " << size << " bytes is too big");
|
return get_file_size_error("");
|
||||||
}
|
}
|
||||||
if (location.file_type_ == FileType::Photo && size > MAX_PHOTO_SIZE) {
|
if (location.file_type_ == FileType::Photo && size > MAX_PHOTO_SIZE) {
|
||||||
return Status::Error(
|
return get_file_size_error(" for a photo");
|
||||||
400, PSLICE() << "File \"" << location.path_ << "\" of size " << size << " bytes is too big for a photo");
|
|
||||||
}
|
}
|
||||||
if (location.file_type_ == FileType::VideoNote &&
|
if (location.file_type_ == FileType::VideoNote &&
|
||||||
size > G()->shared_config().get_option_integer("video_note_size_max", DEFAULT_VIDEO_NOTE_SIZE_MAX)) {
|
size > G()->shared_config().get_option_integer("video_note_size_max", DEFAULT_VIDEO_NOTE_SIZE_MAX)) {
|
||||||
return Status::Error(
|
return get_file_size_error(" for a video note");
|
||||||
400, PSLICE() << "File \"" << location.path_ << "\" of size " << size << " bytes is too big for a video note");
|
|
||||||
}
|
}
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ TDJSON_EXPORT const char *td_execute(const char *request);
|
|||||||
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
|
* \param verbosity_level Log verbosity level with which the message was added (-1 - 1024).
|
||||||
* If 0, then TDLib will crash as soon as the callback returns.
|
* If 0, then TDLib will crash as soon as the callback returns.
|
||||||
* None of the TDLib methods can be called from the callback.
|
* None of the TDLib methods can be called from the callback.
|
||||||
* \param message Null-terminated string with the logged message.
|
* \param message Null-terminated string with the logged message. The string isn't guaranteed to be encoded in UTF-8.
|
||||||
*/
|
*/
|
||||||
typedef void (*td_log_message_callback_ptr)(int verbosity_level, const char *message);
|
typedef void (*td_log_message_callback_ptr)(int verbosity_level, const char *message);
|
||||||
|
|
||||||
|
@ -1113,7 +1113,10 @@ Status create_openssl_error(int code, Slice message) {
|
|||||||
|
|
||||||
void clear_openssl_errors(Slice source) {
|
void clear_openssl_errors(Slice source) {
|
||||||
if (ERR_peek_error() != 0) {
|
if (ERR_peek_error() != 0) {
|
||||||
LOG(ERROR) << source << ": " << create_openssl_error(0, "Unprocessed OPENSSL_ERROR");
|
auto error = create_openssl_error(0, "Unprocessed OPENSSL_ERROR");
|
||||||
|
if (!ends_with(error.message(), ":def_load:system lib}]")) {
|
||||||
|
LOG(ERROR) << source << ": " << error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if TD_PORT_WINDOWS
|
#if TD_PORT_WINDOWS
|
||||||
WSASetLastError(0);
|
WSASetLastError(0);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "td/utils/utf8.h"
|
#include "td/utils/utf8.h"
|
||||||
|
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
|
#include "td/utils/misc.h"
|
||||||
|
#include "td/utils/SliceBuilder.h"
|
||||||
#include "td/utils/unicode.h"
|
#include "td/utils/unicode.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
@ -121,4 +123,11 @@ string utf8_to_lower(Slice str) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string utf8_encode(CSlice data) {
|
||||||
|
if (check_utf8(data)) {
|
||||||
|
return data.str();
|
||||||
|
}
|
||||||
|
return PSTRING() << "url_decode(" << url_encode(data) << ')';
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -118,4 +118,7 @@ T utf8_utf16_substr(T str, size_t offset, size_t length) {
|
|||||||
/// Returns UTF-8 string converted to lower case.
|
/// Returns UTF-8 string converted to lower case.
|
||||||
string utf8_to_lower(Slice str);
|
string utf8_to_lower(Slice str);
|
||||||
|
|
||||||
|
/// Returns valid UTF-8 representation of the string.
|
||||||
|
string utf8_encode(CSlice data);
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
Loading…
x
Reference in New Issue
Block a user