Merge remote-tracking branch 'td/master'

This commit is contained in:
Andrea Cavalli 2022-07-03 23:48:22 +02:00
commit 277513ce18
38 changed files with 373 additions and 348 deletions

View File

@ -2989,7 +2989,7 @@ premiumFeatureAppIcons = PremiumFeature;
premiumLimit type:PremiumLimitType default_value:int32 premium_value:int32 = PremiumLimit;
//@description Contains information about features, available to Premium users @features The list of available features @limits The list of limits, increased for Premium users
//@payment_link An internal link to be opened to pay for Telegram Premium if store payment isn't possible; may be null if direct payment isn't available. If the link has type internalLinkTypeBotStart, then sendBotStartMessage must be called automatically
//@payment_link An internal link to be opened to pay for Telegram Premium if store payment isn't possible; may be null if direct payment isn't available
premiumFeatures features:vector<PremiumFeature> limits:vector<premiumLimit> payment_link:InternalLinkType = PremiumFeatures;
@ -3611,7 +3611,8 @@ internalLinkTypeBackground background_name:string = InternalLinkType;
//@description The link is a link to a chat with a Telegram bot. Call searchPublicChat with the given bot username, check that the user is a bot, show START button in the chat with the bot,
//-and then call sendBotStartMessage with the given start parameter after the button is pressed
//@bot_username Username of the bot @start_parameter The parameter to be passed to sendBotStartMessage
internalLinkTypeBotStart bot_username:string start_parameter:string = InternalLinkType;
//@autostart True, if sendBotStartMessage must be called automatically without showing the START button
internalLinkTypeBotStart bot_username:string start_parameter:string autostart:Bool = InternalLinkType;
//@description The link is a link to a Telegram bot, which is supposed to be added to a group chat. Call searchPublicChat with the given bot username, check that the user is a bot and can be added to groups,
//-ask the current user to select a basic group or a supergroup chat to add the bot to, taking into account that bots can be added to a public supergroup only by administrators of the supergroup.

View File

