diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2021-03-22 01:30:51 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2021-03-22 01:30:51 -0400 |
commit | ac31bc6b94e422b929e63437696994b17002334d (patch) | |
tree | 37c68528ee257bb139a39e30a6668da5f00b3613 /discord | |
parent | 60404783bd4ce9be26233fe66fc3a74475d9eaa3 (diff) | |
download | abaddon-portaudio-ac31bc6b94e422b929e63437696994b17002334d.tar.gz abaddon-portaudio-ac31bc6b94e422b929e63437696994b17002334d.zip |
basic member verification for guilds that set rules
Diffstat (limited to 'discord')
-rw-r--r-- | discord/channel.hpp | 3 | ||||
-rw-r--r-- | discord/discord.cpp | 71 | ||||
-rw-r--r-- | discord/discord.hpp | 23 | ||||
-rw-r--r-- | discord/guild.cpp | 17 | ||||
-rw-r--r-- | discord/guild.hpp | 22 | ||||
-rw-r--r-- | discord/objects.cpp | 49 | ||||
-rw-r--r-- | discord/objects.hpp | 42 | ||||
-rw-r--r-- | discord/store.cpp | 2 |
8 files changed, 223 insertions, 6 deletions
diff --git a/discord/channel.hpp b/discord/channel.hpp index 7b0cf50..4f93569 100644 --- a/discord/channel.hpp +++ b/discord/channel.hpp @@ -14,6 +14,9 @@ enum class ChannelType : int { GUILD_CATEGORY = 4, GUILD_NEWS = 5, GUILD_STORE = 6, + PUBLIC_THREAD = 11, + PRIVATE_THREAD = 12, + GUILD_STAGE_VOICE = 13, }; struct ChannelData { diff --git a/discord/discord.cpp b/discord/discord.cpp index a16a119..6d481d2 100644 --- a/discord/discord.cpp +++ b/discord/discord.cpp @@ -631,6 +631,12 @@ void DiscordClient::DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::sl }); } +std::optional<GuildApplicationData> DiscordClient::GetGuildApplication(Snowflake guild_id) const { + const auto it = m_guild_join_requests.find(guild_id); + if (it == m_guild_join_requests.end()) return std::nullopt; + return it->second; +} + bool DiscordClient::CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const { const auto guild = *GetGuild(guild_id); if (guild.OwnerID == user_id) return true; @@ -753,6 +759,23 @@ void DiscordClient::FetchUserRelationships(Snowflake user_id, sigc::slot<void(st }); } +void DiscordClient::GetVerificationGateInfo(Snowflake guild_id, sigc::slot<void(std::optional<VerificationGateInfoObject>)> callback) { + m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/member-verification", [this, callback](const http::response_type &response) { + if (!CheckCode(response)) return; + if (response.status_code == 204) callback(std::nullopt); + callback(nlohmann::json::parse(response.text).get<VerificationGateInfoObject>()); + }); +} + +void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, sigc::slot<void(bool success)> callback) { + if (info.VerificationFields.has_value()) + for (auto &field : *info.VerificationFields) + field.Response = true; + m_http.MakePUT("/guilds/" + std::to_string(guild_id) + "/requests/@me", nlohmann::json(info).dump(), [this, callback](const http::response_type &response) { + callback(CheckCode(response)); + }); +} + void DiscordClient::UpdateToken(std::string token) { if (!IsStarted()) { m_token = token; @@ -949,6 +972,15 @@ void DiscordClient::HandleGatewayMessage(std::string str) { case GatewayEvent::GUILD_EMOJIS_UPDATE: { HandleGatewayGuildEmojisUpdate(m); } break; + case GatewayEvent::GUILD_JOIN_REQUEST_CREATE: { + HandleGatewayGuildJoinRequestCreate(m); + } break; + case GatewayEvent::GUILD_JOIN_REQUEST_UPDATE: { + HandleGatewayGuildJoinRequestUpdate(m); + } break; + case GatewayEvent::GUILD_JOIN_REQUEST_DELETE: { + HandleGatewayGuildJoinRequestDelete(m); + } break; } } break; default: @@ -1033,6 +1065,10 @@ void DiscordClient::HandleGatewayReady(const GatewayMessage &msg) { for (const auto &relationship : *data.Relationships) m_user_relationships[relationship.ID] = relationship.Type; + if (data.GuildJoinRequests.has_value()) + for (const auto &request : *data.GuildJoinRequests) + m_guild_join_requests[request.GuildID] = request; + m_store.EndTransaction(); m_session_id = data.SessionID; @@ -1361,6 +1397,24 @@ void DiscordClient::HandleGatewayGuildEmojisUpdate(const GatewayMessage &msg) { FetchGuildEmojis(data.GuildID, cb); } +void DiscordClient::HandleGatewayGuildJoinRequestCreate(const GatewayMessage &msg) { + GuildJoinRequestCreateData data = msg.Data; + m_guild_join_requests[data.GuildID] = data.Request; + m_signal_guild_join_request_create.emit(data); +} + +void DiscordClient::HandleGatewayGuildJoinRequestUpdate(const GatewayMessage &msg) { + GuildJoinRequestUpdateData data = msg.Data; + m_guild_join_requests[data.GuildID] = data.Request; + m_signal_guild_join_request_update.emit(data); +} + +void DiscordClient::HandleGatewayGuildJoinRequestDelete(const GatewayMessage &msg) { + GuildJoinRequestDeleteData data = msg.Data; + m_guild_join_requests.erase(data.GuildID); + m_signal_guild_join_request_delete.emit(data); +} + void DiscordClient::HandleGatewayReadySupplemental(const GatewayMessage &msg) { ReadySupplementalData data = msg.Data; for (const auto &p : data.MergedPresences.Friends) { @@ -1478,7 +1532,7 @@ void DiscordClient::HandleGatewayGuildCreate(const GatewayMessage &msg) { GuildData data = msg.Data; ProcessNewGuild(data); - m_signal_guild_create.emit(data.ID); + m_signal_guild_create.emit(data); } void DiscordClient::HandleGatewayGuildDelete(const GatewayMessage &msg) { @@ -1682,6 +1736,9 @@ void DiscordClient::LoadEventMap() { m_event_map["USER_NOTE_UPDATE"] = GatewayEvent::USER_NOTE_UPDATE; m_event_map["READY_SUPPLEMENTAL"] = GatewayEvent::READY_SUPPLEMENTAL; m_event_map["GUILD_EMOJIS_UPDATE"] = GatewayEvent::GUILD_EMOJIS_UPDATE; + m_event_map["GUILD_JOIN_REQUEST_CREATE"] = GatewayEvent::GUILD_JOIN_REQUEST_CREATE; + m_event_map["GUILD_JOIN_REQUEST_UPDATE"] = GatewayEvent::GUILD_JOIN_REQUEST_UPDATE; + m_event_map["GUILD_JOIN_REQUEST_DELETE"] = GatewayEvent::GUILD_JOIN_REQUEST_DELETE; } DiscordClient::type_signal_gateway_ready DiscordClient::signal_gateway_ready() { @@ -1791,3 +1848,15 @@ DiscordClient::type_signal_note_update DiscordClient::signal_note_update() { DiscordClient::type_signal_guild_emojis_update DiscordClient::signal_guild_emojis_update() { return m_signal_guild_emojis_update; } + +DiscordClient::type_signal_guild_join_request_create DiscordClient::signal_guild_join_request_create() { + return m_signal_guild_join_request_create; +} + +DiscordClient::type_signal_guild_join_request_update DiscordClient::signal_guild_join_request_update() { + return m_signal_guild_join_request_update; +} + +DiscordClient::type_signal_guild_join_request_delete DiscordClient::signal_guild_join_request_delete() { + return m_signal_guild_join_request_delete; +} diff --git a/discord/discord.hpp b/discord/discord.hpp index 476adc8..fbcdb5f 100644 --- a/discord/discord.hpp +++ b/discord/discord.hpp @@ -131,6 +131,7 @@ public: void ModifyRolePosition(Snowflake guild_id, Snowflake role_id, int position, sigc::slot<void(bool success)> callback); void ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, const Glib::ustring &name, sigc::slot<void(bool success)> callback); void DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::slot<void(bool success)> callback); + std::optional<GuildApplicationData> GetGuildApplication(Snowflake guild_id) const; bool CanModifyRole(Snowflake guild_id, Snowflake role_id) const; bool CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const; @@ -163,6 +164,9 @@ public: void SetUserNote(Snowflake user_id, std::string note, sigc::slot<void(bool success)> callback); void FetchUserRelationships(Snowflake user_id, sigc::slot<void(std::vector<UserData>)> callback); + void GetVerificationGateInfo(Snowflake guild_id, sigc::slot<void(std::optional<VerificationGateInfoObject>)> callback); + void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, sigc::slot<void(bool success)> callback); + void UpdateToken(std::string token); void SetUserAgent(std::string agent); @@ -209,6 +213,9 @@ private: void HandleGatewayInviteDelete(const GatewayMessage &msg); void HandleGatewayUserNoteUpdate(const GatewayMessage &msg); void HandleGatewayGuildEmojisUpdate(const GatewayMessage &msg); + void HandleGatewayGuildJoinRequestCreate(const GatewayMessage &msg); + void HandleGatewayGuildJoinRequestUpdate(const GatewayMessage &msg); + void HandleGatewayGuildJoinRequestDelete(const GatewayMessage &msg); void HandleGatewayReadySupplemental(const GatewayMessage &msg); void HandleGatewayReconnect(const GatewayMessage &msg); void HandleGatewayInvalidSession(const GatewayMessage &msg); @@ -233,6 +240,7 @@ private: std::unordered_map<Snowflake, std::unordered_set<Snowflake>> m_guild_to_users; std::unordered_map<Snowflake, std::unordered_set<Snowflake>> m_guild_to_channels; + std::unordered_map<Snowflake, GuildApplicationData> m_guild_join_requests; std::unordered_map<Snowflake, PresenceStatus> m_user_to_status; @@ -275,7 +283,7 @@ public: typedef sigc::signal<void, Snowflake, Snowflake> type_signal_message_delete; typedef sigc::signal<void, Snowflake, Snowflake> type_signal_message_update; typedef sigc::signal<void, Snowflake> type_signal_guild_member_list_update; - typedef sigc::signal<void, Snowflake> type_signal_guild_create; + typedef sigc::signal<void, GuildData> type_signal_guild_create; typedef sigc::signal<void, Snowflake> type_signal_guild_delete; typedef sigc::signal<void, Snowflake> type_signal_channel_delete; typedef sigc::signal<void, Snowflake> type_signal_channel_update; @@ -295,7 +303,10 @@ public: typedef sigc::signal<void, Snowflake, PresenceStatus> type_signal_presence_update; typedef sigc::signal<void, Snowflake, std::string> type_signal_note_update; typedef sigc::signal<void, Snowflake, std::vector<EmojiData>> type_signal_guild_emojis_update; // guild id - typedef sigc::signal<void, bool, GatewayCloseCode> type_signal_disconnected; // bool true if reconnecting + typedef sigc::signal<void, GuildJoinRequestCreateData> type_signal_guild_join_request_create; + typedef sigc::signal<void, GuildJoinRequestUpdateData> type_signal_guild_join_request_update; + typedef sigc::signal<void, GuildJoinRequestDeleteData> type_signal_guild_join_request_delete; + typedef sigc::signal<void, bool, GatewayCloseCode> type_signal_disconnected; // bool true if reconnecting typedef sigc::signal<void> type_signal_connected; type_signal_gateway_ready signal_gateway_ready(); @@ -303,7 +314,7 @@ public: type_signal_message_delete signal_message_delete(); type_signal_message_update signal_message_update(); type_signal_guild_member_list_update signal_guild_member_list_update(); - type_signal_guild_create signal_guild_create(); + type_signal_guild_create signal_guild_create(); // structs are complete in this signal type_signal_guild_delete signal_guild_delete(); type_signal_channel_delete signal_channel_delete(); type_signal_channel_update signal_channel_update(); @@ -323,6 +334,9 @@ public: type_signal_presence_update signal_presence_update(); type_signal_note_update signal_note_update(); type_signal_guild_emojis_update signal_guild_emojis_update(); + type_signal_guild_join_request_create signal_guild_join_request_create(); + type_signal_guild_join_request_update signal_guild_join_request_update(); + type_signal_guild_join_request_delete signal_guild_join_request_delete(); type_signal_disconnected signal_disconnected(); type_signal_connected signal_connected(); @@ -352,6 +366,9 @@ protected: type_signal_presence_update m_signal_presence_update; type_signal_note_update m_signal_note_update; type_signal_guild_emojis_update m_signal_guild_emojis_update; + type_signal_guild_join_request_create m_signal_guild_join_request_create; + type_signal_guild_join_request_update m_signal_guild_join_request_update; + type_signal_guild_join_request_delete m_signal_guild_join_request_delete; type_signal_disconnected m_signal_disconnected; type_signal_connected m_signal_connected; }; diff --git a/discord/guild.cpp b/discord/guild.cpp index 5fb524e..d387729 100644 --- a/discord/guild.cpp +++ b/discord/guild.cpp @@ -197,3 +197,20 @@ std::vector<RoleData> GuildData::FetchRoles() const { }); return ret; } + +void from_json(const nlohmann::json &j, GuildApplicationData &m) { + JS_D("user_id", m.UserID); + JS_D("guild_id", m.GuildID); + auto tmp = j.at("application_status").get<std::string_view>(); + if (tmp == "STARTED") + m.ApplicationStatus = GuildApplicationStatus::STARTED; + else if (tmp == "PENDING") + m.ApplicationStatus = GuildApplicationStatus::PENDING; + else if (tmp == "REJECTED") + m.ApplicationStatus = GuildApplicationStatus::REJECTED; + else if (tmp == "APPROVED") + m.ApplicationStatus = GuildApplicationStatus::APPROVED; + JS_N("rejection_reason", m.RejectionReason); + JS_N("last_seen", m.LastSeen); + JS_N("created_at", m.CreatedAt); +} diff --git a/discord/guild.hpp b/discord/guild.hpp index c2d7333..a57bc15 100644 --- a/discord/guild.hpp +++ b/discord/guild.hpp @@ -6,6 +6,26 @@ #include "emoji.hpp" #include <vector> #include <string> +#include <unordered_set> + +enum class GuildApplicationStatus { + STARTED, + PENDING, + REJECTED, + APPROVED, + UNKNOWN, +}; + +struct GuildApplicationData { + Snowflake UserID; + Snowflake GuildID; + GuildApplicationStatus ApplicationStatus; + std::optional<std::string> RejectionReason; + std::optional<std::string> LastSeen; + std::optional<std::string> CreatedAt; + + friend void from_json(const nlohmann::json &j, GuildApplicationData &m); +}; // a bot is apparently only supposed to receive the `id` and `unavailable` as false // but user tokens seem to get the full objects (minus users) @@ -32,7 +52,7 @@ struct GuildData { std::optional<int> ExplicitContentFilter; std::optional<std::vector<RoleData>> Roles; // only access id std::optional<std::vector<EmojiData>> Emojis; // only access id - std::optional<std::vector<std::string>> Features; + std::optional<std::unordered_set<std::string>> Features; std::optional<int> MFALevel; std::optional<Snowflake> ApplicationID; // null std::optional<bool> IsWidgetEnabled; diff --git a/discord/objects.cpp b/discord/objects.cpp index 3aef9ee..7d44ece 100644 --- a/discord/objects.cpp +++ b/discord/objects.cpp @@ -125,6 +125,7 @@ void from_json(const nlohmann::json &j, ReadyEventData &m) { JS_O("users", m.Users); JS_ON("merged_members", m.MergedMembers); JS_O("relationships", m.Relationships); + JS_O("guild_join_requests", m.GuildJoinRequests); } void from_json(const nlohmann::json &j, MergedPresence &m) { @@ -394,3 +395,51 @@ void from_json(const nlohmann::json &j, GuildEmojisUpdateObject &m) { void to_json(nlohmann::json &j, const ModifyGuildEmojiObject &m) { JS_IF("name", m.Name); } + +void from_json(const nlohmann::json &j, GuildJoinRequestCreateData &m) { + auto tmp = j.at("status").get<std::string_view>(); + if (tmp == "STARTED") + m.Status = GuildApplicationStatus::STARTED; + else if (tmp == "PENDING") + m.Status = GuildApplicationStatus::PENDING; + else if (tmp == "REJECTED") + m.Status = GuildApplicationStatus::REJECTED; + else if (tmp == "APPROVED") + m.Status = GuildApplicationStatus::APPROVED; + JS_D("request", m.Request); + JS_D("guild_id", m.GuildID); +} + +void from_json(const nlohmann::json &j, GuildJoinRequestDeleteData &m) { + JS_D("user_id", m.UserID); + JS_D("guild_id", m.GuildID); +} + +void from_json(const nlohmann::json &j, VerificationFieldObject &m) { + JS_D("field_type", m.Type); + JS_D("label", m.Label); + JS_D("required", m.Required); + JS_D("values", m.Values); +} + +void from_json(const nlohmann::json &j, VerificationGateInfoObject &m) { + JS_O("description", m.Description); + JS_O("form_fields", m.VerificationFields); + JS_O("version", m.Version); + JS_O("enabled", m.Enabled); +} + +void to_json(nlohmann::json &j, const VerificationFieldObject &m) { + j["field_type"] = m.Type; + j["label"] = m.Label; + j["required"] = m.Required; + j["values"] = m.Values; + JS_IF("response", m.Response); +} + +void to_json(nlohmann::json &j, const VerificationGateInfoObject &m) { + JS_IF("description", m.Description); + JS_IF("form_fields", m.VerificationFields); + JS_IF("version", m.Version); + JS_IF("enabled", m.Enabled); +} diff --git a/discord/objects.hpp b/discord/objects.hpp index 88cac21..bad9fd4 100644 --- a/discord/objects.hpp +++ b/discord/objects.hpp @@ -65,6 +65,9 @@ enum class GatewayEvent : int { USER_NOTE_UPDATE, READY_SUPPLEMENTAL, GUILD_EMOJIS_UPDATE, + GUILD_JOIN_REQUEST_CREATE, + GUILD_JOIN_REQUEST_UPDATE, + GUILD_JOIN_REQUEST_DELETE, }; enum class GatewayCloseCode : uint16_t { @@ -206,6 +209,7 @@ struct ReadyEventData { UserSettings Settings; std::optional<std::vector<std::vector<GuildMember>>> MergedMembers; std::optional<std::vector<RelationshipData>> Relationships; + std::optional<std::vector<GuildApplicationData>> GuildJoinRequests; // std::vector<Unknown> ConnectedAccounts; // opt // std::map<std::string, Unknown> Consents; // opt // std::vector<Unknown> Experiments; // opt @@ -555,3 +559,41 @@ struct ModifyGuildEmojiObject { friend void to_json(nlohmann::json &j, const ModifyGuildEmojiObject &m); }; + +struct GuildJoinRequestCreateData { + GuildApplicationStatus Status; + GuildApplicationData Request; + Snowflake GuildID; + + friend void from_json(const nlohmann::json &j, GuildJoinRequestCreateData &m); +}; + +using GuildJoinRequestUpdateData = GuildJoinRequestCreateData; + +struct GuildJoinRequestDeleteData { + Snowflake UserID; + Snowflake GuildID; + + friend void from_json(const nlohmann::json &j, GuildJoinRequestDeleteData &m); +}; + +struct VerificationFieldObject { + std::string Type; + std::string Label; + bool Required; + std::vector<std::string> Values; + std::optional<bool> Response; // present in client to server + + friend void from_json(const nlohmann::json &j, VerificationFieldObject &m); + friend void to_json(nlohmann::json &j, const VerificationFieldObject &m); +}; + +struct VerificationGateInfoObject { + std::optional<std::string> Description; + std::optional<std::vector<VerificationFieldObject>> VerificationFields; + std::optional<std::string> Version; + std::optional<bool> Enabled; // present only in client to server in modify gate + + friend void from_json(const nlohmann::json &j, VerificationGateInfoObject &m); + friend void to_json(nlohmann::json &j, const VerificationGateInfoObject &m); +}; diff --git a/discord/store.cpp b/discord/store.cpp index 44af4cd..6dcaabb 100644 --- a/discord/store.cpp +++ b/discord/store.cpp @@ -449,7 +449,7 @@ std::optional<GuildData> Store::GetGuild(Snowflake id) const { for (const auto &id : nlohmann::json::parse(tmp).get<std::vector<Snowflake>>()) ret.Emojis->emplace_back().ID = id; Get(m_get_guild_stmt, 14, tmp); - ret.Features = nlohmann::json::parse(tmp).get<std::vector<std::string>>(); + ret.Features = nlohmann::json::parse(tmp).get<std::unordered_set<std::string>>(); Get(m_get_guild_stmt, 15, ret.MFALevel); Get(m_get_guild_stmt, 16, ret.ApplicationID); Get(m_get_guild_stmt, 17, ret.IsWidgetEnabled); |