diff --git a/td/generate/scheme/telegram_api.tl b/td/generate/scheme/telegram_api.tl index 61e68c5f9..5d87305f6 100644 --- a/td/generate/scheme/telegram_api.tl +++ b/td/generate/scheme/telegram_api.tl @@ -26,6 +26,7 @@ inputStickerSetThumbLegacy#dbaeae9 stickerset:InputStickerSet volume_id:long loc test.useError = Error; test.useConfigSimple = help.ConfigSimple; +test.parseInputAppEvent = InputAppEvent; ---types--- diff --git a/td/telegram/Application.cpp b/td/telegram/Application.cpp index 8f4e559d4..f733bf7f1 100644 --- a/td/telegram/Application.cpp +++ b/td/telegram/Application.cpp @@ -7,11 +7,18 @@ #include "td/telegram/Application.h" #include "td/telegram/Global.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/logevent/LogEventHelper.h" #include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" + +#include "td/db/binlog/BinlogEvent.h" +#include "td/db/binlog/BinlogHelper.h" #include "td/utils/buffer.h" #include "td/utils/logging.h" #include "td/utils/Status.h" +#include "td/utils/tl_parsers.h" namespace td { @@ -48,11 +55,9 @@ class SaveAppLogQuery final : public Td::ResultHandler { explicit SaveAppLogQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(const string &type, DialogId dialog_id, tl_object_ptr &&data) { - CHECK(data != nullptr); + void send(telegram_api::object_ptr &&input_app_event) { vector> input_app_events; - input_app_events.push_back( - make_tl_object(G()->server_time_cached(), type, dialog_id.get(), std::move(data))); + input_app_events.push_back(std::move(input_app_event)); send_query(G()->net_query_creator().create_unauth(telegram_api::help_saveAppLog(std::move(input_app_events)))); } @@ -76,9 +81,55 @@ void get_invite_text(Td *td, Promise &&promise) { td->create_handler(std::move(promise))->send(); } +class SaveAppLogLogEvent { + public: + const telegram_api::inputAppEvent *input_app_event_in_ = nullptr; + telegram_api::object_ptr input_app_event_out_; + + template + void store(StorerT &storer) const { + input_app_event_in_->store(storer); + } + + template + void parse(ParserT &parser) { + auto buffer = parser.fetch_string_raw(parser.get_left_len()); + TlBufferParser buffer_parser{&buffer}; + input_app_event_out_ = telegram_api::make_object(buffer_parser); + } +}; + +static void save_app_log_impl(Td *td, telegram_api::object_ptr input_app_event, + uint64 log_event_id, Promise &&promise) { + if (log_event_id == 0) { + SaveAppLogLogEvent log_event; + log_event.input_app_event_in_ = input_app_event.get(); + log_event_id = + binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SaveAppLog, get_log_event_storer(log_event)); + } + + td->create_handler(get_erase_log_event_promise(log_event_id, std::move(promise))) + ->send(std::move(input_app_event)); +} + void save_app_log(Td *td, const string &type, DialogId dialog_id, tl_object_ptr &&data, Promise &&promise) { - td->create_handler(std::move(promise))->send(type, dialog_id, std::move(data)); + CHECK(data != nullptr); + auto input_app_event = telegram_api::make_object(G()->server_time_cached(), type, + dialog_id.get(), std::move(data)); + save_app_log_impl(td, std::move(input_app_event), 0, std::move(promise)); +} + +void on_save_app_log_binlog_event(Td *td, BinlogEvent &&event) { + if (G()->close_flag()) { + return; + } + CHECK(event.id_ != 0); + CHECK(event.type_ == LogEvent::HandlerType::SaveAppLog); + SaveAppLogLogEvent log_event; + log_event_parse(log_event, event.data_).ensure(); + + save_app_log_impl(td, std::move(log_event.input_app_event_out_), event.id_, Promise()); } } // namespace td diff --git a/td/telegram/Application.h b/td/telegram/Application.h index 4ca4ca7ac..e6d792689 100644 --- a/td/telegram/Application.h +++ b/td/telegram/Application.h @@ -14,6 +14,8 @@ namespace td { +struct BinlogEvent; + class Td; void get_invite_text(Td *td, Promise &&promise); @@ -21,4 +23,6 @@ void get_invite_text(Td *td, Promise &&promise); void save_app_log(Td *td, const string &type, DialogId dialog_id, tl_object_ptr &&data, Promise &&promise); +void on_save_app_log_binlog_event(Td *td, BinlogEvent &&event); + } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index c6216e1bf..a1e06e94b 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -3801,6 +3801,10 @@ void Td::init(Result r_opened_database) { web_pages_manager_->on_binlog_web_page_event(std::move(event)); } + for (auto &event : events.save_app_log_events) { + on_save_app_log_binlog_event(this, std::move(event)); + } + if (is_online_) { on_online_updated(true, true); } diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 948526d22..96eb70ab5 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -117,6 +117,9 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::EditMessagePushNotification: events.to_notification_manager.push_back(event.clone()); break; + case LogEvent::HandlerType::SaveAppLog: + events.save_app_log_events.push_back(event.clone()); + break; case LogEvent::HandlerType::BinlogPmcMagic: binlog_pmc.external_init_handle(event); break; diff --git a/td/telegram/TdDb.h b/td/telegram/TdDb.h index 14beacfa3..f38fb7c42 100644 --- a/td/telegram/TdDb.h +++ b/td/telegram/TdDb.h @@ -63,6 +63,7 @@ class TdDb { vector channel_events; vector secret_chat_events; vector web_page_events; + vector save_app_log_events; vector to_poll_manager; vector to_messages_manager; vector to_notification_manager; diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index d0f0a80d6..2a4fee9b0 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -104,6 +104,7 @@ class LogEvent { GetChannelDifference = 0x140, AddMessagePushNotification = 0x200, EditMessagePushNotification = 0x201, + SaveAppLog = 0x300, ConfigPmcMagic = 0x1f18, BinlogPmcMagic = 0x4327 };