@ -720,7 +720,7 @@ void AnimationsManager::add_saved_animation_impl(FileId animation_id, bool add_o
return promise.set_error(Status::Error(400, "Animation file not found"));
}
LOG(INFO) << "Add saved animation " << animation_id << " with main file " << file_view.file_id();
LOG(INFO) << "Add saved animation " << animation_id << " with main file " << file_view.get_main_file_id();
if (!are_saved_animations_loaded_) {
load_saved_animations(
PromiseCreator::lambda([animation_id, add_on_server, promise = std::move(promise)](Result<> result) mutable {
@ -801,7 +801,11 @@ void AnimationsManager::remove_saved_animation(const tl_object_ptr<td_api::Input
}
FileId file_id = r_file_id.ok();
if (!td::remove(saved_animation_ids_, file_id)) {
auto is_equal = [animation_id = file_id](FileId file_id) {
return file_id == animation_id ||
(file_id.get_remote() == animation_id.get_remote() && animation_id.get_remote() != 0);
};
if (!td::remove_if(saved_animation_ids_, is_equal)) {
return promise.set_value(Unit());
}

View File

@ -857,7 +857,7 @@ void BackgroundManager::do_upload_background_file(FileId file_id, const Backgrou
Promise<Unit> &&promise) {
if (input_file == nullptr) {
FileView file_view = td_->file_manager_->get_file_view(file_id);
file_id = file_view.file_id();
file_id = file_view.get_main_file_id();
auto it = file_id_to_background_id_.find(file_id);
if (it != file_id_to_background_id_.end()) {
set_background(it->second, type, for_dark_theme, std::move(promise));
@ -1022,8 +1022,9 @@ void BackgroundManager::add_background(const Background &background, bool replac
if (result->file_id != background.file_id) {
if (result->file_id.is_valid()) {
if (!background.file_id.is_valid() || td_->file_manager_->get_file_view(result->file_id).file_id() !=
td_->file_manager_->get_file_view(background.file_id).file_id()) {
if (!background.file_id.is_valid() ||
td_->file_manager_->get_file_view(result->file_id).get_main_file_id() !=
td_->file_manager_->get_file_view(background.file_id).get_main_file_id()) {
LOG(ERROR) << "Background file has changed from " << result->file_id << " to " << background.file_id;
file_id_to_background_id_.erase(result->file_id);
result->file_source_id = FileSourceId();

View File

@ -39,7 +39,7 @@
#include "td/actor/actor.h"
#include "td/actor/MultiPromise.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -74,7 +74,7 @@ FileView DownloadManagerCallback::get_sync_file_view(FileId file_id) {
td_api::object_ptr<td_api::fileDownload> DownloadManagerCallback::get_file_download_object(
FileId file_id, FileSourceId file_source_id, int32 add_date, int32 complete_date, bool is_paused) {
return td_api::make_object<td_api::fileDownload>(td_->file_manager_->get_file_view(file_id).file_id().get(),
return td_api::make_object<td_api::fileDownload>(td_->file_manager_->get_file_view(file_id).get_main_file_id().get(),
td_->file_reference_manager_->get_message_object(file_source_id),
add_date, complete_date, is_paused);
}

View File

@ -365,7 +365,7 @@ FileReferenceManager::Destination FileReferenceManager::on_query_result(Destinat
}
void FileReferenceManager::repair_file_reference(NodeId node_id, Promise<> promise) {
auto main_file_id = G()->td().get_actor_unsafe()->file_manager_->get_file_view(node_id).file_id();
auto main_file_id = G()->td().get_actor_unsafe()->file_manager_->get_file_view(node_id).get_main_file_id();
VLOG(file_references) << "Repair file reference for file " << node_id << "/" << main_file_id;
node_id = main_file_id;
CHECK(node_id.is_valid());

View File

@ -17,7 +17,7 @@
#include "td/telegram/UserId.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -19,7 +19,7 @@
#include "td/actor/actor.h"
#include "td/actor/MultiPromise.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -250,14 +250,20 @@ class LinkManager::InternalLinkBotAddToChannel final : public InternalLink {
class LinkManager::InternalLinkBotStart final : public InternalLink {
string bot_username_;
string start_parameter_;
bool autostart_;
td_api::object_ptr<td_api::InternalLinkType> get_internal_link_type_object() const final {
return td_api::make_object<td_api::internalLinkTypeBotStart>(bot_username_, start_parameter_);
bool autostart = autostart_;
if (Scheduler::context() != nullptr &&
bot_username_ == G()->shared_config().get_option_string("premium_bot_username")) {
autostart = true;
}
return td_api::make_object<td_api::internalLinkTypeBotStart>(bot_username_, start_parameter_, autostart);
}
public:
InternalLinkBotStart(string bot_username, string start_parameter)
: bot_username_(std::move(bot_username)), start_parameter_(std::move(start_parameter)) {
InternalLinkBotStart(string bot_username, string start_parameter, bool autostart)
: bot_username_(std::move(bot_username)), start_parameter_(std::move(start_parameter)), autostart_(autostart) {
}
};
@ -918,15 +924,15 @@ LinkManager::LinkInfo LinkManager::get_link_info(Slice link) {
return result;
}
unique_ptr<LinkManager::InternalLink> LinkManager::parse_internal_link(Slice link) {
unique_ptr<LinkManager::InternalLink> LinkManager::parse_internal_link(Slice link, bool is_trusted) {
auto info = get_link_info(link);
if (!info.is_internal_) {
return nullptr;
}
if (info.is_tg_) {
return parse_tg_link_query(info.query_);
return parse_tg_link_query(info.query_, is_trusted);
} else {
return parse_t_me_link_query(info.query_);
return parse_t_me_link_query(info.query_, is_trusted);
}
}
@ -959,7 +965,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const CopyArg &copy_arg
}
} // namespace
unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice query) {
unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice query, bool is_trusted) {
const auto url_query = parse_url_query(query);
const auto &path = url_query.path_;
@ -997,7 +1003,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
}
if (arg.first == "start" && is_valid_start_parameter(arg.second)) {
// resolve?domain=<bot_username>&start=<parameter>
return td::make_unique<InternalLinkBotStart>(std::move(username), arg.second);
return td::make_unique<InternalLinkBotStart>(std::move(username), arg.second, is_trusted);
}
if (arg.first == "startgroup" && is_valid_start_parameter(arg.second)) {
// resolve?domain=<bot_username>&startgroup=<parameter>
@ -1178,7 +1184,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_tg_link_query(Slice que
return nullptr;
}
unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice query) {
unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice query, bool is_trusted) {
CHECK(query[0] == '/');
const auto url_query = parse_url_query(query);
const auto &path = url_query.path_;
@ -1324,7 +1330,7 @@ unique_ptr<LinkManager::InternalLink> LinkManager::parse_t_me_link_query(Slice q
}
if (arg.first == "start" && is_valid_start_parameter(arg.second)) {
// /<bot_username>?start=<parameter>
return td::make_unique<InternalLinkBotStart>(std::move(username), arg.second);
return td::make_unique<InternalLinkBotStart>(std::move(username), arg.second, is_trusted);
}
if (arg.first == "startgroup" && is_valid_start_parameter(arg.second)) {
// /<bot_username>?startgroup=<parameter>

View File

@ -53,7 +53,7 @@ class LinkManager final : public Actor {
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
static unique_ptr<InternalLink> parse_internal_link(Slice link);
static unique_ptr<InternalLink> parse_internal_link(Slice link, bool is_trusted = false);
void update_autologin_domains(string autologin_token, vector<string> autologin_domains,
vector<string> url_auth_domains);
@ -124,9 +124,9 @@ class LinkManager final : public Actor {
// returns information about the link
static LinkInfo get_link_info(Slice link);
static unique_ptr<InternalLink> parse_tg_link_query(Slice query);
static unique_ptr<InternalLink> parse_tg_link_query(Slice query, bool is_trusted);
static unique_ptr<InternalLink> parse_t_me_link_query(Slice query);
static unique_ptr<InternalLink> parse_t_me_link_query(Slice query, bool is_trusted);
static unique_ptr<InternalLink> get_internal_link_passport(Slice query,
const vector<std::pair<string, string>> &args);

View File

@ -4032,27 +4032,27 @@ static unique_ptr<MessageContent> get_document_message_content(Td *td, tl_object
unique_ptr<MessageContent> get_secret_message_content(
Td *td, string message_text, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::DecryptedMessageMedia> &&media,
tl_object_ptr<secret_api::DecryptedMessageMedia> &&media_ptr,
vector<tl_object_ptr<secret_api::MessageEntity>> &&secret_entities, DialogId owner_dialog_id,
MultiPromiseActor &load_data_multipromise, bool is_premium) {
int32 constructor_id = media == nullptr ? secret_api::decryptedMessageMediaEmpty::ID : media->get_id();
int32 constructor_id = media_ptr == nullptr ? secret_api::decryptedMessageMediaEmpty::ID : media_ptr->get_id();
auto caption = [&] {
switch (constructor_id) {
case secret_api::decryptedMessageMediaVideo::ID: {
auto video = static_cast<secret_api::decryptedMessageMediaVideo *>(media.get());
return std::move(video->caption_);
auto media = static_cast<secret_api::decryptedMessageMediaVideo *>(media_ptr.get());
return std::move(media->caption_);
}
case secret_api::decryptedMessageMediaPhoto::ID: {
auto photo = static_cast<secret_api::decryptedMessageMediaPhoto *>(media.get());
return std::move(photo->caption_);
auto media = static_cast<secret_api::decryptedMessageMediaPhoto *>(media_ptr.get());
return std::move(media->caption_);
}
case secret_api::decryptedMessageMediaDocument46::ID: {
auto document = static_cast<secret_api::decryptedMessageMediaDocument46 *>(media.get());
return std::move(document->caption_);
auto media = static_cast<secret_api::decryptedMessageMediaDocument46 *>(media_ptr.get());
return std::move(media->caption_);
}
case secret_api::decryptedMessageMediaDocument::ID: {
auto document = static_cast<secret_api::decryptedMessageMediaDocument *>(media.get());
return std::move(document->caption_);
auto media = static_cast<secret_api::decryptedMessageMediaDocument *>(media_ptr.get());
return std::move(media->caption_);
}
default:
return string();
@ -4082,22 +4082,22 @@ unique_ptr<MessageContent> get_secret_message_content(
// support of old layer and old constructions
switch (constructor_id) {
case secret_api::decryptedMessageMediaDocument46::ID: {
auto document = move_tl_object_as<secret_api::decryptedMessageMediaDocument46>(media);
media = make_tl_object<secret_api::decryptedMessageMediaDocument>(
std::move(document->thumb_), document->thumb_w_, document->thumb_h_, document->mime_type_, document->size_,
std::move(document->key_), std::move(document->iv_), std::move(document->attributes_), string());
auto media = move_tl_object_as<secret_api::decryptedMessageMediaDocument46>(media_ptr);
media_ptr = make_tl_object<secret_api::decryptedMessageMediaDocument>(
std::move(media->thumb_), media->thumb_w_, media->thumb_h_, media->mime_type_, media->size_,
std::move(media->key_), std::move(media->iv_), std::move(media->attributes_), string());
constructor_id = secret_api::decryptedMessageMediaDocument::ID;
break;
}
case secret_api::decryptedMessageMediaVideo::ID: {
auto video = move_tl_object_as<secret_api::decryptedMessageMediaVideo>(media);
auto media = move_tl_object_as<secret_api::decryptedMessageMediaVideo>(media_ptr);
vector<tl_object_ptr<secret_api::DocumentAttribute>> attributes;
attributes.emplace_back(
make_tl_object<secret_api::documentAttributeVideo>(video->duration_, video->w_, video->h_));
media = make_tl_object<secret_api::decryptedMessageMediaDocument>(
std::move(video->thumb_), video->thumb_w_, video->thumb_h_, video->mime_type_, video->size_,
std::move(video->key_), std::move(video->iv_), std::move(attributes), string());
make_tl_object<secret_api::documentAttributeVideo>(media->duration_, media->w_, media->h_));
media_ptr = make_tl_object<secret_api::decryptedMessageMediaDocument>(
std::move(media->thumb_), media->thumb_w_, media->thumb_h_, media->mime_type_, media->size_,
std::move(media->key_), std::move(media->iv_), std::move(attributes), string());
constructor_id = secret_api::decryptedMessageMediaDocument::ID;
break;
@ -4115,9 +4115,9 @@ unique_ptr<MessageContent> get_secret_message_content(
is_media_empty = true;
break;
case secret_api::decryptedMessageMediaGeoPoint::ID: {
auto message_geo_point = move_tl_object_as<secret_api::decryptedMessageMediaGeoPoint>(media);
auto media = move_tl_object_as<secret_api::decryptedMessageMediaGeoPoint>(media_ptr);
auto m = make_unique<MessageLocation>(Location(message_geo_point));
auto m = make_unique<MessageLocation>(Location(media));
if (m->location.empty()) {
is_media_empty = true;
break;
@ -4126,25 +4126,24 @@ unique_ptr<MessageContent> get_secret_message_content(
return std::move(m);
}
case secret_api::decryptedMessageMediaVenue::ID: {
auto message_venue = move_tl_object_as<secret_api::decryptedMessageMediaVenue>(media);
auto media = move_tl_object_as<secret_api::decryptedMessageMediaVenue>(media_ptr);
if (!clean_input_string(message_venue->title_)) {
message_venue->title_.clear();
if (!clean_input_string(media->title_)) {
media->title_.clear();
}
if (!clean_input_string(message_venue->address_)) {
message_venue->address_.clear();
if (!clean_input_string(media->address_)) {
media->address_.clear();
}
if (!clean_input_string(message_venue->provider_)) {
message_venue->provider_.clear();
if (!clean_input_string(media->provider_)) {
media->provider_.clear();
}
if (!clean_input_string(message_venue->venue_id_)) {
message_venue->venue_id_.clear();
if (!clean_input_string(media->venue_id_)) {
media->venue_id_.clear();
}
auto m = make_unique<MessageVenue>(Venue(Location(message_venue->lat_, message_venue->long_, 0.0, 0),
std::move(message_venue->title_), std::move(message_venue->address_),
std::move(message_venue->provider_), std::move(message_venue->venue_id_),
string()));
auto m = make_unique<MessageVenue>(Venue(Location(media->lat_, media->long_, 0.0, 0), std::move(media->title_),
std::move(media->address_), std::move(media->provider_),
std::move(media->venue_id_), string()));
if (m->venue.empty()) {
is_media_empty = true;
break;
@ -4153,26 +4152,25 @@ unique_ptr<MessageContent> get_secret_message_content(
return std::move(m);
}
case secret_api::decryptedMessageMediaContact::ID: {
auto message_contact = move_tl_object_as<secret_api::decryptedMessageMediaContact>(media);
if (!clean_input_string(message_contact->phone_number_)) {
message_contact->phone_number_.clear();
auto media = move_tl_object_as<secret_api::decryptedMessageMediaContact>(media_ptr);
if (!clean_input_string(media->phone_number_)) {
media->phone_number_.clear();
}
if (!clean_input_string(message_contact->first_name_)) {
message_contact->first_name_.clear();
if (!clean_input_string(media->first_name_)) {
media->first_name_.clear();
}
if (!clean_input_string(message_contact->last_name_)) {
message_contact->last_name_.clear();
if (!clean_input_string(media->last_name_)) {
media->last_name_.clear();
}
return make_unique<MessageContact>(Contact(std::move(message_contact->phone_number_),
std::move(message_contact->first_name_),
std::move(message_contact->last_name_), string(), UserId()));
return make_unique<MessageContact>(Contact(std::move(media->phone_number_), std::move(media->first_name_),
std::move(media->last_name_), string(), UserId()));
}
case secret_api::decryptedMessageMediaWebPage::ID: {
auto media_web_page = move_tl_object_as<secret_api::decryptedMessageMediaWebPage>(media);
if (!clean_input_string(media_web_page->url_)) {
media_web_page->url_.clear();
auto media = move_tl_object_as<secret_api::decryptedMessageMediaWebPage>(media_ptr);
if (!clean_input_string(media->url_)) {
media->url_.clear();
}
auto r_http_url = parse_url(media_web_page->url_);
auto r_http_url = parse_url(media->url_);
if (r_http_url.is_error()) {
is_media_empty = true;
break;
@ -4192,9 +4190,8 @@ unique_ptr<MessageContent> get_secret_message_content(
return std::move(result);
}
case secret_api::decryptedMessageMediaExternalDocument::ID: {
auto external_document = move_tl_object_as<secret_api::decryptedMessageMediaExternalDocument>(media);
auto document = secret_to_telegram_document(*external_document);
return get_document_message_content(td, std::move(document), owner_dialog_id,
auto media = move_tl_object_as<secret_api::decryptedMessageMediaExternalDocument>(media_ptr);
return get_document_message_content(td, secret_to_telegram_document(*media), owner_dialog_id,
FormattedText{std::move(message_text), std::move(entities)}, false,
is_premium, &load_data_multipromise);
}
@ -4210,17 +4207,17 @@ unique_ptr<MessageContent> get_secret_message_content(
}
switch (constructor_id) {
case secret_api::decryptedMessageMediaPhoto::ID: {
auto message_photo = move_tl_object_as<secret_api::decryptedMessageMediaPhoto>(media);
auto media = move_tl_object_as<secret_api::decryptedMessageMediaPhoto>(media_ptr);
return make_unique<MessagePhoto>(
get_encrypted_file_photo(td->file_manager_.get(), std::move(file), std::move(message_photo), owner_dialog_id),
get_encrypted_file_photo(td->file_manager_.get(), std::move(file), std::move(media), owner_dialog_id),
FormattedText{std::move(message_text), std::move(entities)});
}
case secret_api::decryptedMessageMediaDocument::ID: {
auto message_document = move_tl_object_as<secret_api::decryptedMessageMediaDocument>(media);
if (!clean_input_string(message_document->mime_type_)) {
message_document->mime_type_.clear();
auto media = move_tl_object_as<secret_api::decryptedMessageMediaDocument>(media_ptr);
if (!clean_input_string(media->mime_type_)) {
media->mime_type_.clear();
}
auto attributes = secret_to_telegram(message_document->attributes_);
auto attributes = secret_to_telegram(media->attributes_);
for (auto &attribute : attributes) {
CHECK(attribute != nullptr);
if (attribute->get_id() == telegram_api::documentAttributeSticker::ID) {
@ -4232,32 +4229,32 @@ unique_ptr<MessageContent> get_secret_message_content(
}
}
message_document->attributes_.clear();
media->attributes_.clear();
auto document = td->documents_manager_->on_get_document(
{std::move(file), std::move(message_document), std::move(attributes)}, owner_dialog_id);
{std::move(file), std::move(media), std::move(attributes)}, owner_dialog_id);
return get_document_message_content(std::move(document), {std::move(message_text), std::move(entities)}, false,
false);
}
default:
LOG(ERROR) << "Unsupported: " << to_string(media);
LOG(ERROR) << "Unsupported: " << to_string(media_ptr);
return make_unique<MessageUnsupported>();
}
}
unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
tl_object_ptr<telegram_api::MessageMedia> &&media,
tl_object_ptr<telegram_api::MessageMedia> &&media_ptr,
DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id,
int32 *ttl, bool *disable_web_page_preview) {
if (!td->auth_manager_->was_authorized() && !G()->close_flag() && media != nullptr &&
media->get_id() != telegram_api::messageMediaEmpty::ID) {
LOG(ERROR) << "Receive without authorization " << to_string(media);
media = nullptr;
if (!td->auth_manager_->was_authorized() && !G()->close_flag() && media_ptr != nullptr &&
media_ptr->get_id() != telegram_api::messageMediaEmpty::ID) {
LOG(ERROR) << "Receive without authorization " << to_string(media_ptr);
media_ptr = nullptr;
}
if (disable_web_page_preview != nullptr) {
*disable_web_page_preview = false;
}
int32 constructor_id = media == nullptr ? telegram_api::messageMediaEmpty::ID : media->get_id();
int32 constructor_id = media_ptr == nullptr ? telegram_api::messageMediaEmpty::ID : media_ptr->get_id();
switch (constructor_id) {
case telegram_api::messageMediaEmpty::ID:
if (message.text.empty()) {
@ -4268,30 +4265,30 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
}
return make_unique<MessageText>(std::move(message), WebPageId());
case telegram_api::messageMediaPhoto::ID: {
auto message_photo = move_tl_object_as<telegram_api::messageMediaPhoto>(media);
if (message_photo->photo_ == nullptr) {
if ((message_photo->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) == 0) {
LOG(ERROR) << "Receive messageMediaPhoto without photo and TTL: " << oneline(to_string(message_photo));
auto media = move_tl_object_as<telegram_api::messageMediaPhoto>(media_ptr);
if (media->photo_ == nullptr) {
if ((media->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) == 0) {
LOG(ERROR) << "Receive messageMediaPhoto without photo and TTL: " << oneline(to_string(media));
break;
}
return make_unique<MessageExpiredPhoto>();
}
auto photo = get_photo(td->file_manager_.get(), std::move(message_photo->photo_), owner_dialog_id);
auto photo = get_photo(td->file_manager_.get(), std::move(media->photo_), owner_dialog_id);
if (photo.is_empty()) {
return make_unique<MessageExpiredPhoto>();
}
if (ttl != nullptr && (message_photo->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) != 0) {
*ttl = message_photo->ttl_seconds_;
if (ttl != nullptr && (media->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) != 0) {
*ttl = media->ttl_seconds_;
}
return make_unique<MessagePhoto>(std::move(photo), std::move(message));
}
case telegram_api::messageMediaDice::ID: {
auto message_dice = move_tl_object_as<telegram_api::messageMediaDice>(media);
auto media = move_tl_object_as<telegram_api::messageMediaDice>(media_ptr);
auto m = td::make_unique<MessageDice>(message_dice->emoticon_, message_dice->value_);
auto m = td::make_unique<MessageDice>(media->emoticon_, media->value_);
if (!m->is_valid()) {
break;
}
@ -4299,9 +4296,9 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
return std::move(m);
}
case telegram_api::messageMediaGeo::ID: {
auto message_geo_point = move_tl_object_as<telegram_api::messageMediaGeo>(media);
auto media = move_tl_object_as<telegram_api::messageMediaGeo>(media_ptr);
auto m = make_unique<MessageLocation>(Location(message_geo_point->geo_));
auto m = make_unique<MessageLocation>(Location(media->geo_));
if (m->location.empty()) {
break;
}
@ -4309,27 +4306,25 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
return std::move(m);
}
case telegram_api::messageMediaGeoLive::ID: {
auto message_geo_point_live = move_tl_object_as<telegram_api::messageMediaGeoLive>(media);
auto location = Location(message_geo_point_live->geo_);
auto media = move_tl_object_as<telegram_api::messageMediaGeoLive>(media_ptr);
auto location = Location(media->geo_);
if (location.empty()) {
break;
}
int32 period = message_geo_point_live->period_;
int32 period = media->period_;
if (period <= 0) {
LOG(ERROR) << "Receive wrong live location period = " << period;
return make_unique<MessageLocation>(std::move(location));
}
return make_unique<MessageLiveLocation>(std::move(location), period, message_geo_point_live->heading_,
message_geo_point_live->proximity_notification_radius_);
return make_unique<MessageLiveLocation>(std::move(location), period, media->heading_,
media->proximity_notification_radius_);
}
case telegram_api::messageMediaVenue::ID: {
auto message_venue = move_tl_object_as<telegram_api::messageMediaVenue>(media);
auto m =
make_unique<MessageVenue>(Venue(message_venue->geo_, std::move(message_venue->title_),
std::move(message_venue->address_), std::move(message_venue->provider_),
std::move(message_venue->venue_id_), std::move(message_venue->venue_type_)));
auto media = move_tl_object_as<telegram_api::messageMediaVenue>(media_ptr);
auto m = make_unique<MessageVenue>(Venue(media->geo_, std::move(media->title_), std::move(media->address_),
std::move(media->provider_), std::move(media->venue_id_),
std::move(media->venue_type_)));
if (m->venue.empty()) {
break;
}
@ -4337,46 +4332,43 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
return std::move(m);
}
case telegram_api::messageMediaContact::ID: {
auto message_contact = move_tl_object_as<telegram_api::messageMediaContact>(media);
if (message_contact->user_id_ != 0) {
td->contacts_manager_->get_user_id_object(UserId(message_contact->user_id_),
auto media = move_tl_object_as<telegram_api::messageMediaContact>(media_ptr);
if (media->user_id_ != 0) {
td->contacts_manager_->get_user_id_object(UserId(media->user_id_),
"MessageMediaContact"); // to ensure updateUser
}
return make_unique<MessageContact>(
Contact(std::move(message_contact->phone_number_), std::move(message_contact->first_name_),
std::move(message_contact->last_name_), std::move(message_contact->vcard_),
UserId(message_contact->user_id_)));
return make_unique<MessageContact>(Contact(std::move(media->phone_number_), std::move(media->first_name_),
std::move(media->last_name_), std::move(media->vcard_),
UserId(media->user_id_)));
}
case telegram_api::messageMediaDocument::ID: {
auto message_document = move_tl_object_as<telegram_api::messageMediaDocument>(media);
if (message_document->document_ == nullptr) {
if ((message_document->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) == 0) {
LOG(ERROR) << "Receive messageMediaDocument without document and TTL: "
<< oneline(to_string(message_document));
auto media = move_tl_object_as<telegram_api::messageMediaDocument>(media_ptr);
if (media->document_ == nullptr) {
if ((media->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) == 0) {
LOG(ERROR) << "Receive messageMediaDocument without document and TTL: " << oneline(to_string(media));
break;
}
return make_unique<MessageExpiredVideo>();
}
auto document_ptr = std::move(message_document->document_);
auto document_ptr = std::move(media->document_);
int32 document_id = document_ptr->get_id();
if (document_id == telegram_api::documentEmpty::ID) {
break;
}
CHECK(document_id == telegram_api::document::ID);
if (ttl != nullptr && (message_document->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) != 0) {
*ttl = message_document->ttl_seconds_;
if (ttl != nullptr && (media->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) != 0) {
*ttl = media->ttl_seconds_;
}
return get_document_message_content(td, move_tl_object_as<telegram_api::document>(document_ptr), owner_dialog_id,
std::move(message), is_content_read, !message_document->nopremium_, nullptr);
std::move(message), is_content_read, !media->nopremium_, nullptr);
}
case telegram_api::messageMediaGame::ID: {
auto message_game = move_tl_object_as<telegram_api::messageMediaGame>(media);
auto media = move_tl_object_as<telegram_api::messageMediaGame>(media_ptr);
auto m =
make_unique<MessageGame>(Game(td, via_bot_user_id, std::move(message_game->game_), message, owner_dialog_id));
auto m = make_unique<MessageGame>(Game(td, via_bot_user_id, std::move(media->game_), message, owner_dialog_id));
if (m->game.is_empty()) {
break;
}
@ -4384,19 +4376,19 @@ unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message,
}
case telegram_api::messageMediaInvoice::ID:
return td::make_unique<MessageInvoice>(
get_input_invoice(move_tl_object_as<telegram_api::messageMediaInvoice>(media), td, owner_dialog_id));
get_input_invoice(move_tl_object_as<telegram_api::messageMediaInvoice>(media_ptr), td, owner_dialog_id));
case telegram_api::messageMediaWebPage::ID: {
auto media_web_page = move_tl_object_as<telegram_api::messageMediaWebPage>(media);
auto media = move_tl_object_as<telegram_api::messageMediaWebPage>(media_ptr);
if (disable_web_page_preview != nullptr) {
*disable_web_page_preview = (media_web_page->webpage_ == nullptr);
*disable_web_page_preview = (media->webpage_ == nullptr);
}
auto web_page_id = td->web_pages_manager_->on_get_web_page(std::move(media_web_page->webpage_), owner_dialog_id);
auto web_page_id = td->web_pages_manager_->on_get_web_page(std::move(media->webpage_), owner_dialog_id);
return make_unique<MessageText>(std::move(message), web_page_id);
}
case telegram_api::messageMediaPoll::ID: {
auto media_poll = move_tl_object_as<telegram_api::messageMediaPoll>(media);
auto poll_id = td->poll_manager_->on_get_poll(PollId(), std::move(media_poll->poll_),
std::move(media_poll->results_), "messageMediaPoll");
auto media = move_tl_object_as<telegram_api::messageMediaPoll>(media_ptr);
auto poll_id = td->poll_manager_->on_get_poll(PollId(), std::move(media->poll_), std::move(media->results_),
"messageMediaPoll");
if (!poll_id.is_valid()) {
break;
}
@ -4668,21 +4660,21 @@ unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const
return nullptr;
}
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action,
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action_ptr,
DialogId owner_dialog_id, DialogId reply_in_dialog_id,
MessageId reply_to_message_id) {
CHECK(action != nullptr);
CHECK(action_ptr != nullptr);
switch (action->get_id()) {
switch (action_ptr->get_id()) {
case telegram_api::messageActionEmpty::ID:
LOG(ERROR) << "Receive empty message action in " << owner_dialog_id;
break;
case telegram_api::messageActionChatCreate::ID: {
auto chat_create = move_tl_object_as<telegram_api::messageActionChatCreate>(action);
auto action = move_tl_object_as<telegram_api::messageActionChatCreate>(action_ptr);
vector<UserId> participant_user_ids;
participant_user_ids.reserve(chat_create->users_.size());
for (auto &user : chat_create->users_) {
participant_user_ids.reserve(action->users_.size());
for (auto &user : action->users_) {
UserId user_id(user);
if (user_id.is_valid()) {
participant_user_ids.push_back(user_id);
@ -4691,15 +4683,15 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
}
}
return td::make_unique<MessageChatCreate>(std::move(chat_create->title_), std::move(participant_user_ids));
return td::make_unique<MessageChatCreate>(std::move(action->title_), std::move(participant_user_ids));
}
case telegram_api::messageActionChatEditTitle::ID: {
auto chat_edit_title = move_tl_object_as<telegram_api::messageActionChatEditTitle>(action);
return td::make_unique<MessageChatChangeTitle>(std::move(chat_edit_title->title_));
auto action = move_tl_object_as<telegram_api::messageActionChatEditTitle>(action_ptr);
return td::make_unique<MessageChatChangeTitle>(std::move(action->title_));
}
case telegram_api::messageActionChatEditPhoto::ID: {
auto chat_edit_photo = move_tl_object_as<telegram_api::messageActionChatEditPhoto>(action);
auto photo = get_photo(td->file_manager_.get(), std::move(chat_edit_photo->photo_), owner_dialog_id);
auto action = move_tl_object_as<telegram_api::messageActionChatEditPhoto>(action_ptr);
auto photo = get_photo(td->file_manager_.get(), std::move(action->photo_), owner_dialog_id);
if (photo.is_empty()) {
break;
}
@ -4712,11 +4704,11 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
return make_unique<MessageChatDeleteHistory>();
}
case telegram_api::messageActionChatAddUser::ID: {
auto chat_add_user = move_tl_object_as<telegram_api::messageActionChatAddUser>(action);
auto action = move_tl_object_as<telegram_api::messageActionChatAddUser>(action_ptr);
vector<UserId> user_ids;
user_ids.reserve(chat_add_user->users_.size());
for (auto &user : chat_add_user->users_) {
user_ids.reserve(action->users_.size());
for (auto &user : action->users_) {
UserId user_id(user);
if (user_id.is_valid()) {
user_ids.push_back(user_id);
@ -4730,9 +4722,9 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
case telegram_api::messageActionChatJoinedByLink::ID:
return make_unique<MessageChatJoinedByLink>(false);
case telegram_api::messageActionChatDeleteUser::ID: {
auto chat_delete_user = move_tl_object_as<telegram_api::messageActionChatDeleteUser>(action);
auto action = move_tl_object_as<telegram_api::messageActionChatDeleteUser>(action_ptr);
UserId user_id(chat_delete_user->user_id_);
UserId user_id(action->user_id_);
if (!user_id.is_valid()) {
LOG(ERROR) << "Receive messageActionChatDeleteUser with invalid " << user_id << " in " << owner_dialog_id;
break;
@ -4741,9 +4733,9 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
return make_unique<MessageChatDeleteUser>(user_id);
}
case telegram_api::messageActionChatMigrateTo::ID: {
auto chat_migrate_to = move_tl_object_as<telegram_api::messageActionChatMigrateTo>(action);
auto action = move_tl_object_as<telegram_api::messageActionChatMigrateTo>(action_ptr);
ChannelId migrated_to_channel_id(chat_migrate_to->channel_id_);
ChannelId migrated_to_channel_id(action->channel_id_);
if (!migrated_to_channel_id.is_valid()) {
LOG(ERROR) << "Receive messageActionChatMigrateTo with invalid " << migrated_to_channel_id << " in "
<< owner_dialog_id;
@ -4753,17 +4745,16 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
return make_unique<MessageChatMigrateTo>(migrated_to_channel_id);
}
case telegram_api::messageActionChannelCreate::ID: {
auto channel_create = move_tl_object_as<telegram_api::messageActionChannelCreate>(action);
return td::make_unique<MessageChannelCreate>(std::move(channel_create->title_));
auto action = move_tl_object_as<telegram_api::messageActionChannelCreate>(action_ptr);
return td::make_unique<MessageChannelCreate>(std::move(action->title_));
}
case telegram_api::messageActionChannelMigrateFrom::ID: {
auto channel_migrate_from = move_tl_object_as<telegram_api::messageActionChannelMigrateFrom>(action);
ChatId chat_id(channel_migrate_from->chat_id_);
auto action = move_tl_object_as<telegram_api::messageActionChannelMigrateFrom>(action_ptr);
ChatId chat_id(action->chat_id_);
LOG_IF(ERROR, !chat_id.is_valid()) << "Receive messageActionChannelMigrateFrom with invalid " << chat_id << " in "
<< owner_dialog_id;
return td::make_unique<MessageChannelMigrateFrom>(std::move(channel_migrate_from->title_), chat_id);
return td::make_unique<MessageChannelMigrateFrom>(std::move(action->title_), chat_id);
}
case telegram_api::messageActionPinMessage::ID: {
if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) {
@ -4791,26 +4782,26 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
LOG(INFO) << "Receive game score with " << reply_to_message_id << " in " << owner_dialog_id;
reply_to_message_id = MessageId();
}
auto game_score = move_tl_object_as<telegram_api::messageActionGameScore>(action);
return make_unique<MessageGameScore>(reply_to_message_id, game_score->game_id_, game_score->score_);
auto action = move_tl_object_as<telegram_api::messageActionGameScore>(action_ptr);
return make_unique<MessageGameScore>(reply_to_message_id, action->game_id_, action->score_);
}
case telegram_api::messageActionPhoneCall::ID: {
auto phone_call = move_tl_object_as<telegram_api::messageActionPhoneCall>(action);
auto action = move_tl_object_as<telegram_api::messageActionPhoneCall>(action_ptr);
auto duration =
(phone_call->flags_ & telegram_api::messageActionPhoneCall::DURATION_MASK) != 0 ? phone_call->duration_ : 0;
(action->flags_ & telegram_api::messageActionPhoneCall::DURATION_MASK) != 0 ? action->duration_ : 0;
if (duration < 0) {
LOG(ERROR) << "Receive invalid " << oneline(to_string(phone_call));
LOG(ERROR) << "Receive invalid " << oneline(to_string(action));
break;
}
return make_unique<MessageCall>(phone_call->call_id_, duration, get_call_discard_reason(phone_call->reason_),
phone_call->video_);
return make_unique<MessageCall>(action->call_id_, duration, get_call_discard_reason(action->reason_),
action->video_);
}
case telegram_api::messageActionPaymentSent::ID: {
if (td->auth_manager_->is_bot()) {
LOG(ERROR) << "Receive MessageActionPaymentSent in " << owner_dialog_id;
break;
}
auto payment_sent = move_tl_object_as<telegram_api::messageActionPaymentSent>(action);
auto action = move_tl_object_as<telegram_api::messageActionPaymentSent>(action_ptr);
if (!reply_to_message_id.is_valid()) {
if (reply_to_message_id != MessageId()) {
LOG(ERROR) << "Receive succesful payment message with " << reply_to_message_id << " in " << owner_dialog_id;
@ -4819,81 +4810,81 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
reply_to_message_id = MessageId();
}
return td::make_unique<MessagePaymentSuccessful>(
reply_in_dialog_id, reply_to_message_id, std::move(payment_sent->currency_), payment_sent->total_amount_,
std::move(payment_sent->invoice_slug_), payment_sent->recurring_used_, payment_sent->recurring_init_);
reply_in_dialog_id, reply_to_message_id, std::move(action->currency_), action->total_amount_,
std::move(action->invoice_slug_), action->recurring_used_, action->recurring_init_);
}
case telegram_api::messageActionPaymentSentMe::ID: {
if (!td->auth_manager_->is_bot()) {
LOG(ERROR) << "Receive MessageActionPaymentSentMe in " << owner_dialog_id;
break;
}
auto payment_sent = move_tl_object_as<telegram_api::messageActionPaymentSentMe>(action);
auto result = td::make_unique<MessagePaymentSuccessful>(
DialogId(), MessageId(), std::move(payment_sent->currency_), payment_sent->total_amount_,
payment_sent->payload_.as_slice().str(), payment_sent->recurring_used_, payment_sent->recurring_init_);
result->shipping_option_id = std::move(payment_sent->shipping_option_id_);
result->order_info = get_order_info(std::move(payment_sent->info_));
result->telegram_payment_charge_id = std::move(payment_sent->charge_->id_);
result->provider_payment_charge_id = std::move(payment_sent->charge_->provider_charge_id_);
auto action = move_tl_object_as<telegram_api::messageActionPaymentSentMe>(action_ptr);
auto result = td::make_unique<MessagePaymentSuccessful>(DialogId(), MessageId(), std::move(action->currency_),
action->total_amount_, action->payload_.as_slice().str(),
action->recurring_used_, action->recurring_init_);
result->shipping_option_id = std::move(action->shipping_option_id_);
result->order_info = get_order_info(std::move(action->info_));
result->telegram_payment_charge_id = std::move(action->charge_->id_);
result->provider_payment_charge_id = std::move(action->charge_->provider_charge_id_);
return std::move(result);
}
case telegram_api::messageActionScreenshotTaken::ID: {
return make_unique<MessageScreenshotTaken>();
}
case telegram_api::messageActionCustomAction::ID: {
auto custom_action = move_tl_object_as<telegram_api::messageActionCustomAction>(action);
return td::make_unique<MessageCustomServiceAction>(std::move(custom_action->message_));
auto action = move_tl_object_as<telegram_api::messageActionCustomAction>(action_ptr);
return td::make_unique<MessageCustomServiceAction>(std::move(action->message_));
}
case telegram_api::messageActionBotAllowed::ID: {
auto bot_allowed = move_tl_object_as<telegram_api::messageActionBotAllowed>(action);
return td::make_unique<MessageWebsiteConnected>(std::move(bot_allowed->domain_));
auto action = move_tl_object_as<telegram_api::messageActionBotAllowed>(action_ptr);
return td::make_unique<MessageWebsiteConnected>(std::move(action->domain_));
}
case telegram_api::messageActionSecureValuesSent::ID: {
LOG_IF(ERROR, td->auth_manager_->is_bot()) << "Receive MessageActionSecureValuesSent in " << owner_dialog_id;
auto secure_values = move_tl_object_as<telegram_api::messageActionSecureValuesSent>(action);
return td::make_unique<MessagePassportDataSent>(get_secure_value_types(secure_values->types_));
auto action = move_tl_object_as<telegram_api::messageActionSecureValuesSent>(action_ptr);
return td::make_unique<MessagePassportDataSent>(get_secure_value_types(action->types_));
}
case telegram_api::messageActionSecureValuesSentMe::ID: {
LOG_IF(ERROR, !td->auth_manager_->is_bot()) << "Receive MessageActionSecureValuesSentMe in " << owner_dialog_id;
auto secure_values = move_tl_object_as<telegram_api::messageActionSecureValuesSentMe>(action);
auto action = move_tl_object_as<telegram_api::messageActionSecureValuesSentMe>(action_ptr);
return td::make_unique<MessagePassportDataReceived>(
get_encrypted_secure_values(td->file_manager_.get(), std::move(secure_values->values_)),
get_encrypted_secure_credentials(std::move(secure_values->credentials_)));
get_encrypted_secure_values(td->file_manager_.get(), std::move(action->values_)),
get_encrypted_secure_credentials(std::move(action->credentials_)));
}
case telegram_api::messageActionContactSignUp::ID: {
LOG_IF(ERROR, td->auth_manager_->is_bot()) << "Receive ContactRegistered in " << owner_dialog_id;
return td::make_unique<MessageContactRegistered>();
}
case telegram_api::messageActionGeoProximityReached::ID: {
auto geo_proximity_reached = move_tl_object_as<telegram_api::messageActionGeoProximityReached>(action);
DialogId traveler_id(geo_proximity_reached->from_id_);
DialogId watcher_id(geo_proximity_reached->to_id_);
int32 distance = geo_proximity_reached->distance_;
auto action = move_tl_object_as<telegram_api::messageActionGeoProximityReached>(action_ptr);
DialogId traveler_id(action->from_id_);
DialogId watcher_id(action->to_id_);
int32 distance = action->distance_;
if (!traveler_id.is_valid() || !watcher_id.is_valid() || distance < 0) {
LOG(ERROR) << "Receive invalid " << oneline(to_string(geo_proximity_reached));
LOG(ERROR) << "Receive invalid " << oneline(to_string(action));
break;
}
return make_unique<MessageProximityAlertTriggered>(traveler_id, watcher_id, distance);
}
case telegram_api::messageActionGroupCall::ID: {
auto group_call = move_tl_object_as<telegram_api::messageActionGroupCall>(action);
auto action = move_tl_object_as<telegram_api::messageActionGroupCall>(action_ptr);
int32 duration = -1;
if ((group_call->flags_ & telegram_api::messageActionGroupCall::DURATION_MASK) != 0) {
duration = group_call->duration_;
if ((action->flags_ & telegram_api::messageActionGroupCall::DURATION_MASK) != 0) {
duration = action->duration_;
if (duration < 0) {
LOG(ERROR) << "Receive invalid " << oneline(to_string(group_call));
LOG(ERROR) << "Receive invalid " << oneline(to_string(action));
break;
}
}
return make_unique<MessageGroupCall>(InputGroupCallId(group_call->call_), duration, -1);
return make_unique<MessageGroupCall>(InputGroupCallId(action->call_), duration, -1);
}
case telegram_api::messageActionInviteToGroupCall::ID: {
auto invite_to_group_call = move_tl_object_as<telegram_api::messageActionInviteToGroupCall>(action);
auto action = move_tl_object_as<telegram_api::messageActionInviteToGroupCall>(action_ptr);
vector<UserId> user_ids;
user_ids.reserve(invite_to_group_call->users_.size());
for (auto &user : invite_to_group_call->users_) {
user_ids.reserve(action->users_.size());
for (auto &user : action->users_) {
UserId user_id(user);
if (user_id.is_valid()) {
user_ids.push_back(user_id);
@ -4902,29 +4893,27 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
}
}
return td::make_unique<MessageInviteToGroupCall>(InputGroupCallId(invite_to_group_call->call_),
std::move(user_ids));
return td::make_unique<MessageInviteToGroupCall>(InputGroupCallId(action->call_), std::move(user_ids));
}
case telegram_api::messageActionSetMessagesTTL::ID: {
auto set_messages_ttl = move_tl_object_as<telegram_api::messageActionSetMessagesTTL>(action);
if (set_messages_ttl->period_ < 0) {
LOG(ERROR) << "Receive wrong TTL = " << set_messages_ttl->period_;
auto action = move_tl_object_as<telegram_api::messageActionSetMessagesTTL>(action_ptr);
if (action->period_ < 0) {
LOG(ERROR) << "Receive wrong TTL = " << action->period_;
break;
}
return make_unique<MessageChatSetTtl>(set_messages_ttl->period_);
return make_unique<MessageChatSetTtl>(action->period_);
}
case telegram_api::messageActionGroupCallScheduled::ID: {
auto scheduled_group_call = move_tl_object_as<telegram_api::messageActionGroupCallScheduled>(action);
if (scheduled_group_call->schedule_date_ <= 0) {
LOG(ERROR) << "Receive wrong schedule_date = " << scheduled_group_call->schedule_date_;
auto action = move_tl_object_as<telegram_api::messageActionGroupCallScheduled>(action_ptr);
if (action->schedule_date_ <= 0) {
LOG(ERROR) << "Receive wrong schedule_date = " << action->schedule_date_;
break;
}
return make_unique<MessageGroupCall>(InputGroupCallId(scheduled_group_call->call_), -1,
scheduled_group_call->schedule_date_);
return make_unique<MessageGroupCall>(InputGroupCallId(action->call_), -1, action->schedule_date_);
}
case telegram_api::messageActionSetChatTheme::ID: {
auto set_chat_theme = move_tl_object_as<telegram_api::messageActionSetChatTheme>(action);
return td::make_unique<MessageChatSetTheme>(std::move(set_chat_theme->emoticon_));
auto action = move_tl_object_as<telegram_api::messageActionSetChatTheme>(action_ptr);
return td::make_unique<MessageChatSetTheme>(std::move(action->emoticon_));
}
case telegram_api::messageActionChatJoinedByRequest::ID:
return make_unique<MessageChatJoinedByLink>(true);
@ -4933,16 +4922,16 @@ unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<tele
LOG(ERROR) << "Receive messageActionWebViewDataSent in " << owner_dialog_id;
break;
}
auto data_sent = move_tl_object_as<telegram_api::messageActionWebViewDataSent>(action);
return td::make_unique<MessageWebViewDataSent>(std::move(data_sent->text_));
auto action = move_tl_object_as<telegram_api::messageActionWebViewDataSent>(action_ptr);
return td::make_unique<MessageWebViewDataSent>(std::move(action->text_));
}
case telegram_api::messageActionWebViewDataSentMe::ID: {
if (!td->auth_manager_->is_bot()) {
LOG(ERROR) << "Receive messageActionWebViewDataSentMe in " << owner_dialog_id;
break;
}
auto data_sent = move_tl_object_as<telegram_api::messageActionWebViewDataSentMe>(action);
return td::make_unique<MessageWebViewDataReceived>(std::move(data_sent->text_), std::move(data_sent->data_));
auto action = move_tl_object_as<telegram_api::messageActionWebViewDataSentMe>(action_ptr);
return td::make_unique<MessageWebViewDataReceived>(std::move(action->text_), std::move(action->data_));
}
default:
UNREACHABLE();

View File

@ -181,12 +181,12 @@ void unregister_message_content(Td *td, const MessageContent *content, FullMessa
unique_ptr<MessageContent> get_secret_message_content(
Td *td, string message_text, unique_ptr<EncryptedFile> file,
tl_object_ptr<secret_api::DecryptedMessageMedia> &&media,
tl_object_ptr<secret_api::DecryptedMessageMedia> &&media_ptr,
vector<tl_object_ptr<secret_api::MessageEntity>> &&secret_entities, DialogId owner_dialog_id,
MultiPromiseActor &load_data_multipromise, bool is_premium);
unique_ptr<MessageContent> get_message_content(Td *td, FormattedText message_text,
tl_object_ptr<telegram_api::MessageMedia> &&media,
tl_object_ptr<telegram_api::MessageMedia> &&media_ptr,
DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id,
int32 *ttl, bool *disable_web_page_preview);
@ -195,7 +195,7 @@ enum class MessageContentDupType : int32 { Send, SendViaBot, Forward, Copy, Serv
unique_ptr<MessageContent> dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content,
MessageContentDupType type, MessageCopyOptions &&copy_options);
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action,
unique_ptr<MessageContent> get_action_message_content(Td *td, tl_object_ptr<telegram_api::MessageAction> &&action_ptr,
DialogId owner_dialog_id, DialogId reply_in_dialog_id,
MessageId reply_to_message_id);

View File

@ -20783,7 +20783,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
for (auto file_id : get_message_file_ids(m)) {
auto file_view = td_->file_manager_->get_file_view(file_id);
CHECK(!file_view.empty());
td_->download_manager_->update_file_viewed(file_view.file_id(), file_source_id);
td_->download_manager_->update_file_viewed(file_view.get_main_file_id(), file_source_id);
}
}
@ -22951,8 +22951,8 @@ void MessagesManager::remove_message_file_sources(DialogId dialog_id, const Mess
if (file_source_id.is_valid()) {
for (auto file_id : file_ids) {
auto file_view = td_->file_manager_->get_file_view(file_id);
send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, file_view.file_id(), file_source_id,
false);
send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, file_view.get_main_file_id(),
file_source_id, false);
td_->file_manager_->remove_file_source(file_id, file_source_id);
}
}
@ -22978,8 +22978,8 @@ void MessagesManager::change_message_files(DialogId dialog_id, const Message *m,
}
if (file_source_id.is_valid()) {
auto file_view = td_->file_manager_->get_file_view(file_id);
send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, file_view.file_id(), file_source_id,
false);
send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, file_view.get_main_file_id(),
file_source_id, false);
}
}
}
@ -33071,6 +33071,7 @@ void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_threa
}
if (is_dialog_action_unneeded(dialog_id)) {
LOG(INFO) << "Skip unneeded " << action << " in " << dialog_id;
return promise.set_value(Unit());
}
@ -35341,7 +35342,7 @@ bool MessagesManager::need_delete_file(FullMessageId full_message_id, FileId fil
return false;
}
auto main_file_id = td_->file_manager_->get_file_view(file_id).file_id();
auto main_file_id = td_->file_manager_->get_file_view(file_id).get_main_file_id();
auto full_message_ids = td_->file_reference_manager_->get_some_message_file_sources(main_file_id);
LOG(INFO) << "Receive " << full_message_ids << " as sources for file " << main_file_id << "/" << file_id << " from "
<< full_message_id;
@ -36108,7 +36109,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me
auto search_text = get_message_search_text(old_message);
for (auto file_id : file_ids) {
auto file_view = td_->file_manager_->get_file_view(file_id);
send_closure(td_->download_manager_actor_, &DownloadManager::change_search_text, file_view.file_id(),
send_closure(td_->download_manager_actor_, &DownloadManager::change_search_text, file_view.get_main_file_id(),
file_source_id, search_text);
}
}
@ -40199,12 +40200,12 @@ void MessagesManager::add_message_file_to_downloads(FullMessageId full_message_i
if (file_view.empty()) {
return promise.set_error(Status::Error(400, "File not found"));
}
file_id = file_view.file_id();
file_id = file_view.get_main_file_id();
bool is_found = false;
for (auto message_file_id : get_message_file_ids(m)) {
auto message_file_view = td_->file_manager_->get_file_view(message_file_id);
CHECK(!message_file_view.empty());
if (message_file_view.file_id() == file_id) {
if (message_file_view.get_main_file_id() == file_id) {
is_found = true;
}
}

View File

@ -61,6 +61,7 @@
#include "td/actor/actor.h"
#include "td/actor/MultiPromise.h"
#include "td/actor/MultiTimeout.h"
#include "td/actor/SignalSlot.h"
#include "td/actor/Timeout.h"

View File

@ -21,7 +21,7 @@
#include "td/telegram/td_api.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -818,7 +818,7 @@ FileId NotificationSettingsManager::get_saved_ringtone(int64 ringtone_id, Promis
CHECK(file_view.get_type() == FileType::Ringtone);
CHECK(file_view.has_remote_location());
if (file_view.remote_location().get_id() == ringtone_id) {
return file_view.file_id();
return file_view.get_main_file_id();
}
}
return {};
@ -898,7 +898,7 @@ void NotificationSettingsManager::add_saved_ringtone(td_api::object_ptr<td_api::
return promise.set_error(Status::Error(400, "Can't use web document as notification sound"));
}
FileId ringtone_file_id = file_view.file_id();
FileId ringtone_file_id = file_view.get_main_file_id();
if (file_type != FileType::Ringtone) {
if (file_type != FileType::Audio && file_type != FileType::VoiceNote) {
return promise.set_error(Status::Error(400, "Unsupported file specified"));
@ -920,7 +920,7 @@ void NotificationSettingsManager::add_saved_ringtone(td_api::object_ptr<td_api::
}
send_save_ringtone_query(
file_view.file_id(), false,
file_view.get_main_file_id(), false,
PromiseCreator::lambda(
[actor_id = actor_id(this), file_id = ringtone_file_id, promise = std::move(promise)](
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtone>> &&result) mutable {
@ -982,9 +982,9 @@ void NotificationSettingsManager::on_upload_ringtone(FileId file_id,
}
send_save_ringtone_query(
file_view.file_id(), false,
file_view.get_main_file_id(), false,
PromiseCreator::lambda(
[actor_id = actor_id(this), file_id = file_view.file_id(), promise = std::move(promise)](
[actor_id = actor_id(this), file_id = file_view.get_main_file_id(), promise = std::move(promise)](
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtone>> &&result) mutable {
if (result.is_error()) {
promise.set_error(result.move_as_error());
@ -1091,7 +1091,7 @@ void NotificationSettingsManager::remove_saved_ringtone(int64 ringtone_id, Promi
CHECK(file_view.has_remote_location());
if (file_view.remote_location().get_id() == ringtone_id) {
send_save_ringtone_query(
file_view.file_id(), true,
file_view.get_main_file_id(), true,
PromiseCreator::lambda(
[actor_id = actor_id(this), ringtone_id, promise = std::move(promise)](
Result<telegram_api::object_ptr<telegram_api::account_SavedRingtone>> &&result) mutable {

View File

@ -14,7 +14,7 @@
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -16,7 +16,7 @@
#include "td/telegram/UserId.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"

View File

@ -431,7 +431,7 @@ void get_premium_features(Td *td, const td_api::object_ptr<td_api::PremiumSource
td_api::object_ptr<td_api::InternalLinkType> payment_link;
auto premium_bot_username = G()->shared_config().get_option_string("premium_bot_username");
if (!premium_bot_username.empty()) {
payment_link = td_api::make_object<td_api::internalLinkTypeBotStart>(premium_bot_username, source_str);
payment_link = td_api::make_object<td_api::internalLinkTypeBotStart>(premium_bot_username, source_str, true);
} else {
auto premium_invoice_slug = G()->shared_config().get_option_string("premium_invoice_slug");
if (!premium_invoice_slug.empty()) {

View File

@ -412,12 +412,12 @@ void SetSecureValue::start_up() {
// Remove duplicate files
FileId front_side_file_id;
if (secure_value_.front_side.file_id.is_valid()) {
front_side_file_id = file_manager->get_file_view(secure_value_.front_side.file_id).file_id();
front_side_file_id = file_manager->get_file_view(secure_value_.front_side.file_id).get_main_file_id();
front_side_ = SecureInputFile();
}
FileId reverse_side_file_id;
if (secure_value_.reverse_side.file_id.is_valid()) {
reverse_side_file_id = file_manager->get_file_view(secure_value_.reverse_side.file_id).file_id();
reverse_side_file_id = file_manager->get_file_view(secure_value_.reverse_side.file_id).get_main_file_id();
reverse_side_ = SecureInputFile();
if (front_side_file_id == reverse_side_file_id) {
return on_error(Status::Error(400, "Front side and reverse side must be different"));
@ -425,7 +425,7 @@ void SetSecureValue::start_up() {
}
FileId selfie_file_id;
if (secure_value_.selfie.file_id.is_valid()) {
selfie_file_id = file_manager->get_file_view(secure_value_.selfie.file_id).file_id();
selfie_file_id = file_manager->get_file_view(secure_value_.selfie.file_id).get_main_file_id();
selfie_ = SecureInputFile();
if (front_side_file_id == selfie_file_id) {
return on_error(Status::Error(400, "Front side and selfie must be different"));
@ -440,10 +440,10 @@ void SetSecureValue::start_up() {
CHECK(!reverse_side_file_id.is_valid());
CHECK(!selfie_file_id.is_valid());
for (auto it = secure_value_.files.begin(); it != secure_value_.files.end();) {
auto file_id = file_manager->get_file_view(it->file_id).file_id();
auto file_id = file_manager->get_file_view(it->file_id).get_main_file_id();
bool is_duplicate = false;
for (auto other_it = secure_value_.files.begin(); other_it != it; ++other_it) {
if (file_id == file_manager->get_file_view(other_it->file_id).file_id()) {
if (file_id == file_manager->get_file_view(other_it->file_id).get_main_file_id()) {
is_duplicate = true;
break;
}
@ -457,16 +457,16 @@ void SetSecureValue::start_up() {
}
if (!secure_value_.translations.empty()) {
for (auto it = secure_value_.translations.begin(); it != secure_value_.translations.end();) {
auto file_id = file_manager->get_file_view(it->file_id).file_id();
auto file_id = file_manager->get_file_view(it->file_id).get_main_file_id();
bool is_duplicate = file_id == front_side_file_id || file_id == reverse_side_file_id || file_id == selfie_file_id;
for (auto other_it = secure_value_.translations.begin(); other_it != it; ++other_it) {
if (file_id == file_manager->get_file_view(other_it->file_id).file_id()) {
if (file_id == file_manager->get_file_view(other_it->file_id).get_main_file_id()) {
is_duplicate = true;
break;
}
}
for (auto &dated_file : secure_value_.files) {
if (file_id == file_manager->get_file_view(dated_file.file_id).file_id()) {
if (file_id == file_manager->get_file_view(dated_file.file_id).get_main_file_id()) {
is_duplicate = true;
break;
}

View File

@ -393,8 +393,8 @@ telegram_api::object_ptr<telegram_api::InputSecureFile> get_input_secure_file_ob
return nullptr;
}
CHECK(input_file.file_id.is_valid());
CHECK(file_manager->get_file_view(file.file.file_id).file_id() ==
file_manager->get_file_view(input_file.file_id).file_id());
CHECK(file_manager->get_file_view(file.file.file_id).get_main_file_id() ==
file_manager->get_file_view(input_file.file_id).get_main_file_id());
auto res = std::move(input_file.input_file);
if (res == nullptr) {
return file_manager->get_file_view(file.file.file_id).remote_location().as_input_secure_file();

View File

@ -163,7 +163,7 @@ td_api::object_ptr<td_api::sponsoredMessage> SponsoredMessageManager::get_sponso
if (bot_username.empty()) {
break;
}
link = td_api::make_object<td_api::internalLinkTypeBotStart>(bot_username, sponsored_message.start_param);
link = td_api::make_object<td_api::internalLinkTypeBotStart>(bot_username, sponsored_message.start_param, false);
break;
}
case DialogType::Channel:

View File

@ -12,7 +12,7 @@
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -2758,6 +2758,12 @@ bool StickersManager::has_input_media(FileId sticker_file_id, bool is_secret) co
if (td_->auth_manager_->is_bot() && file_view.has_remote_location()) {
return true;
}
const Sticker *sticker = get_sticker(sticker_file_id);
CHECK(sticker != nullptr);
if (sticker->set_id.is_valid()) {
// stickers within a set doesn't need to be duped
return true;
}
// having remote location is not enough to have InputMedia, because the file may not have valid file_reference
// also file_id needs to be duped, because upload can be called to repair the file_reference and every upload
// request must have unique file_id
@ -7230,7 +7236,10 @@ void StickersManager::remove_favorite_sticker(const tl_object_ptr<td_api::InputF
}
FileId file_id = r_file_id.ok();
if (!td::remove(favorite_sticker_ids_, file_id)) {
auto is_equal = [sticker_id = file_id](FileId file_id) {
return file_id == sticker_id || (file_id.get_remote() == sticker_id.get_remote() && sticker_id.get_remote() != 0);
};
if (!td::remove_if(favorite_sticker_ids_, is_equal)) {
return promise.set_value(Unit());
}

View File

@ -21,7 +21,7 @@
#include "td/db/DbKey.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/buffer.h"
#include "td/utils/common.h"

View File

@ -284,7 +284,6 @@ Status TdDb::init_sqlite(const TdParameters &parameters, const DbKey &key, const
bool use_file_db = parameters.use_file_db;
bool use_dialog_db = parameters.use_message_db;
bool use_message_db = parameters.use_message_db;
bool use_downloads_db = parameters.use_file_db;
if (!use_sqlite) {
unlink(sql_database_path).ignore();
return Status::OK();
@ -376,7 +375,7 @@ Status TdDb::init_sqlite(const TdParameters &parameters, const DbKey &key, const
dialog_db_async_ = create_dialog_db_async(dialog_db_sync_safe_);
}
if (use_downloads_db) {
if (use_message_db) {
messages_db_sync_safe_ = create_messages_db_sync(sql_connection_);
messages_db_async_ = create_messages_db_async(messages_db_sync_safe_);
}

View File

@ -13,7 +13,7 @@
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -1315,8 +1315,8 @@ tl_object_ptr<td_api::webPageInstantView> WebPagesManager::get_web_page_instant_
LOG(ERROR) << "Trying to get not loaded web page instant view";
return nullptr;
}
auto feedback_link =
td_api::make_object<td_api::internalLinkTypeBotStart>("previews", PSTRING() << "webpage" << web_page_id.get());
auto feedback_link = td_api::make_object<td_api::internalLinkTypeBotStart>(
"previews", PSTRING() << "webpage" << web_page_id.get(), true);
return td_api::make_object<td_api::webPageInstantView>(
get_page_block_objects(web_page_instant_view->page_blocks, td_, web_page_instant_view->url),
web_page_instant_view->view_count, web_page_instant_view->is_v2 ? 2 : 1, web_page_instant_view->is_rtl,

View File

@ -16,7 +16,7 @@
#include "td/telegram/WebPageId.h"
#include "td/actor/actor.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/FlatHashMap.h"

View File

@ -1912,9 +1912,9 @@ void FileManager::flush_to_pmc(FileNodePtr node, bool new_remote, bool new_local
data.encryption_key_ = node->encryption_key_;
data.url_ = node->url_;
data.owner_dialog_id_ = node->owner_dialog_id_;
data.file_source_ids_ = context_->get_some_file_sources(view.file_id());
VLOG(file_references) << "Save file " << view.file_id() << " to database with " << data.file_source_ids_ << " from "
<< source;
data.file_source_ids_ = context_->get_some_file_sources(view.get_main_file_id());
VLOG(file_references) << "Save file " << view.get_main_file_id() << " to database with " << data.file_source_ids_
<< " from " << source;
file_db_->set_file_data(node->pmc_id_, data, (create_flag || new_remote), (create_flag || new_local),
(create_flag || new_generate));
@ -1972,7 +1972,7 @@ void FileManager::load_from_pmc(FileNodePtr node, bool new_remote, bool new_loca
generate = file_view.generate_location();
}
LOG(DEBUG) << "Load from pmc " << file_id << "/" << file_view.file_id() << ", new_remote = " << new_remote
LOG(DEBUG) << "Load from pmc " << file_id << "/" << file_view.get_main_file_id() << ", new_remote = " << new_remote
<< ", new_local = " << new_local << ", new_generate = " << new_generate;
auto load = [&](auto location) {
TRY_RESULT(file_data, file_db_->get_file_data_sync(location));
@ -2143,7 +2143,7 @@ void FileManager::delete_file(FileId file_id, Promise<Unit> promise, const char
auto file_view = FileView(node);
send_closure(G()->download_manager(), &DownloadManager::remove_file_if_finished, file_view.file_id());
send_closure(G()->download_manager(), &DownloadManager::remove_file_if_finished, file_view.get_main_file_id());
string path;
if (file_view.has_local_location()) {
if (begins_with(file_view.local_location().path_, get_files_dir(file_view.get_type()))) {
@ -3017,13 +3017,13 @@ td_api::object_ptr<td_api::file> FileManager::get_file_object(FileId file_id, bo
auto *file_info = get_file_id_info(result_file_id);
if (with_main_file_id) {
if (!file_info->send_updates_flag_) {
result_file_id = file_view.file_id();
result_file_id = file_view.get_main_file_id();
}
file_info = get_file_id_info(file_view.file_id());
file_info = get_file_id_info(file_view.get_main_file_id());
}
file_info->send_updates_flag_ = true;
VLOG(update_file) << "Send file " << file_id << " as " << result_file_id << " and update send_updates_flag_ for file "
<< (with_main_file_id ? file_view.file_id() : result_file_id);
<< (with_main_file_id ? file_view.get_main_file_id() : result_file_id);
return td_api::make_object<td_api::file>(
result_file_id.get(), size, expected_size,
@ -3041,9 +3041,9 @@ vector<int32> FileManager::get_file_ids_object(const vector<FileId> &file_ids, b
auto *file_info = get_file_id_info(result_file_id);
if (with_main_file_id) {
if (!file_info->sent_file_id_flag_ && !file_info->send_updates_flag_) {
result_file_id = file_view.file_id();
result_file_id = file_view.get_main_file_id();
}
file_info = get_file_id_info(file_view.file_id());
file_info = get_file_id_info(file_view.get_main_file_id());
}
file_info->sent_file_id_flag_ = true;

View File

@ -268,7 +268,7 @@ class FileView {
bool get_by_hash() const;
FileId file_id() const {
FileId get_main_file_id() const {
return node_->main_file_id_;
}

View File

@ -11,7 +11,7 @@ set(TDACTOR_SOURCE
td/actor/ConcurrentScheduler.cpp
td/actor/impl/Scheduler.cpp
td/actor/MultiPromise.cpp
td/actor/Timeout.cpp
td/actor/MultiTimeout.cpp
td/actor/actor.h
td/actor/ConcurrentScheduler.h
@ -27,6 +27,7 @@ set(TDACTOR_SOURCE
td/actor/impl/Scheduler-decl.h
td/actor/impl/Scheduler.h
td/actor/MultiPromise.h
td/actor/MultiTimeout.h
td/actor/PromiseFuture.h
td/actor/SchedulerLocalStorage.h
td/actor/SignalSlot.h

View File

@ -4,10 +4,9 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/logging.h"
#include "td/utils/Time.h"
namespace td {

View File

@ -0,0 +1,81 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/actor/actor.h"
#include "td/utils/common.h"
#include "td/utils/Heap.h"
#include "td/utils/Slice.h"
#include "td/utils/Time.h"
#include <set>
namespace td {
// TODO optimize
class MultiTimeout final : public Actor {
struct Item final : public HeapNode {
int64 key;
explicit Item(int64 key) : key(key) {
}
bool operator<(const Item &other) const {
return key < other.key;
}
};
public:
using Data = void *;
using Callback = void (*)(Data, int64);
explicit MultiTimeout(Slice name) {
register_actor(name, this).release();
}
void set_callback(Callback callback) {
callback_ = callback;
}
void set_callback_data(Data data) {
data_ = data;
}
bool has_timeout(int64 key) const;
void set_timeout_in(int64 key, double timeout) {
set_timeout_at(key, Time::now() + timeout);
}
void add_timeout_in(int64 key, double timeout) {
add_timeout_at(key, Time::now() + timeout);
}
void set_timeout_at(int64 key, double timeout);
void add_timeout_at(int64 key, double timeout); // memcache semantics, doesn't replace old timeout
void cancel_timeout(int64 key);
void run_all();
private:
friend class Scheduler;
Callback callback_;
Data data_;
KHeap<double> timeout_queue_;
std::set<Item> items_;
void update_timeout();
void timeout_expired() final;
vector<int64> get_expired_keys(double now);
};
} // namespace td

View File

@ -8,13 +8,6 @@
#include "td/actor/actor.h"
#include "td/utils/common.h"
#include "td/utils/Heap.h"
#include "td/utils/Slice.h"
#include "td/utils/Time.h"
#include <set>
namespace td {
class Timeout final : public Actor {
@ -70,65 +63,4 @@ class Timeout final : public Actor {
}
};
// TODO optimize
class MultiTimeout final : public Actor {
struct Item final : public HeapNode {
int64 key;
explicit Item(int64 key) : key(key) {
}
bool operator<(const Item &other) const {
return key < other.key;
}
};
public:
using Data = void *;
using Callback = void (*)(Data, int64);
explicit MultiTimeout(Slice name) {
register_actor(name, this).release();
}
void set_callback(Callback callback) {
callback_ = callback;
}
void set_callback_data(Data data) {
data_ = data;
}
bool has_timeout(int64 key) const;
void set_timeout_in(int64 key, double timeout) {
set_timeout_at(key, Time::now() + timeout);
}
void add_timeout_in(int64 key, double timeout) {
add_timeout_at(key, Time::now() + timeout);
}
void set_timeout_at(int64 key, double timeout);
void add_timeout_at(int64 key, double timeout); // memcache semantics, doesn't replace old timeout
void cancel_timeout(int64 key);
void run_all();
private:
friend class Scheduler;
Callback callback_;
Data data_;
KHeap<double> timeout_queue_;
std::set<Item> items_;
void update_timeout();
void timeout_expired() final;
vector<int64> get_expired_keys(double now);
};
} // namespace td

View File

@ -6,7 +6,7 @@
//
#include "td/actor/actor.h"
#include "td/actor/ConcurrentScheduler.h"
#include "td/actor/Timeout.h"
#include "td/actor/MultiTimeout.h"
#include "td/utils/common.h"
#include "td/utils/logging.h"

View File

@ -7,6 +7,7 @@
#include "td/net/DarwinHttp.h"
#include "td/utils/logging.h"
#include "td/utils/SliceBuilder.h"
#import <Foundation/Foundation.h>
@ -47,9 +48,9 @@ void http_send(NSURLRequest *request, Promise<BufferSlice> promise) {
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error == nil) {
callback(BufferSlice(Slice((const char *)([data bytes]), [data length])));
callback.set_value(BufferSlice(Slice((const char *)([data bytes]), [data length])));
} else {
callback(Status::Error(static_cast<int32>([error code]), "HTTP request failed"));
callback.set_error(Status::Error(static_cast<int32>([error code]), "HTTP request failed"));
}
}];
[dataTask resume];

View File

@ -128,7 +128,7 @@ TEST(Link, parse_internal_link) {
std::move(administrator_rights));
};
auto bot_start = [](const td::string &bot_username, const td::string &start_parameter) {
return td::td_api::make_object<td::td_api::internalLinkTypeBotStart>(bot_username, start_parameter);
return td::td_api::make_object<td::td_api::internalLinkTypeBotStart>(bot_username, start_parameter, false);
};
auto bot_start_in_group = [](const td::string &bot_username, const td::string &start_parameter,
td::td_api::object_ptr<td::td_api::chatAdministratorRights> &&administrator_rights) {