2020-02-16 17:46:52 +01:00
|
|
|
#include "td-client.h"
|
2020-02-16 17:59:19 +01:00
|
|
|
#include "config.h"
|
2020-02-16 17:46:52 +01:00
|
|
|
|
|
|
|
class UpdateHandler {
|
|
|
|
public:
|
|
|
|
UpdateHandler(PurpleTdClient *owner) : m_owner(owner) {}
|
|
|
|
|
2020-02-22 11:10:30 +01:00
|
|
|
void operator() (td::td_api::updateAuthorizationState &update_authorization_state) const {
|
2020-02-16 17:59:19 +01:00
|
|
|
purple_debug_misc(config::pluginId, "Incoming update: authorization state\n");
|
2020-02-16 17:46:52 +01:00
|
|
|
td::td_api::downcast_call(*update_authorization_state.authorization_state_, *m_owner->m_authUpdateHandler);
|
|
|
|
}
|
|
|
|
|
2020-02-22 11:10:30 +01:00
|
|
|
void operator() (auto &update) const {
|
2020-02-16 17:59:19 +01:00
|
|
|
purple_debug_misc(config::pluginId, "Incoming update: ignorig ID=%d\n", update.get_id());
|
|
|
|
}
|
2020-02-16 17:46:52 +01:00
|
|
|
private:
|
|
|
|
PurpleTdClient *m_owner;
|
|
|
|
};
|
|
|
|
|
|
|
|
class AuthUpdateHandler {
|
|
|
|
public:
|
|
|
|
AuthUpdateHandler(PurpleTdClient *owner) : m_owner(owner) {}
|
|
|
|
|
|
|
|
void operator()(td::td_api::authorizationStateWaitEncryptionKey &) const {
|
2020-02-16 17:59:19 +01:00
|
|
|
purple_debug_misc(config::pluginId, "Authorization state update: encriytion key requested\n");
|
2020-02-16 17:46:52 +01:00
|
|
|
}
|
|
|
|
|
2020-02-22 11:10:30 +01:00
|
|
|
void operator() (td::td_api::authorizationStateWaitTdlibParameters &) const {
|
|
|
|
purple_debug_misc(config::pluginId, "Authorization state update: TDLib parameters requested\n");
|
|
|
|
m_owner->sendTdlibParameters();
|
|
|
|
}
|
|
|
|
|
2020-02-16 17:59:19 +01:00
|
|
|
void operator()(auto &update) const {
|
|
|
|
purple_debug_misc(config::pluginId, "Authorization state update: ignorig ID=%d\n", update.get_id());
|
|
|
|
}
|
2020-02-16 17:46:52 +01:00
|
|
|
private:
|
|
|
|
PurpleTdClient *m_owner;
|
|
|
|
};
|
|
|
|
|
2020-02-22 11:42:04 +01:00
|
|
|
PurpleTdClient::PurpleTdClient(PurpleAccount *acct)
|
2020-02-16 17:46:52 +01:00
|
|
|
{
|
2020-02-22 11:42:04 +01:00
|
|
|
m_account = acct;
|
2020-02-16 17:46:52 +01:00
|
|
|
m_updateHandler = std::make_unique<UpdateHandler>(this);
|
|
|
|
m_authUpdateHandler = std::make_unique<AuthUpdateHandler>(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
PurpleTdClient::~PurpleTdClient()
|
|
|
|
{
|
2020-02-22 11:10:30 +01:00
|
|
|
m_stopThread = true;
|
|
|
|
m_client->send({UINT64_MAX, td::td_api::make_object<td::td_api::close>()});
|
|
|
|
m_pollThread.join();
|
2020-02-16 17:46:52 +01:00
|
|
|
}
|
|
|
|
|
2020-02-17 23:30:24 +01:00
|
|
|
void PurpleTdClient::setLogLevel(int level)
|
|
|
|
{
|
|
|
|
// Why not just call setLogVerbosityLevel? No idea!
|
|
|
|
td::Client::execute({0, td::td_api::make_object<td::td_api::setLogVerbosityLevel>(level)});
|
|
|
|
}
|
|
|
|
|
2020-02-16 17:46:52 +01:00
|
|
|
void PurpleTdClient::startLogin()
|
|
|
|
{
|
2020-02-22 11:10:30 +01:00
|
|
|
#if !GLIB_CHECK_VERSION(2, 32, 0)
|
|
|
|
// GLib threading system is automaticaly initialized since 2.32.
|
|
|
|
// For earlier versions, it have to be initialized before calling any
|
|
|
|
// Glib or GTK+ functions.
|
|
|
|
if (!g_thread_supported())
|
|
|
|
g_thread_init(NULL);
|
|
|
|
#endif
|
|
|
|
|
2020-02-16 17:46:52 +01:00
|
|
|
m_client = std::make_unique<td::Client>();
|
2020-02-22 11:10:30 +01:00
|
|
|
if (!m_pollThread.joinable()) {
|
2020-02-22 11:42:04 +01:00
|
|
|
m_lastQueryId = 0;
|
2020-02-22 11:10:30 +01:00
|
|
|
m_stopThread = false;
|
|
|
|
m_pollThread = std::thread([this]() { pollThreadLoop(); });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PurpleTdClient::pollThreadLoop()
|
|
|
|
{
|
|
|
|
while (!m_stopThread)
|
|
|
|
processResponse(m_client->receive(1));
|
2020-02-16 17:46:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void PurpleTdClient::processResponse(td::Client::Response response)
|
|
|
|
{
|
|
|
|
if (response.object) {
|
2020-02-16 17:59:19 +01:00
|
|
|
if (response.id == 0) {
|
|
|
|
purple_debug_misc(config::pluginId, "Incoming update\n");
|
2020-02-16 17:46:52 +01:00
|
|
|
td::td_api::downcast_call(*response.object, *m_updateHandler);
|
2020-02-16 17:59:19 +01:00
|
|
|
} else {
|
2020-02-22 11:42:04 +01:00
|
|
|
auto it = m_responseHandlers.find(response.id);
|
|
|
|
if (it != m_responseHandlers.end()) {
|
|
|
|
it->second(response.id, std::move(response.object));
|
|
|
|
m_responseHandlers.erase(it);
|
|
|
|
}
|
2020-02-16 17:46:52 +01:00
|
|
|
}
|
2020-02-16 17:59:19 +01:00
|
|
|
} else
|
|
|
|
purple_debug_misc(config::pluginId, "Response id %lu timed out or something\n", response.id);
|
2020-02-16 17:46:52 +01:00
|
|
|
}
|
2020-02-22 11:10:30 +01:00
|
|
|
|
2020-02-22 11:42:04 +01:00
|
|
|
static void authResponse(uint64_t requestId, td::td_api::object_ptr<td::td_api::Object> object)
|
|
|
|
{
|
|
|
|
if (object->get_id() == td::td_api::error::ID) {
|
|
|
|
auto error = td::move_tl_object_as<td::td_api::error>(object);
|
|
|
|
purple_debug_misc(config::pluginId, "Authentication error on query %lu: %s\n", (unsigned long)requestId, td::td_api::to_string(error).c_str());
|
|
|
|
} else
|
|
|
|
purple_debug_misc(config::pluginId, "Authentication success on query %lu\n", (unsigned long)requestId);
|
|
|
|
}
|
|
|
|
|
2020-02-22 11:10:30 +01:00
|
|
|
void PurpleTdClient::sendTdlibParameters()
|
|
|
|
{
|
2020-02-22 11:42:04 +01:00
|
|
|
auto parameters = td::td_api::make_object<td::td_api::tdlibParameters>();
|
|
|
|
const char *username = purple_account_get_username(m_account);
|
|
|
|
parameters->database_directory_ = std::string(purple_user_dir()) + G_DIR_SEPARATOR_S +
|
|
|
|
config::configSubdir + G_DIR_SEPARATOR_S + username;
|
|
|
|
purple_debug_misc(config::pluginId, "Account %s using database directory %s\n",
|
|
|
|
username, parameters->database_directory_.c_str());
|
|
|
|
parameters->use_message_database_ = true;
|
|
|
|
parameters->use_secret_chats_ = true;
|
|
|
|
parameters->api_id_ = 94575;
|
|
|
|
parameters->api_hash_ = "a3406de8d171bb422bb6ddf3bbd800e2";
|
|
|
|
parameters->system_language_code_ = "en";
|
|
|
|
parameters->device_model_ = "Desktop";
|
|
|
|
parameters->system_version_ = "Unknown";
|
|
|
|
parameters->application_version_ = "1.0";
|
|
|
|
parameters->enable_storage_optimizer_ = true;
|
|
|
|
sendQuery(td::td_api::make_object<td::td_api::setTdlibParameters>(std::move(parameters)),
|
|
|
|
authResponse);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PurpleTdClient::sendQuery(td::td_api::object_ptr<td::td_api::Function> f, ResponseCb handler)
|
|
|
|
{
|
|
|
|
uint64_t queryId = ++m_lastQueryId;
|
|
|
|
purple_debug_misc(config::pluginId, "Sending query id %lu\n", (unsigned long)queryId);
|
|
|
|
if (handler)
|
|
|
|
m_responseHandlers.emplace(queryId, std::move(handler));
|
|
|
|
m_client->send({queryId, std::move(f)});
|
2020-02-22 11:10:30 +01:00
|
|
|
}
|