From 812b1d99f4813791bcf47ccbfc591082459135c6 Mon Sep 17 00:00:00 2001 From: niansa Date: Sat, 7 Jan 2023 21:25:41 +0100 Subject: [PATCH] Properly handle timestamps --- dcboost | 2 +- main.cpp | 121 +++++++++++++++++++++++-------------------------------- 2 files changed, 51 insertions(+), 72 deletions(-) diff --git a/dcboost b/dcboost index 53b8c9a..2f77d0a 160000 --- a/dcboost +++ b/dcboost @@ -1 +1 @@ -Subproject commit 53b8c9ac5e7c670f0af03cc94aa6ba02f906ab03 +Subproject commit 2f77d0a9c0248a496be051cbe29f41d8091741bc diff --git a/main.cpp b/main.cpp index b906a5f..1be9eac 100644 --- a/main.cpp +++ b/main.cpp @@ -48,7 +48,7 @@ public: }; -struct MyClient final : public Discord::Client { +class MyClient final : public Discord::Client { sqlite::database db; Cache cache; @@ -77,7 +77,8 @@ public: " message_id TEXT NOT NULL," " is_initial INTEGER DEFAULT 1 NOT NULL," " timestamp TEXT NOT NULL," - " content TEXT NOT NULL" + " content TEXT NOT NULL," + " embed TEXT" // Discord JSON embed object ");"; db << "CREATE TABLE IF NOT EXISTS users (" " id TEXT NOT NULL," @@ -138,6 +139,7 @@ public: } } +protected: boost::asio::awaitable fetchAllGuilds(const Json::Value& unavailable_guild_array) { RandomGenerator rng; rng.seed(); @@ -173,25 +175,68 @@ public: << data["id"].asString() << std::to_string(time(nullptr)) << is_initial << data["name"].asString() << data["owner_id"].asString(); cache.store(data); } - void insertGuildLeave(const Json::Value& data) { + void insertGuildDelete(const Json::Value& data) { auto cached_data = cache.fetch(data["id"]); db << "INSERT OR IGNORE INTO guilds (id, timestamp, is_initial, name, owner_user_id, in_guild)" " VALUES (?, ?, 0, ?, ?, 0 );" << data["id"].asString() << std::to_string(time(nullptr)) << cached_data["name"].asString() << cached_data["owner_id"].asString(); } + void insertMessageContent(const Json::Value& data, bool is_initial) { + auto created_time = Discord::Utilities::TimestampToTimeT(data["timestamp"].asString()); + auto edited_time = Discord::Utilities::TimestampToTimeT(data["edited_timestamp"].asString()); + const auto& embed = data["embed"]; + db << "INSERT OR IGNORE INTO message_contents (message_id, is_initial, timestamp, content, embed)" + " VALUES (?, ?, ?, ?, ? );" + << data["id"].asString() << is_initial << std::to_string(edited_time?edited_time:created_time) << data["content"].asString() << (embed.isObject()?embed.toStyledString():std::optional()); + } + void insertMessageUpdate(const Json::Value& data, bool is_initial) { + if (is_initial) { + const auto& author = data["author"]; + int type = data["type"].asInt(); + auto created_time = Discord::Utilities::TimestampToTimeT(data["edited_timestamp"].asString()); + db << "INSERT OR IGNORE INTO messages (id, type, channel_id, author_id, replied_to_id, creation_timestamp)" + " VALUES (?, ?, ?, ?, ?, ? );" + << data["id"].asString() << type << data["channel_id"].asString() << author["id"].asString() << (type==19?data["referenced_message"]["id"].asString():std::optional()) << created_time; + if (!data["content"].asString().empty()) insertMessageContent(data, true); + cache.store(author); + } else { + if (!data["content"].asString().empty()) { + insertMessageContent(data, true); + db << "UPDATE messages " + "SET is_edited = 1 " + "WHERE id = ?;" + << data["id"].asString(); + } + } + } + void insertMessageDelete(const Json::Value& data) { + db << "UPDATE messages " + "SET is_deleted = 1 " + "WHERE id = ?;" + << data["id"].asString(); + } + virtual boost::asio::awaitable intentHandler(const std::string& intent, const Json::Value& data) override { if (intent == "READY") [[unlikely]] { const auto& user = cache.store(data["user"]); logger.log(Loglevel::info, "Connected to Discord as: "+user["username"].asString()+'#'+user["discriminator"].asString()); settings.is_bot = user["bot"].asBool(); co_await fetchAllGuilds(data["guilds"]); - } else if (intent == "GUILD_CREATE") [[unlikely]] { + } + else if (intent == "GUILD_CREATE") [[unlikely]] { insertGuildUpdate(data, true); } else if (intent == "GUILD_UPDATE") [[unlikely]] { insertGuildUpdate(data, false); } else if (intent == "GUILD_DELETE") [[unlikely]] { - insertGuildLeave(data); + insertGuildDelete(data); + } + else if (intent == "MESSAGE_CREATE") [[likely]] { + insertMessageUpdate(data, true); + } else if (intent == "MESSAGE_UPDATE") [[likely]] { + insertMessageUpdate(data, false); + } else if (intent == "MESSAGE_DELETE") { + insertMessageDelete(data); } co_return; } @@ -222,70 +267,4 @@ int main(int argc, char **argv) { io.run(); return EXIT_SUCCESS; - - - - /*// Initialize bot - dpp::cluster cluster("ODAyODYzNTU0MjY4NjI2OTY1.GsYaeE.Mzu8hrICXwcJMfDKnYssRMkRtDfX-r7zrQOCRI", dpp::i_all_intents); - - // Set up callbacks - // Useful: https://discord.com/developers/docs/topics/gateway-events - cluster.on_ready([&](const dpp::ready_t& event) { - std::cout << "Connected to Discord as " << cluster.me.format_username() << std::endl; - }); - - cluster.on_guild_create([&](const dpp::guild_create_t& event) { - std::cout << "Logging guild " << event.created->name << std::endl; - const auto guild = event.created; - db << "INSERT OR IGNORE INTO levels (id, timestamp, name, owner_user_id)" - " VALUES (?, ?, ?, ? );" - << std::to_string(guild->id) << std::to_string(time(nullptr)) << guild->name << std::to_string(guild->owner_id); - cache.store(guild->id, *guild); - }); - cluster.on_guild_update([&](const dpp::guild_update_t& event) { - const auto guild = event.updated; - db << "INSERT OR IGNORE INTO levels (id, timestamp, is_initial, name, owner_user_id)" - " VALUES (?, ?, 0, ?, ? );" - << std::to_string(guild->id) << std::to_string(time(nullptr)) << guild->name << std::to_string(guild->owner_id); - cache.store(guild->id, *guild); - }); - cluster.on_guild_delete([&](const dpp::guild_delete_t& event) { - const auto& guild = std::get(cache.fetch(event.deleted->id)); - db << "INSERT OR IGNORE INTO levels (id, timestamp, is_initial, name, owner_user_id)" - " VALUES (?, ?, 0, ?, ? );" - << std::to_string(guild.id) << std::to_string(time(nullptr)) << guild.name << std::to_string(guild.owner_id); - }); - - auto on_message_content = [&](const dpp::message& msg, bool is_initial) { - db << "INSERT OR IGNORE INTO message_contents (message_id, is_initial, timestamp, content)" - " VALUES (?, ?, ?, ? );" - << std::to_string(msg.id) << is_initial << std::to_string(msg.edited?msg.edited:msg.sent) << msg.content; - }; - cluster.on_message_create([&](const dpp::message_create_t& event) { - const auto& msg = event.msg; - db << "INSERT OR IGNORE INTO messages (id, type, channel_id, author_id, replied_to_id, creation_timestamp)" - " VALUES (?, ?, ?, ?, ?, ? );" - << std::to_string(msg.id) << std::to_string(msg.type) << std::to_string(msg.channel_id) << std::to_string(msg.author.id) << (msg.message_reference.message_id?std::optional(std::to_string(msg.message_reference.message_id)):nullptr) << std::to_string(msg.sent); - if (!msg.content.empty()) on_message_content(msg, true); - cache.store(msg.author.id, msg.author); - }); - cluster.on_message_update([&](const dpp::message_update_t& event) { - const auto& msg = event.msg; - if (!msg.content.empty()) { - on_message_content(msg, false); - db << "UPDATE messages " - "SET is_edited = 1 " - "WHERE id = ?;" - << std::to_string(msg.id);; - } - }); - cluster.on_message_delete([&](const dpp::message_delete_t& event) { - db << "UPDATE messages " - "SET is_deleted = 1 " - "WHERE id = ?;" - << std::to_string(event.deleted->id);; - }); - - // Run - cluster.start(false);*/ }