mirror of
https://github.com/tdlight-team/tdlight-telegram-bot-api.git
synced 2024-12-24 11:45:51 +01:00
commit
e18ecceee4
@ -6,7 +6,7 @@ if (POLICY CMP0065)
|
||||
cmake_policy(SET CMP0065 NEW)
|
||||
endif()
|
||||
|
||||
project(TelegramBotApi VERSION 6.6 LANGUAGES CXX)
|
||||
project(TelegramBotApi VERSION 6.7.1 LANGUAGES CXX)
|
||||
|
||||
if (POLICY CMP0069)
|
||||
option(TELEGRAM_BOT_API_ENABLE_LTO "Use \"ON\" to enable Link Time Optimization.")
|
||||
@ -73,6 +73,9 @@ if (CLANG OR GCC)
|
||||
elseif (APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie")
|
||||
endif()
|
||||
include(AddCXXCompilerFlag)
|
||||
add_cxx_compiler_flag("-static-libstdc++")
|
||||
add_cxx_compiler_flag("-static-libgcc")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
2
td
2
td
@ -1 +1 @@
|
||||
Subproject commit 70bee089d492437ce931aa78446d89af3da182fc
|
||||
Subproject commit 328b8649d859c5ed4088a875cbb059db6029dc0d
|
@ -57,7 +57,7 @@ using td_api::move_object_as;
|
||||
|
||||
int Client::get_retry_after_time(td::Slice error_message) {
|
||||
td::Slice prefix = "Too Many Requests: retry after ";
|
||||
if (begins_with(error_message, prefix)) {
|
||||
if (td::begins_with(error_message, prefix)) {
|
||||
auto r_retry_after = td::to_integer_safe<int>(error_message.substr(prefix.size()));
|
||||
if (r_retry_after.is_ok() && r_retry_after.ok() > 0) {
|
||||
return r_retry_after.ok();
|
||||
@ -173,7 +173,7 @@ void Client::fail_query_with_error(PromisedQueryPtr query, int32 error_code, td:
|
||||
return fail_query(400, PSLICE() << "Bad Request: " << error_message, std::move(query));
|
||||
}
|
||||
|
||||
if (begins_with(error_message, prefix)) {
|
||||
if (td::begins_with(error_message, prefix)) {
|
||||
return fail_query(error_code, error_message, std::move(query));
|
||||
} else {
|
||||
td::string error_str = prefix.str();
|
||||
@ -225,6 +225,8 @@ bool Client::init_methods() {
|
||||
methods_.emplace("deletemycommands", &Client::process_delete_my_commands_query);
|
||||
methods_.emplace("getmydefaultadministratorrights", &Client::process_get_my_default_administrator_rights_query);
|
||||
methods_.emplace("setmydefaultadministratorrights", &Client::process_set_my_default_administrator_rights_query);
|
||||
methods_.emplace("getmyname", &Client::process_get_my_name_query);
|
||||
methods_.emplace("setmyname", &Client::process_set_my_name_query);
|
||||
methods_.emplace("getmydescription", &Client::process_get_my_description_query);
|
||||
methods_.emplace("setmydescription", &Client::process_set_my_description_query);
|
||||
methods_.emplace("getmyshortdescription", &Client::process_get_my_short_description_query);
|
||||
@ -1928,10 +1930,28 @@ class Client::JsonInlineKeyboardButton final : public td::Jsonable {
|
||||
break;
|
||||
case td_api::inlineKeyboardButtonTypeSwitchInline::ID: {
|
||||
auto type = static_cast<const td_api::inlineKeyboardButtonTypeSwitchInline *>(button_->type_.get());
|
||||
if (type->in_current_chat_) {
|
||||
switch (type->target_chat_->get_id()) {
|
||||
case td_api::targetChatCurrent::ID:
|
||||
object("switch_inline_query_current_chat", type->query_);
|
||||
} else {
|
||||
break;
|
||||
case td_api::targetChatChosen::ID: {
|
||||
auto target_chat = static_cast<const td_api::targetChatChosen *>(type->target_chat_.get());
|
||||
if (target_chat->allow_user_chats_ && target_chat->allow_bot_chats_ && target_chat->allow_group_chats_ &&
|
||||
target_chat->allow_channel_chats_) {
|
||||
object("switch_inline_query", type->query_);
|
||||
} else {
|
||||
object("switch_inline_query_chosen_chat", td::json_object([&](auto &o) {
|
||||
o("query", type->query_);
|
||||
o("allow_user_chats", td::JsonBool(target_chat->allow_user_chats_));
|
||||
o("allow_bot_chats", td::JsonBool(target_chat->allow_bot_chats_));
|
||||
o("allow_group_chats", td::JsonBool(target_chat->allow_group_chats_));
|
||||
o("allow_channel_chats", td::JsonBool(target_chat->allow_channel_chats_));
|
||||
}));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2384,6 +2404,8 @@ void Client::JsonMessage::store(td::JsonValueScope *scope) const {
|
||||
object("chat_shared", JsonChatShared(content));
|
||||
break;
|
||||
}
|
||||
case td_api::messageChatSetBackground::ID:
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -2702,6 +2724,19 @@ class Client::JsonBotMenuButton final : public td::Jsonable {
|
||||
const td_api::botMenuButton *menu_button_;
|
||||
};
|
||||
|
||||
class Client::JsonBotName final : public td::Jsonable {
|
||||
public:
|
||||
explicit JsonBotName(const td_api::text *text) : text_(text) {
|
||||
}
|
||||
void store(td::JsonValueScope *scope) const {
|
||||
auto object = scope->enter_object();
|
||||
object("name", text_->text_);
|
||||
}
|
||||
|
||||
private:
|
||||
const td_api::text *text_;
|
||||
};
|
||||
|
||||
class Client::JsonBotInfoDescription final : public td::Jsonable {
|
||||
public:
|
||||
explicit JsonBotInfoDescription(const td_api::text *text) : text_(text) {
|
||||
@ -2904,6 +2939,9 @@ class Client::JsonChatMemberUpdated final : public td::Jsonable {
|
||||
if (update_->invite_link_ != nullptr) {
|
||||
object("invite_link", JsonChatInviteLink(update_->invite_link_.get(), client_));
|
||||
}
|
||||
if (update_->via_chat_folder_invite_link_) {
|
||||
object("via_chat_folder_invite_link", td::JsonTrue());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@ -4172,6 +4210,25 @@ class Client::TdOnGetMyDefaultAdministratorRightsCallback final : public TdQuery
|
||||
PromisedQueryPtr query_;
|
||||
};
|
||||
|
||||
class Client::TdOnGetMyNameCallback final : public TdQueryCallback {
|
||||
public:
|
||||
explicit TdOnGetMyNameCallback(PromisedQueryPtr query) : query_(std::move(query)) {
|
||||
}
|
||||
|
||||
void on_result(object_ptr<td_api::Object> result) final {
|
||||
if (result->get_id() == td_api::error::ID) {
|
||||
return fail_query_with_error(std::move(query_), move_object_as<td_api::error>(result));
|
||||
}
|
||||
|
||||
CHECK(result->get_id() == td_api::text::ID);
|
||||
auto text = move_object_as<td_api::text>(result);
|
||||
answer_query(JsonBotName(text.get()), std::move(query_));
|
||||
}
|
||||
|
||||
private:
|
||||
PromisedQueryPtr query_;
|
||||
};
|
||||
|
||||
class Client::TdOnGetMyDescriptionCallback final : public TdQueryCallback {
|
||||
public:
|
||||
explicit TdOnGetMyDescriptionCallback(PromisedQueryPtr query) : query_(std::move(query)) {
|
||||
@ -5547,8 +5604,8 @@ void Client::on_update_authorization_state() {
|
||||
send_request(make_object<td_api::setOption>("reuse_uploaded_photos_by_hash",
|
||||
make_object<td_api::optionValueBoolean>(true)),
|
||||
td::make_unique<TdOnOkCallback>());
|
||||
send_request(make_object<td_api::setOption>("disable_persistent_network_statistics",
|
||||
make_object<td_api::optionValueBoolean>(true)),
|
||||
send_request(
|
||||
make_object<td_api::setOption>("disable_network_statistics", make_object<td_api::optionValueBoolean>(true)),
|
||||
td::make_unique<TdOnOkCallback>());
|
||||
send_request(make_object<td_api::setOption>("disable_time_adjustment_protection",
|
||||
make_object<td_api::optionValueBoolean>(true)),
|
||||
@ -6271,13 +6328,31 @@ td::Result<td_api::object_ptr<td_api::inlineKeyboardButton>> Client::get_inline_
|
||||
if (has_json_object_field(object, "switch_inline_query")) {
|
||||
TRY_RESULT(switch_inline_query, get_json_object_string_field(object, "switch_inline_query", false));
|
||||
return make_object<td_api::inlineKeyboardButton>(
|
||||
text, make_object<td_api::inlineKeyboardButtonTypeSwitchInline>(switch_inline_query, false));
|
||||
text, make_object<td_api::inlineKeyboardButtonTypeSwitchInline>(
|
||||
switch_inline_query, td_api::make_object<td_api::targetChatChosen>(true, true, true, true)));
|
||||
}
|
||||
|
||||
if (has_json_object_field(object, "switch_inline_query_chosen_chat")) {
|
||||
TRY_RESULT(switch_inline_query,
|
||||
get_json_object_field(object, "switch_inline_query_chosen_chat", td::JsonValue::Type::Object, false));
|
||||
CHECK(switch_inline_query.type() == td::JsonValue::Type::Object);
|
||||
auto &switch_inline_query_object = switch_inline_query.get_object();
|
||||
TRY_RESULT(query, get_json_object_string_field(switch_inline_query_object, "query"));
|
||||
TRY_RESULT(allow_user_chats, get_json_object_bool_field(switch_inline_query_object, "allow_user_chats"));
|
||||
TRY_RESULT(allow_bot_chats, get_json_object_bool_field(switch_inline_query_object, "allow_bot_chats"));
|
||||
TRY_RESULT(allow_group_chats, get_json_object_bool_field(switch_inline_query_object, "allow_group_chats"));
|
||||
TRY_RESULT(allow_channel_chats, get_json_object_bool_field(switch_inline_query_object, "allow_channel_chats"));
|
||||
return make_object<td_api::inlineKeyboardButton>(
|
||||
text, make_object<td_api::inlineKeyboardButtonTypeSwitchInline>(
|
||||
query, td_api::make_object<td_api::targetChatChosen>(allow_user_chats, allow_bot_chats,
|
||||
allow_group_chats, allow_channel_chats)));
|
||||
}
|
||||
|
||||
if (has_json_object_field(object, "switch_inline_query_current_chat")) {
|
||||
TRY_RESULT(switch_inline_query, get_json_object_string_field(object, "switch_inline_query_current_chat", false));
|
||||
return make_object<td_api::inlineKeyboardButton>(
|
||||
text, make_object<td_api::inlineKeyboardButtonTypeSwitchInline>(switch_inline_query, true));
|
||||
text, make_object<td_api::inlineKeyboardButtonTypeSwitchInline>(
|
||||
switch_inline_query, td_api::make_object<td_api::targetChatCurrent>()));
|
||||
}
|
||||
|
||||
if (has_json_object_field(object, "login_url")) {
|
||||
@ -8710,9 +8785,24 @@ td::Status Client::process_set_my_default_administrator_rights_query(PromisedQue
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Status Client::process_get_my_name_query(PromisedQueryPtr &query) {
|
||||
auto language_code = query->arg("language_code");
|
||||
send_request(make_object<td_api::getBotName>(my_id_, language_code.str()),
|
||||
td::make_unique<TdOnGetMyNameCallback>(std::move(query)));
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Status Client::process_set_my_name_query(PromisedQueryPtr &query) {
|
||||
auto language_code = query->arg("language_code");
|
||||
auto name = query->arg("name");
|
||||
send_request(make_object<td_api::setBotName>(my_id_, language_code.str(), name.str()),
|
||||
td::make_unique<TdOnOkQueryCallback>(std::move(query)));
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Status Client::process_get_my_description_query(PromisedQueryPtr &query) {
|
||||
auto language_code = query->arg("language_code");
|
||||
send_request(make_object<td_api::getBotInfoDescription>(language_code.str()),
|
||||
send_request(make_object<td_api::getBotInfoDescription>(my_id_, language_code.str()),
|
||||
td::make_unique<TdOnGetMyDescriptionCallback>(std::move(query)));
|
||||
return td::Status::OK();
|
||||
}
|
||||
@ -8720,14 +8810,14 @@ td::Status Client::process_get_my_description_query(PromisedQueryPtr &query) {
|
||||
td::Status Client::process_set_my_description_query(PromisedQueryPtr &query) {
|
||||
auto language_code = query->arg("language_code");
|
||||
auto description = query->arg("description");
|
||||
send_request(make_object<td_api::setBotInfoDescription>(language_code.str(), description.str()),
|
||||
send_request(make_object<td_api::setBotInfoDescription>(my_id_, language_code.str(), description.str()),
|
||||
td::make_unique<TdOnOkQueryCallback>(std::move(query)));
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
||||
td::Status Client::process_get_my_short_description_query(PromisedQueryPtr &query) {
|
||||
auto language_code = query->arg("language_code");
|
||||
send_request(make_object<td_api::getBotInfoShortDescription>(language_code.str()),
|
||||
send_request(make_object<td_api::getBotInfoShortDescription>(my_id_, language_code.str()),
|
||||
td::make_unique<TdOnGetMyShortDescriptionCallback>(std::move(query)));
|
||||
return td::Status::OK();
|
||||
}
|
||||
@ -8735,7 +8825,7 @@ td::Status Client::process_get_my_short_description_query(PromisedQueryPtr &quer
|
||||
td::Status Client::process_set_my_short_description_query(PromisedQueryPtr &query) {
|
||||
auto language_code = query->arg("language_code");
|
||||
auto short_description = query->arg("short_description");
|
||||
send_request(make_object<td_api::setBotInfoShortDescription>(language_code.str(), short_description.str()),
|
||||
send_request(make_object<td_api::setBotInfoShortDescription>(my_id_, language_code.str(), short_description.str()),
|
||||
td::make_unique<TdOnOkQueryCallback>(std::move(query)));
|
||||
return td::Status::OK();
|
||||
}
|
||||
@ -11525,7 +11615,8 @@ void Client::do_get_updates(int32 offset, int32 limit, int32 timeout, PromisedQu
|
||||
if (need_warning && previous_get_updates_finish_time_ > 0) {
|
||||
LOG(WARNING) << "Found " << updates.size() << " updates out of " << (total_size + updates.size())
|
||||
<< " after last getUpdates call " << (query->start_timestamp() - previous_get_updates_finish_time_)
|
||||
<< " seconds ago in " << (td::Time::now() - query->start_timestamp()) << " seconds";
|
||||
<< " seconds ago in " << (td::Time::now() - query->start_timestamp()) << " seconds from "
|
||||
<< query->get_peer_ip_address();
|
||||
} else {
|
||||
LOG(DEBUG) << "Found " << updates.size() << " updates out of " << total_size << " from " << from;
|
||||
}
|
||||
@ -12442,6 +12533,8 @@ bool Client::need_skip_update_message(int64 chat_id, const object_ptr<td_api::me
|
||||
return true;
|
||||
case td_api::messageSuggestProfilePhoto::ID:
|
||||
return true;
|
||||
case td_api::messageChatSetBackground::ID:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -12564,7 +12657,8 @@ bool Client::are_equal_inline_keyboard_buttons(const td_api::inlineKeyboardButto
|
||||
case td_api::inlineKeyboardButtonTypeSwitchInline::ID: {
|
||||
auto lhs_type = static_cast<const td_api::inlineKeyboardButtonTypeSwitchInline *>(lhs->type_.get());
|
||||
auto rhs_type = static_cast<const td_api::inlineKeyboardButtonTypeSwitchInline *>(rhs->type_.get());
|
||||
return lhs_type->query_ == rhs_type->query_ && lhs_type->in_current_chat_ == rhs_type->in_current_chat_;
|
||||
return lhs_type->query_ == rhs_type->query_ &&
|
||||
to_string(lhs_type->target_chat_) == to_string(rhs_type->target_chat_);
|
||||
}
|
||||
case td_api::inlineKeyboardButtonTypeBuy::ID:
|
||||
return true;
|
||||
|
@ -150,6 +150,7 @@ class Client final : public WebhookActor::Callback {
|
||||
class JsonPreCheckoutQuery;
|
||||
class JsonBotCommand;
|
||||
class JsonBotMenuButton;
|
||||
class JsonBotName;
|
||||
class JsonBotInfoDescription;
|
||||
class JsonBotInfoShortDescription;
|
||||
class JsonChatAdministratorRights;
|
||||
@ -214,6 +215,7 @@ class Client final : public WebhookActor::Callback {
|
||||
class TdOnGetMenuButtonCallback;
|
||||
class TdOnGetMyCommandsCallback;
|
||||
class TdOnGetMyDefaultAdministratorRightsCallback;
|
||||
class TdOnGetMyNameCallback;
|
||||
class TdOnGetMyDescriptionCallback;
|
||||
class TdOnGetMyShortDescriptionCallback;
|
||||
class TdOnGetChatFullInfoCallback;
|
||||
@ -573,6 +575,8 @@ class Client final : public WebhookActor::Callback {
|
||||
td::Status process_delete_my_commands_query(PromisedQueryPtr &query);
|
||||
td::Status process_get_my_default_administrator_rights_query(PromisedQueryPtr &query);
|
||||
td::Status process_set_my_default_administrator_rights_query(PromisedQueryPtr &query);
|
||||
td::Status process_get_my_name_query(PromisedQueryPtr &query);
|
||||
td::Status process_set_my_name_query(PromisedQueryPtr &query);
|
||||
td::Status process_get_my_description_query(PromisedQueryPtr &query);
|
||||
td::Status process_set_my_description_query(PromisedQueryPtr &query);
|
||||
td::Status process_get_my_short_description_query(PromisedQueryPtr &query);
|
||||
|
@ -177,13 +177,7 @@ void ClientManager::user_login(PromisedQueryPtr query) {
|
||||
}
|
||||
|
||||
bool ClientManager::check_flood_limits(PromisedQueryPtr &query, bool is_user_login) {
|
||||
td::string ip_address;
|
||||
if (query->peer_address().is_valid() && !query->peer_address().is_reserved()) { // external connection
|
||||
ip_address = query->peer_address().get_ip_str().str();
|
||||
} else {
|
||||
// invalid peer address or connection from the local network
|
||||
ip_address = query->get_header("x-real-ip").str();
|
||||
}
|
||||
td::string ip_address = query->get_peer_ip_address();
|
||||
if (!ip_address.empty()) {
|
||||
td::IPAddress tmp;
|
||||
tmp.init_host_port(ip_address, 0).ignore();
|
||||
@ -192,7 +186,7 @@ bool ClientManager::check_flood_limits(PromisedQueryPtr &query, bool is_user_log
|
||||
ip_address = tmp.get_ip_str().str();
|
||||
}
|
||||
}
|
||||
LOG(DEBUG) << "Receive incoming query for new bot " << query->token() << " from " << query->peer_address();
|
||||
LOG(DEBUG) << "Receive incoming query for new bot " << query->token() << " from " << ip_address;
|
||||
if (!ip_address.empty()) {
|
||||
LOG(DEBUG) << "Check Client creation flood control for IP address " << ip_address;
|
||||
if (is_user_login) {
|
||||
|
@ -26,10 +26,10 @@ td::FlatHashMap<td::string, td::unique_ptr<td::VirtuallyJsonable>> empty_paramet
|
||||
Query::Query(td::vector<td::BufferSlice> &&container, td::Slice token, bool is_user, bool is_test_dc, td::MutableSlice method,
|
||||
td::vector<std::pair<td::MutableSlice, td::MutableSlice>> &&args,
|
||||
td::vector<std::pair<td::MutableSlice, td::MutableSlice>> &&headers, td::vector<td::HttpFile> &&files,
|
||||
std::shared_ptr<SharedData> shared_data, const td::IPAddress &peer_address, bool is_internal)
|
||||
std::shared_ptr<SharedData> shared_data, const td::IPAddress &peer_ip_address, bool is_internal)
|
||||
: state_(State::Query)
|
||||
, shared_data_(shared_data)
|
||||
, peer_address_(peer_address)
|
||||
, peer_ip_address_(peer_ip_address)
|
||||
, container_(std::move(container))
|
||||
, token_(token)
|
||||
, is_user_(is_user)
|
||||
@ -54,6 +54,15 @@ Query::Query(td::vector<td::BufferSlice> &&container, td::Slice token, bool is_u
|
||||
}
|
||||
}
|
||||
|
||||
td::string Query::get_peer_ip_address() const {
|
||||
if (peer_ip_address_.is_valid() && !peer_ip_address_.is_reserved()) { // external connection
|
||||
return peer_ip_address_.get_ip_str().str();
|
||||
} else {
|
||||
// invalid peer IP address or connection from the local network
|
||||
return get_header("x-real-ip").str();
|
||||
}
|
||||
}
|
||||
|
||||
td::int64 Query::query_size() const {
|
||||
return std::accumulate(
|
||||
container_.begin(), container_.end(), td::int64{0},
|
||||
|
@ -73,9 +73,7 @@ class Query final : public td::ListNode {
|
||||
return files_;
|
||||
}
|
||||
|
||||
const td::IPAddress &peer_address() const {
|
||||
return peer_address_;
|
||||
}
|
||||
td::string get_peer_ip_address() const;
|
||||
|
||||
td::BufferSlice &answer() {
|
||||
return answer_;
|
||||
@ -106,7 +104,7 @@ class Query final : public td::ListNode {
|
||||
Query(td::vector<td::BufferSlice> &&container, td::Slice token, bool is_user, bool is_test_dc, td::MutableSlice method,
|
||||
td::vector<std::pair<td::MutableSlice, td::MutableSlice>> &&args,
|
||||
td::vector<std::pair<td::MutableSlice, td::MutableSlice>> &&headers, td::vector<td::HttpFile> &&files,
|
||||
std::shared_ptr<SharedData> shared_data, const td::IPAddress &peer_address, bool is_internal);
|
||||
std::shared_ptr<SharedData> shared_data, const td::IPAddress &peer_ip_address, bool is_internal);
|
||||
Query(const Query &) = delete;
|
||||
Query &operator=(const Query &) = delete;
|
||||
Query(Query &&) = delete;
|
||||
@ -132,7 +130,7 @@ class Query final : public td::ListNode {
|
||||
State state_;
|
||||
std::shared_ptr<SharedData> shared_data_;
|
||||
double start_timestamp_;
|
||||
td::IPAddress peer_address_;
|
||||
td::IPAddress peer_ip_address_;
|
||||
td::ActorId<BotStatActor> stat_actor_;
|
||||
|
||||
// request
|
||||
|
@ -13,7 +13,7 @@ namespace telegram_bot_api {
|
||||
|
||||
void Watchdog::kick() {
|
||||
auto now = td::Time::now();
|
||||
if (now >= last_kick_time_ + timeout_ && last_kick_time_ > 0) {
|
||||
if (now >= last_kick_time_ + timeout_ && last_kick_time_ > 0 && GET_VERBOSITY_LEVEL() >= VERBOSITY_NAME(ERROR)) {
|
||||
LOG(ERROR) << get_name() << " timeout expired after " << now - last_kick_time_ << " seconds";
|
||||
td::thread::send_real_time_signal(main_thread_id_, 2);
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ td::Status WebhookActor::create_webhook_error(td::Slice error_message, td::Statu
|
||||
on_webhook_error(error_message);
|
||||
}
|
||||
on_error(std::move(result));
|
||||
return std::move(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
td::Result<td::SslStream> WebhookActor::create_ssl_stream() {
|
||||
|
@ -165,7 +165,7 @@ int main(int argc, char *argv[]) {
|
||||
auto start_time = td::Time::now();
|
||||
auto shared_data = std::make_shared<SharedData>();
|
||||
auto parameters = std::make_unique<ClientParameters>();
|
||||
parameters->version_ = "6.6";
|
||||
parameters->version_ = "6.7.1";
|
||||
parameters->shared_data_ = shared_data;
|
||||
parameters->start_time_ = start_time;
|
||||
auto net_query_stats = td::create_net_query_stats();
|
||||
|
Loading…
Reference in New Issue
Block a user