From 93149d09fdfdfd02af1ad490e009264fb8ab2f61 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 3 Jul 2023 22:03:29 +0300 Subject: [PATCH] Add SendStoryLogEvent. --- td/telegram/StoryManager.cpp | 84 +++++++++++++++++++++++++++++---- td/telegram/StoryManager.h | 5 +- td/telegram/TdDb.cpp | 1 + td/telegram/logevent/LogEvent.h | 1 + 4 files changed, 80 insertions(+), 11 deletions(-) diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index 5aa71ffee..d10c9f9ef 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -684,14 +684,12 @@ class StoryManager::UploadMediaCallback final : public FileManager::UploadCallba } }; -StoryManager::PendingStory::PendingStory(DialogId dialog_id, StoryId story_id, uint64 log_event_id, - uint32 send_story_num, int64 random_id, unique_ptr &&story) +StoryManager::PendingStory::PendingStory(DialogId dialog_id, StoryId story_id, uint32 send_story_num, int64 random_id, + unique_ptr &&story) : dialog_id_(dialog_id) , story_id_(story_id) - , log_event_id_(log_event_id) , send_story_num_(send_story_num) , random_id_(random_id) - , was_reuploaded_(false) , story_(std::move(story)) { } @@ -2609,7 +2607,7 @@ void StoryManager::send_story(td_api::object_ptr &&in story->is_pinned_ = is_pinned; story->noforwards_ = protect_content; story->privacy_rules_ = std::move(privacy_rules); - story->content_ = std::move(content); + story->content_ = dup_story_content(td_, content.get()); story->caption_ = std::move(caption); int64 random_id; @@ -2619,14 +2617,46 @@ void StoryManager::send_story(td_api::object_ptr &&in auto story_ptr = story.get(); - auto pending_story = td::make_unique(dialog_id, StoryId(), 0 /*log_event_id*/, ++send_story_count_, - random_id, std::move(story)); + auto pending_story = + td::make_unique(dialog_id, StoryId(), ++send_story_count_, random_id, std::move(story)); + pending_story->log_event_id_ = save_send_story_log_event(pending_story.get()); do_send_story(std::move(pending_story), {}); promise.set_value(get_story_object({dialog_id, StoryId()}, story_ptr)); } +class StoryManager::SendStoryLogEvent { + public: + const PendingStory *pending_story_in; + unique_ptr pending_story_out; + + SendStoryLogEvent() : pending_story_in(nullptr) { + } + + explicit SendStoryLogEvent(const PendingStory *pending_story) : pending_story_in(pending_story) { + } + + template + void store(StorerT &storer) const { + td::store(*pending_story_in, storer); + } + + template + void parse(ParserT &parser) { + td::parse(pending_story_out, parser); + } +}; + +int64 StoryManager::save_send_story_log_event(const PendingStory *pending_story) { + if (!G()->use_message_database()) { + return 0; + } + + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SendStory, + get_log_event_storer(SendStoryLogEvent(pending_story))); +} + void StoryManager::delete_pending_story(unique_ptr &&pending_story) { CHECK(pending_story != nullptr); if (pending_story->log_event_id_ != 0) { @@ -2783,9 +2813,9 @@ void StoryManager::edit_story(StoryId story_id, td_api::object_ptr(); new_story->content_ = dup_story_content(td_, edited_story->content_.get()); - auto pending_story = td::make_unique(dialog_id, story_id, 0 /*log_event_id*/, - std::numeric_limits::max() - (++send_story_count_), - story->edit_generation_, std::move(new_story)); + auto pending_story = + td::make_unique(dialog_id, story_id, std::numeric_limits::max() - (++send_story_count_), + story->edit_generation_, std::move(new_story)); on_story_changed(story_full_id, story, true, true); @@ -2969,6 +2999,7 @@ void StoryManager::on_binlog_events(vector &&events) { if (G()->close_flag()) { return; } + bool have_old_message_database = G()->use_message_database() && !G()->td_db()->was_dialog_db_created(); for (auto &event : events) { CHECK(event.id_ != 0); switch (event.type_) { @@ -3018,6 +3049,39 @@ void StoryManager::on_binlog_events(vector &&events) { load_dialog_expiring_stories(dialog_id, event.id_, "LoadDialogExpiringStoriesLogEvent"); break; } + case LogEvent::HandlerType::SendStory: { + if (!have_old_message_database) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + SendStoryLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto pending_story = std::move(log_event.pending_story_out); + pending_story->log_event_id_ = event.id_; + + CHECK(pending_story->story_->content_ != nullptr); + if (pending_story->story_->content_->get_type() == StoryContentType::Unsupported) { + LOG(ERROR) << "Sent story content is invalid: " << format::as_hex_dump<4>(event.get_data()); + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + Dependencies dependencies; + add_pending_story_dependencies(dependencies, pending_story.get()); + if (!dependencies.resolve_force(td_, "SendStoryLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + ++send_story_count_; + CHECK(!pending_story->story_id_.is_server()); + pending_story->send_story_num_ = send_story_count_; + pending_story->story_->content_ = dup_story_content(td_, pending_story->story_->content_.get()); + do_send_story(std::move(pending_story), {}); + break; + } default: LOG(FATAL) << "Unsupported log event type " << event.type_; } diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index 855deb010..664e26a1e 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -87,7 +87,7 @@ class StoryManager final : public Actor { PendingStory() = default; - PendingStory(DialogId dialog_id, StoryId story_id, uint64 log_event_id, uint32 send_story_num, int64 random_id, + PendingStory(DialogId dialog_id, StoryId story_id, uint32 send_story_num, int64 random_id, unique_ptr &&story); template @@ -232,6 +232,7 @@ class StoryManager final : public Actor { class DeleteStoryOnServerLogEvent; class ReadStoriesOnServerLogEvent; class LoadDialogExpiringStoriesLogEvent; + class SendStoryLogEvent; static constexpr int32 OPENED_STORY_POLL_PERIOD = 60; static constexpr int32 VIEWED_STORY_POLL_PERIOD = 300; @@ -339,6 +340,8 @@ class StoryManager final : public Actor { void on_reload_story(StoryFullId story_full_id, Result &&result); + int64 save_send_story_log_event(const PendingStory *pending_story); + static void delete_pending_story(unique_ptr &&pending_story); void do_send_story(unique_ptr &&pending_story, vector bad_parts); diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index 4dc9b76c9..ae019b1d2 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -129,6 +129,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::DeleteStoryOnServer: case LogEvent::HandlerType::ReadStoriesOnServer: case LogEvent::HandlerType::LoadDialogExpiringStories: + case LogEvent::HandlerType::SendStory: events.to_story_manager.push_back(event.clone()); break; case LogEvent::HandlerType::UpdateScopeNotificationSettingsOnServer: diff --git a/td/telegram/logevent/LogEvent.h b/td/telegram/logevent/LogEvent.h index 80f853129..e8a43e23d 100644 --- a/td/telegram/logevent/LogEvent.h +++ b/td/telegram/logevent/LogEvent.h @@ -110,6 +110,7 @@ class LogEvent { DeleteStoryOnServer = 0x400, ReadStoriesOnServer = 0x401, LoadDialogExpiringStories = 0x402, + SendStory = 0x403, ConfigPmcMagic = 0x1f18, BinlogPmcMagic = 0x4327 };