diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-12-15 01:51:49 -0500 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-12-15 01:51:49 -0500 |
commit | 2667a4b30dd346f70aa8ca1ee7994c559be6d2bb (patch) | |
tree | 0ff7113d5c30e465e83a330fc1f19bd803bcc68d /discord | |
parent | 0c313ce5e8e849bcbaf23fcdf86f31ea38475d0e (diff) | |
download | abaddon-portaudio-2667a4b30dd346f70aa8ca1ee7994c559be6d2bb.tar.gz abaddon-portaudio-2667a4b30dd346f70aa8ca1ee7994c559be6d2bb.zip |
display reactions + click to add/remove
Diffstat (limited to 'discord')
-rw-r--r-- | discord/discord.cpp | 118 | ||||
-rw-r--r-- | discord/discord.hpp | 10 | ||||
-rw-r--r-- | discord/emoji.cpp | 17 | ||||
-rw-r--r-- | discord/emoji.hpp | 1 | ||||
-rw-r--r-- | discord/message.cpp | 14 | ||||
-rw-r--r-- | discord/message.hpp | 12 | ||||
-rw-r--r-- | discord/objects.cpp | 17 | ||||
-rw-r--r-- | discord/objects.hpp | 23 | ||||
-rw-r--r-- | discord/store.cpp | 410 | ||||
-rw-r--r-- | discord/user.cpp | 7 | ||||
-rw-r--r-- | discord/user.hpp | 1 |
11 files changed, 427 insertions, 203 deletions
diff --git a/discord/discord.cpp b/discord/discord.cpp index 0746250..2151d86 100644 --- a/discord/discord.cpp +++ b/discord/discord.cpp @@ -411,6 +411,34 @@ std::optional<Snowflake> DiscordClient::FindDM(Snowflake user_id) { return std::nullopt; } +void DiscordClient::AddReaction(Snowflake id, Glib::ustring param) { + if (!param.is_ascii()) // means unicode param + param = Glib::uri_escape_string(param, "", false); + else { + const auto &tmp = m_store.GetEmoji(param); + if (tmp.has_value()) + param = tmp->Name + ":" + std::to_string(tmp->ID); + else + return; + } + Snowflake channel_id = m_store.GetMessage(id)->ChannelID; + m_http.MakePUT("/channels/" + std::to_string(channel_id) + "/messages/" + std::to_string(id) + "/reactions/" + param + "/@me", "", [](auto) {}); +} + +void DiscordClient::RemoveReaction(Snowflake id, Glib::ustring param) { + if (!param.is_ascii()) // means unicode param + param = Glib::uri_escape_string(param, "", false); + else { + const auto &tmp = m_store.GetEmoji(param); + if (tmp.has_value()) + param = tmp->Name + ":" + std::to_string(tmp->ID); + else + return; + } + Snowflake channel_id = m_store.GetMessage(id)->ChannelID; + m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/messages/" + std::to_string(id) + "/reactions/" + param + "/@me", [](auto) {}); +} + void DiscordClient::UpdateToken(std::string token) { if (!IsStarted()) { m_token = token; @@ -552,6 +580,12 @@ void DiscordClient::HandleGatewayMessage(std::string str) { case GatewayEvent::GUILD_ROLE_DELETE: { HandleGatewayGuildRoleDelete(m); } break; + case GatewayEvent::MESSAGE_REACTION_ADD: { + HandleGatewayMessageReactionAdd(m); + } break; + case GatewayEvent::MESSAGE_REACTION_REMOVE: { + HandleGatewayMessageReactionRemove(m); + } break; } } break; default: @@ -735,6 +769,80 @@ void DiscordClient::HandleGatewayGuildRoleDelete(const GatewayMessage &msg) { m_signal_role_delete.emit(data.RoleID); } +void DiscordClient::HandleGatewayMessageReactionAdd(const GatewayMessage &msg) { + MessageReactionAddObject data = msg.Data; + auto to = m_store.GetMessage(data.MessageID); + if (!to.has_value()) return; + if (!to->Reactions.has_value()) to->Reactions.emplace(); + // add if present + bool stock; + auto it = std::find_if(to->Reactions->begin(), to->Reactions->end(), [&](const ReactionData &x) { + if (data.Emoji.ID.IsValid() && x.Emoji.ID.IsValid()) { + stock = false; + return data.Emoji.ID == x.Emoji.ID; + } else { + stock = true; + return data.Emoji.Name == x.Emoji.Name; + } + }); + + if (it != to->Reactions->end()) { + it->Count++; + if (data.UserID == GetUserData().ID) + it->HasReactedWith = true; + m_store.SetMessage(data.MessageID, *to); + if (stock) + m_signal_reaction_add.emit(data.MessageID, data.Emoji.Name); + else + m_signal_reaction_add.emit(data.MessageID, std::to_string(data.Emoji.ID)); + return; + } + + // create new + auto &rdata = to->Reactions->emplace_back(); + rdata.Count = 1; + rdata.Emoji = data.Emoji; + rdata.HasReactedWith = data.UserID == GetUserData().ID; + m_store.SetMessage(data.MessageID, *to); + if (stock) + m_signal_reaction_add.emit(data.MessageID, data.Emoji.Name); + else + m_signal_reaction_add.emit(data.MessageID, std::to_string(data.Emoji.ID)); +} + +void DiscordClient::HandleGatewayMessageReactionRemove(const GatewayMessage &msg) { + MessageReactionRemoveObject data = msg.Data; + auto to = m_store.GetMessage(data.MessageID); + if (!to.has_value()) return; + if (!to->Reactions.has_value()) return; + bool stock; + auto it = std::find_if(to->Reactions->begin(), to->Reactions->end(), [&](const ReactionData &x) { + if (data.Emoji.ID.IsValid() && x.Emoji.ID.IsValid()) { + stock = false; + return data.Emoji.ID == x.Emoji.ID; + } else { + stock = true; + return data.Emoji.Name == x.Emoji.Name; + } + }); + if (it == to->Reactions->end()) return; + + if (it->Count == 1) + to->Reactions->erase(it); + else { + if (data.UserID == GetUserData().ID) + it->HasReactedWith = false; + it->Count--; + } + + m_store.SetMessage(data.MessageID, *to); + + if (stock) + m_signal_reaction_remove.emit(data.MessageID, data.Emoji.Name); + else + m_signal_reaction_remove.emit(data.MessageID, std::to_string(data.Emoji.ID)); +} + void DiscordClient::HandleGatewayReconnect(const GatewayMessage &msg) { m_signal_disconnected.emit(true); inflateEnd(&m_zstream); @@ -928,6 +1036,8 @@ void DiscordClient::LoadEventMap() { m_event_map["GUILD_ROLE_UPDATE"] = GatewayEvent::GUILD_ROLE_UPDATE; m_event_map["GUILD_ROLE_CREATE"] = GatewayEvent::GUILD_ROLE_CREATE; m_event_map["GUILD_ROLE_DELETE"] = GatewayEvent::GUILD_ROLE_DELETE; + m_event_map["MESSAGE_REACTION_ADD"] = GatewayEvent::MESSAGE_REACTION_ADD; + m_event_map["MESSAGE_REACTION_REMOVE"] = GatewayEvent::MESSAGE_REACTION_REMOVE; } DiscordClient::type_signal_gateway_ready DiscordClient::signal_gateway_ready() { @@ -993,3 +1103,11 @@ DiscordClient::type_signal_role_create DiscordClient::signal_role_create() { DiscordClient::type_signal_role_delete DiscordClient::signal_role_delete() { return m_signal_role_delete; } + +DiscordClient::type_signal_reaction_add DiscordClient::signal_reaction_add() { + return m_signal_reaction_add; +} + +DiscordClient::type_signal_reaction_remove DiscordClient::signal_reaction_remove() { + return m_signal_reaction_remove; +} diff --git a/discord/discord.hpp b/discord/discord.hpp index c2b4bb0..767cf7a 100644 --- a/discord/discord.hpp +++ b/discord/discord.hpp @@ -108,6 +108,8 @@ public: void UpdateStatus(const std::string &status, bool is_afk, const Activity &obj); void CreateDM(Snowflake user_id); std::optional<Snowflake> FindDM(Snowflake user_id); // wont find group dms + void AddReaction(Snowflake id, Glib::ustring param); + void RemoveReaction(Snowflake id, Glib::ustring param); void UpdateToken(std::string token); void SetUserAgent(std::string agent); @@ -140,6 +142,8 @@ private: void HandleGatewayGuildRoleUpdate(const GatewayMessage &msg); void HandleGatewayGuildRoleCreate(const GatewayMessage &msg); void HandleGatewayGuildRoleDelete(const GatewayMessage &msg); + void HandleGatewayMessageReactionAdd(const GatewayMessage &msg); + void HandleGatewayMessageReactionRemove(const GatewayMessage &msg); void HandleGatewayReconnect(const GatewayMessage &msg); void HeartbeatThread(); void SendIdentify(); @@ -202,6 +206,8 @@ public: typedef sigc::signal<void, Snowflake> type_signal_role_update; typedef sigc::signal<void, Snowflake> type_signal_role_create; typedef sigc::signal<void, Snowflake> type_signal_role_delete; + typedef sigc::signal<void, Snowflake, Glib::ustring> type_signal_reaction_add; + typedef sigc::signal<void, Snowflake, Glib::ustring> type_signal_reaction_remove; typedef sigc::signal<void, bool> type_signal_disconnected; // bool true if reconnecting typedef sigc::signal<void> type_signal_connected; @@ -219,6 +225,8 @@ public: type_signal_role_update signal_role_update(); type_signal_role_create signal_role_create(); type_signal_role_delete signal_role_delete(); + type_signal_reaction_add signal_reaction_add(); + type_signal_reaction_remove signal_reaction_remove(); type_signal_disconnected signal_disconnected(); type_signal_connected signal_connected(); @@ -237,6 +245,8 @@ protected: type_signal_role_update m_signal_role_update; type_signal_role_create m_signal_role_create; type_signal_role_delete m_signal_role_delete; + type_signal_reaction_add m_signal_reaction_add; + type_signal_reaction_remove m_signal_reaction_remove; type_signal_disconnected m_signal_disconnected; type_signal_connected m_signal_connected; }; diff --git a/discord/emoji.cpp b/discord/emoji.cpp index 1804945..2525b57 100644 --- a/discord/emoji.cpp +++ b/discord/emoji.cpp @@ -11,6 +11,23 @@ void from_json(const nlohmann::json &j, Emoji &m) { JS_O("available", m.IsAvailable); } +void to_json(nlohmann::json &j, const Emoji &m) { + if (m.ID.IsValid()) + j["id"] = m.ID; + else + j["id"] = nullptr; + if (m.Name != "") + j["name"] = m.Name; + else + j["name"] = nullptr; + JS_IF("roles", m.Roles); + JS_IF("user", m.Creator); + JS_IF("require_colons", m.NeedsColons); + JS_IF("managed", m.IsManaged); + JS_IF("animated", m.IsAnimated); + JS_IF("available", m.IsAvailable); +} + std::string Emoji::GetURL() const { return "https://cdn.discordapp.com/emojis/" + std::to_string(ID) + ".png"; } diff --git a/discord/emoji.hpp b/discord/emoji.hpp index 18e69d3..71eb83a 100644 --- a/discord/emoji.hpp +++ b/discord/emoji.hpp @@ -16,6 +16,7 @@ struct Emoji { std::optional<bool> IsAvailable; friend void from_json(const nlohmann::json &j, Emoji &m); + friend void to_json(nlohmann::json &j, const Emoji &m); std::string GetURL() const; static std::string URLFromID(std::string emoji_id); diff --git a/discord/message.cpp b/discord/message.cpp index d0f2082..c0e91c1 100644 --- a/discord/message.cpp +++ b/discord/message.cpp @@ -152,6 +152,18 @@ void to_json(nlohmann::json &j, const MessageReferenceData &m) { JS_IF("guild_id", m.GuildID); } +void from_json(const nlohmann::json &j, ReactionData &m) { + JS_D("count", m.Count); + JS_D("me", m.HasReactedWith); + JS_D("emoji", m.Emoji); +} + +void to_json(nlohmann::json &j, const ReactionData &m) { + j["count"] = m.Count; + j["me"] = m.HasReactedWith; + j["emoji"] = m.Emoji; +} + void from_json(const nlohmann::json &j, Message &m) { JS_D("id", m.ID); JS_D("channel_id", m.ChannelID); @@ -170,7 +182,7 @@ void from_json(const nlohmann::json &j, Message &m) { // JS_O("mention_channels", m.MentionChannels); JS_D("attachments", m.Attachments); JS_D("embeds", m.Embeds); - // JS_O("reactions", m.Reactions); + JS_O("reactions", m.Reactions); JS_O("nonce", m.Nonce); JS_D("pinned", m.IsPinned); JS_O("webhook_id", m.WebhookID); diff --git a/discord/message.hpp b/discord/message.hpp index 99c58ab..4de9235 100644 --- a/discord/message.hpp +++ b/discord/message.hpp @@ -3,6 +3,7 @@ #include "json.hpp" #include "user.hpp" #include "sticker.hpp" +#include "emoji.hpp" #include <string> #include <vector> @@ -140,6 +141,15 @@ struct MessageReferenceData { friend void to_json(nlohmann::json &j, const MessageReferenceData &m); }; +struct ReactionData { + int Count; + bool HasReactedWith; + Emoji Emoji; + + friend void from_json(const nlohmann::json &j, ReactionData &m); + friend void to_json(nlohmann::json &j, const ReactionData &m); +}; + struct Message { Snowflake ID; Snowflake ChannelID; @@ -156,7 +166,7 @@ struct Message { // std::optional<std::vector<ChannelMentionData>> MentionChannels; std::vector<AttachmentData> Attachments; std::vector<EmbedData> Embeds; - // std::optional<std::vector<ReactionData>> Reactions; + std::optional<std::vector<ReactionData>> Reactions; std::optional<std::string> Nonce; bool IsPinned; std::optional<Snowflake> WebhookID; diff --git a/discord/objects.cpp b/discord/objects.cpp index 5fad61e..35cb856 100644 --- a/discord/objects.cpp +++ b/discord/objects.cpp @@ -216,3 +216,20 @@ void from_json(const nlohmann::json &j, GuildRoleDeleteObject &m) { JS_D("guild_id", m.GuildID); JS_D("role_id", m.RoleID); } + +void from_json(const nlohmann::json &j, MessageReactionAddObject &m) { + JS_D("user_id", m.UserID); + JS_D("channel_id", m.ChannelID); + JS_D("message_id", m.MessageID); + JS_O("guild_id", m.GuildID); + JS_O("member", m.Member); + JS_D("emoji", m.Emoji); +} + +void from_json(const nlohmann::json &j, MessageReactionRemoveObject &m) { + JS_D("user_id", m.UserID); + JS_D("channel_id", m.ChannelID); + JS_D("message_id", m.MessageID); + JS_O("guild_id", m.GuildID); + JS_D("emoji", m.Emoji); +} diff --git a/discord/objects.hpp b/discord/objects.hpp index 2213ba5..a3877a7 100644 --- a/discord/objects.hpp +++ b/discord/objects.hpp @@ -49,6 +49,8 @@ enum class GatewayEvent : int { GUILD_ROLE_UPDATE, GUILD_ROLE_CREATE, GUILD_ROLE_DELETE, + MESSAGE_REACTION_ADD, + MESSAGE_REACTION_REMOVE, }; struct GatewayMessage { @@ -298,3 +300,24 @@ struct GuildRoleDeleteObject { friend void from_json(const nlohmann::json &j, GuildRoleDeleteObject &m); }; + +struct MessageReactionAddObject { + Snowflake UserID; + Snowflake ChannelID; + Snowflake MessageID; + std::optional<Snowflake> GuildID; + std::optional<GuildMember> Member; + Emoji Emoji; + + friend void from_json(const nlohmann::json &j, MessageReactionAddObject &m); +}; + +struct MessageReactionRemoveObject { + Snowflake UserID; + Snowflake ChannelID; + Snowflake MessageID; + std::optional<Snowflake> GuildID; + Emoji Emoji; + + friend void from_json(const nlohmann::json &j, MessageReactionRemoveObject &m); +}; diff --git a/discord/store.cpp b/discord/store.cpp index 8c5b40e..bf6318a 100644 --- a/discord/store.cpp +++ b/discord/store.cpp @@ -219,9 +219,13 @@ void Store::SetMessage(Snowflake id, const Message &message) { Bind(m_set_msg_stmt, 18, tmp); } else Bind(m_set_msg_stmt, 18, nullptr); - - Bind(m_set_msg_stmt, 19, message.IsDeleted()); - Bind(m_set_msg_stmt, 20, message.IsEdited()); + if (message.Reactions.has_value()) { + std::string tmp = nlohmann::json(*message.Reactions).dump(); + Bind(m_set_msg_stmt, 19, tmp); + } else + Bind(m_set_msg_stmt, 19, nullptr); + Bind(m_set_msg_stmt, 20, message.IsDeleted()); + Bind(m_set_msg_stmt, 21, message.IsEdited()); if (!RunInsert(m_set_msg_stmt)) fprintf(stderr, "message insert failed: %s\n", sqlite3_errstr(m_db_err)); @@ -468,10 +472,13 @@ std::optional<Message> Store::GetMessage(Snowflake id) const { Get(m_get_msg_stmt, 17, tmps); if (tmps != "") ret.Stickers = nlohmann::json::parse(tmps).get<std::vector<Sticker>>(); + Get(m_get_msg_stmt, 18, tmps); + if (tmps != "") + ret.Reactions = nlohmann::json::parse(tmps).get<std::vector<ReactionData>>(); bool tmpb = false; - Get(m_get_msg_stmt, 18, tmpb); - if (tmpb) ret.SetDeleted(); Get(m_get_msg_stmt, 19, tmpb); + if (tmpb) ret.SetDeleted(); + Get(m_get_msg_stmt, 20, tmpb); if (tmpb) ret.SetEdited(); Reset(m_get_msg_stmt); @@ -589,164 +596,165 @@ void Store::EndTransaction() { bool Store::CreateTables() { constexpr const char *create_users = R"( -CREATE TABLE IF NOT EXISTS users ( -id INTEGER PRIMARY KEY, -username TEXT NOT NULL, -discriminator TEXT NOT NULL, -avatar TEXT, -bot BOOL, -system BOOL, -mfa BOOL, -locale TEXT, -verified BOOl, -email TEXT, -flags INTEGER, -premium INTEGER, -pubflags INTEGER -) -)"; + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY, + username TEXT NOT NULL, + discriminator TEXT NOT NULL, + avatar TEXT, + bot BOOL, + system BOOL, + mfa BOOL, + locale TEXT, + verified BOOl, + email TEXT, + flags INTEGER, + premium INTEGER, + pubflags INTEGER + ) + )"; constexpr const char *create_permissions = R"( -CREATE TABLE IF NOT EXISTS permissions ( -id INTEGER NOT NULL, -channel_id INTEGER NOT NULL, -type INTEGER NOT NULL, -allow INTEGER NOT NULL, -deny INTEGER NOT NULL -) -)"; + CREATE TABLE IF NOT EXISTS permissions ( + id INTEGER NOT NULL, + channel_id INTEGER NOT NULL, + type INTEGER NOT NULL, + allow INTEGER NOT NULL, + deny INTEGER NOT NULL + ) + )"; constexpr const char *create_messages = R"( -CREATE TABLE IF NOT EXISTS messages ( -id INTEGER PRIMARY KEY, -channel_id INTEGER NOT NULL, -guild_id INTEGER, -author_id INTEGER NOT NULL, -content TEXT NOT NULL, -timestamp TEXT NOT NULL, -edited_timestamp TEXT, -tts BOOL NOT NULL, -everyone BOOL NOT NULL, -mentions TEXT NOT NULL, /* json */ -attachments TEXT NOT NULL, /* json */ -embeds TEXT NOT NULL, /* json */ -pinned BOOL, -webhook_id INTEGER, -type INTEGER, -reference TEXT, /* json */ -flags INTEGER, -stickers TEXT, /* json */ -/* extra */ -deleted BOOL, -edited BOOL -) -)"; + CREATE TABLE IF NOT EXISTS messages ( + id INTEGER PRIMARY KEY, + channel_id INTEGER NOT NULL, + guild_id INTEGER, + author_id INTEGER NOT NULL, + content TEXT NOT NULL, + timestamp TEXT NOT NULL, + edited_timestamp TEXT, + tts BOOL NOT NULL, + everyone BOOL NOT NULL, + mentions TEXT NOT NULL, /* json */ + attachments TEXT NOT NULL, /* json */ + embeds TEXT NOT NULL, /* json */ + pinned BOOL, + webhook_id INTEGER, + type INTEGER, + reference TEXT, /* json */ + flags INTEGER, + stickers TEXT, /* json */ + reactions TEXT, /* json */ + /* extra */ + deleted BOOL, + edited BOOL + ) + )"; constexpr const char *create_roles = R"( -CREATE TABLE IF NOT EXISTS roles ( -id INTEGER PRIMARY KEY, -name TEXT NOT NULL, -color INTEGER NOT NULL, -hoisted BOOL NOT NULL, -position INTEGER NOT NULL, -permissions INTEGER NOT NULL, -managed BOOL NOT NULL, -mentionable BOOL NOT NULL -) -)"; + CREATE TABLE IF NOT EXISTS roles ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + color INTEGER NOT NULL, + hoisted BOOL NOT NULL, + position INTEGER NOT NULL, + permissions INTEGER NOT NULL, + managed BOOL NOT NULL, + mentionable BOOL NOT NULL + ) + )"; constexpr const char *create_emojis = R"( -CREATE TABLE IF NOT EXISTS emojis ( -id INTEGER PRIMARY KEY, /*though nullable, only custom emojis (with non-null ids) are stored*/ -name TEXT NOT NULL, /*same as id*/ -roles TEXT, /* json */ -creator_id INTEGER, -colons BOOL, -managed BOOL, -animated BOOL, -available BOOL -) -)"; + CREATE TABLE IF NOT EXISTS emojis ( + id INTEGER PRIMARY KEY, /*though nullable, only custom emojis (with non-null ids) are stored*/ + name TEXT NOT NULL, /*same as id*/ + roles TEXT, /* json */ + creator_id INTEGER, + colons BOOL, + managed BOOL, + animated BOOL, + available BOOL + ) + )"; constexpr const char *create_members = R"( -CREATE TABLE IF NOT EXISTS members ( -user_id INTEGER PRIMARY KEY, -guild_id INTEGER NOT NULL, -nickname TEXT, -roles TEXT NOT NULL, /* json */ -joined_at TEXT NOT NULL, -premium_since TEXT, -deaf BOOL NOT NULL, -mute BOOL NOT NULL -) -)"; - - constexpr char *create_guilds = R"( -CREATE TABLE IF NOT EXISTS guilds ( -id INTEGER PRIMARY KEY, -name TEXT NOT NULL, -icon TEXT NOT NULL, -splash TEXT, -owner BOOL, -owner_id INTEGER NOT NULL, -permissions INTEGER, /* new */ -voice_region TEXT, -afk_id INTEGER, -afk_timeout INTEGER NOT NULL, -verification INTEGER NOT NULL, -notifications INTEGER NOT NULL, -roles TEXT NOT NULL, /* json */ -emojis TEXT NOT NULL, /* json */ -features TEXT NOT NULL, /* json */ -mfa INTEGER NOT NULL, -application INTEGER, -widget BOOL, -widget_channel INTEGER, -system_flags INTEGER NOT NULL, -rules_channel INTEGER, -joined_at TEXT, -large BOOL, -unavailable BOOL, -member_count INTEGER, -channels TEXT NOT NULL, /* json */ -max_presences INTEGER, -max_members INTEGER, -vanity TEXT, -description TEXT, -banner_hash TEXT, -premium_tier INTEGER NOT NULL, -premium_count INTEGER, -locale TEXT NOT NULL, -public_updates_id INTEGER, -max_video_users INTEGER, -approx_members INTEGER, -approx_presences INTEGER, -lazy BOOL -) -)"; - - constexpr char *create_channels = R"( -CREATE TABLE IF NOT EXISTS channels ( -id INTEGER PRIMARY KEY, -type INTEGER NOT NULL, -guild_id INTEGER, -position INTEGER, -overwrites TEXT, /* json */ -name TEXT, -topic TEXT, -is_nsfw BOOL, -last_message_id INTEGER, -bitrate INTEGER, -user_limit INTEGER, -rate_limit INTEGER, -recipients TEXT, /* json */ -icon TEXT, -owner_id INTEGER, -application_id INTEGER, -parent_id INTEGER, -last_pin_timestamp TEXT -) -)"; + CREATE TABLE IF NOT EXISTS members ( + user_id INTEGER PRIMARY KEY, + guild_id INTEGER NOT NULL, + nickname TEXT, + roles TEXT NOT NULL, /* json */ + joined_at TEXT NOT NULL, + premium_since TEXT, + deaf BOOL NOT NULL, + mute BOOL NOT NULL + ) + )"; + + constexpr const char *create_guilds = R"( + CREATE TABLE IF NOT EXISTS guilds ( + id INTEGER PRIMARY KEY, + name TEXT NOT NULL, + icon TEXT NOT NULL, + splash TEXT, + owner BOOL, + owner_id INTEGER NOT NULL, + permissions INTEGER, /* new */ + voice_region TEXT, + afk_id INTEGER, + afk_timeout INTEGER NOT NULL, + verification INTEGER NOT NULL, + notifications INTEGER NOT NULL, + roles TEXT NOT NULL, /* json */ + emojis TEXT NOT NULL, /* json */ + features TEXT NOT NULL, /* json */ + mfa INTEGER NOT NULL, + application INTEGER, + widget BOOL, + widget_channel INTEGER, + system_flags INTEGER NOT NULL, + rules_channel INTEGER, + joined_at TEXT, + large BOOL, + unavailable BOOL, + member_count INTEGER, + channels TEXT NOT NULL, /* json */ + max_presences INTEGER, + max_members INTEGER, + vanity TEXT, + description TEXT, + banner_hash TEXT, + premium_tier INTEGER NOT NULL, + premium_count INTEGER, + locale TEXT NOT NULL, + public_updates_id INTEGER, + max_video_users INTEGER, + approx_members INTEGER, + approx_presences INTEGER, + lazy BOOL + ) + )"; + + constexpr const char *create_channels = R"( + CREATE TABLE IF NOT EXISTS channels ( + id INTEGER PRIMARY KEY, + type INTEGER NOT NULL, + guild_id INTEGER, + position INTEGER, + overwrites TEXT, /* json */ + name TEXT, + topic TEXT, + is_nsfw BOOL, + last_message_id INTEGER, + bitrate INTEGER, + user_limit INTEGER, + rate_limit INTEGER, + recipients TEXT, /* json */ + icon TEXT, + owner_id INTEGER, + application_id INTEGER, + parent_id INTEGER, + last_pin_timestamp TEXT + ) + )"; m_db_err = sqlite3_exec(m_db, create_users, nullptr, nullptr, nullptr); if (m_db_err != SQLITE_OK) { @@ -801,84 +809,84 @@ last_pin_timestamp TEXT bool Store::CreateStatements() { constexpr const char *set_user = R"( -REPLACE INTO users VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO users VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_user = R"( -SELECT * FROM users WHERE id = ? -)"; + SELECT * FROM users WHERE id = ? + )"; constexpr const char *set_perm = R"( -REPLACE INTO permissions VALUES ( - ?, ?, ?, ?, ? -) -)"; + REPLACE INTO permissions VALUES ( + ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_perm = R"( -SELECT * FROM permissions WHERE id = ? AND channel_id = ? -)"; + SELECT * FROM permissions WHERE id = ? AND channel_id = ? + )"; constexpr const char *set_msg = R"( -REPLACE INTO messages VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO messages VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_msg = R"( -SELECT * FROM messages WHERE id = ? -)"; + SELECT * FROM messages WHERE id = ? + )"; constexpr const char *set_role = R"( -REPLACE INTO roles VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO roles VALUES ( + ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_role = R"( -SELECT * FROM roles WHERE id = ? -)"; + SELECT * FROM roles WHERE id = ? + )"; constexpr const char *set_emoji = R"( -REPLACE INTO emojis VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO emojis VALUES ( + ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_emoji = R"( -SELECT * FROM emojis WHERE id = ? -)"; + SELECT * FROM emojis WHERE id = ? + )"; constexpr const char *set_member = R"( -REPLACE INTO members VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO members VALUES ( + ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_member = R"( -SELECT * FROM members WHERE user_id = ? AND guild_id = ? -)"; + SELECT * FROM members WHERE user_id = ? AND guild_id = ? + )"; constexpr const char *set_guild = R"( -REPLACE INTO guilds VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO guilds VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_guild = R"( -SELECT * FROM guilds WHERE id = ? -)"; + SELECT * FROM guilds WHERE id = ? + )"; constexpr const char *set_chan = R"( -REPLACE INTO channels VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -) -)"; + REPLACE INTO channels VALUES ( + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ) + )"; constexpr const char *get_chan = R"( -SELECT * FROM channels WHERE id = ? -)"; + SELECT * FROM channels WHERE id = ? + )"; m_db_err = sqlite3_prepare_v2(m_db, set_user, -1, &m_set_user_stmt, nullptr); if (m_db_err != SQLITE_OK) { diff --git a/discord/user.cpp b/discord/user.cpp index 78d309b..56f0350 100644 --- a/discord/user.cpp +++ b/discord/user.cpp @@ -33,6 +33,13 @@ void from_json(const nlohmann::json &j, User &m) { JS_ON("phone", m.Phone); } +void to_json(nlohmann::json &j, const User &m) { + j["id"] = m.ID; + j["username"] = m.Username; + j["avatar"] = m.Avatar; + // rest of stuff as needed im too lazy and its probably not necessary +} + void User::update_from_json(const nlohmann::json &j, User &m) { JS_RD("username", m.Username); JS_RD("discriminator", m.Discriminator); diff --git a/discord/user.hpp b/discord/user.hpp index a34bd81..04817de 100644 --- a/discord/user.hpp +++ b/discord/user.hpp @@ -25,6 +25,7 @@ struct User { std::string Phone; // null? friend void from_json(const nlohmann::json &j, User &m); + friend void to_json(nlohmann::json &j, const User &m); static void update_from_json(const nlohmann::json &j, User &m); bool HasAvatar() const; |