summaryrefslogtreecommitdiff
path: root/discord
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2020-10-19 20:35:10 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2020-10-19 20:35:10 -0400
commitcb73bba135933357878dc47f6e7a6bec3168d001 (patch)
tree0bcced1046c53b6322a6d680db4aca7edbc9371f /discord
parent49a6e581375fdf0b5f5e82f981ca2d7cb419267f (diff)
downloadabaddon-portaudio-cb73bba135933357878dc47f6e7a6bec3168d001.tar.gz
abaddon-portaudio-cb73bba135933357878dc47f6e7a6bec3168d001.zip
CHANNEL_CREATE, CHANNEL_UPDATE, CHANNEL_DELETE
Diffstat (limited to 'discord')
-rw-r--r--discord/channel.cpp20
-rw-r--r--discord/channel.hpp1
-rw-r--r--discord/discord.cpp60
-rw-r--r--discord/discord.hpp15
-rw-r--r--discord/guild.cpp51
-rw-r--r--discord/guild.hpp1
-rw-r--r--discord/json.hpp22
-rw-r--r--discord/objects.hpp3
8 files changed, 173 insertions, 0 deletions
diff --git a/discord/channel.cpp b/discord/channel.cpp
index d104337..b99971c 100644
--- a/discord/channel.cpp
+++ b/discord/channel.cpp
@@ -22,6 +22,26 @@ void from_json(const nlohmann::json &j, Channel &m) {
JS_ON("last_pin_timestamp", m.LastPinTimestamp);
}
+void Channel::update_from_json(const nlohmann::json &j) {
+ JS_RD("type", Type);
+ JS_RD("guild_id", GuildID);
+ JS_RV("position", Position, -1);
+ JS_RD("permission_overwrites", PermissionOverwrites);
+ JS_RD("name", Name);
+ JS_RD("topic", Topic);
+ JS_RD("nsfw", IsNSFW);
+ JS_RD("last_message_id", LastMessageID);
+ JS_RD("bitrate", Bitrate);
+ JS_RD("user_limit", UserLimit);
+ JS_RD("rate_limit_per_user", RateLimitPerUser);
+ JS_RD("recipients", Recipients);
+ JS_RD("icon", Icon);
+ JS_RD("owner_id", OwnerID);
+ JS_RD("application_id", ApplicationID);
+ JS_RD("parent_id", ParentID);
+ JS_RD("last_pin_timestamp", LastPinTimestamp);
+}
+
const PermissionOverwrite *Channel::GetOverwrite(Snowflake id) const {
return Abaddon::Get().GetDiscordClient().GetPermissionOverwrite(ID, id);
}
diff --git a/discord/channel.hpp b/discord/channel.hpp
index 7f2bcd0..845cffb 100644
--- a/discord/channel.hpp
+++ b/discord/channel.hpp
@@ -37,6 +37,7 @@ struct Channel {
std::string LastPinTimestamp; // opt, can be null even tho docs say otherwise
friend void from_json(const nlohmann::json &j, Channel &m);
+ void update_from_json(const nlohmann::json &j);
const PermissionOverwrite *GetOverwrite(Snowflake id) const;
};
diff --git a/discord/discord.cpp b/discord/discord.cpp
index c296aee..9f07259 100644
--- a/discord/discord.cpp
+++ b/discord/discord.cpp
@@ -246,6 +246,13 @@ std::unordered_set<Snowflake> DiscordClient::GetRolesInGuild(Snowflake id) const
return ret;
}
+std::unordered_set<Snowflake> DiscordClient::GetChannelsInGuild(Snowflake id) const {
+ auto it = m_guild_to_channels.find(id);
+ if (it != m_guild_to_channels.end())
+ return it->second;
+ return std::unordered_set<Snowflake>();
+}
+
bool DiscordClient::HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const {
const auto base = ComputePermissions(user_id, guild_id);
return (base & perm) == perm;
@@ -506,6 +513,15 @@ void DiscordClient::HandleGatewayMessage(std::string str) {
case GatewayEvent::PRESENCE_UPDATE: {
HandleGatewayPresenceUpdate(m);
} break;
+ case GatewayEvent::CHANNEL_DELETE: {
+ HandleGatewayChannelDelete(m);
+ } break;
+ case GatewayEvent::CHANNEL_UPDATE: {
+ HandleGatewayChannelUpdate(m);
+ } break;
+ case GatewayEvent::CHANNEL_CREATE: {
+ HandleGatewayChannelCreate(m);
+ } break;
}
} break;
default:
@@ -527,6 +543,7 @@ void DiscordClient::ProcessNewGuild(Guild &guild) {
for (auto &c : guild.Channels) {
c.GuildID = guild.ID;
m_store.SetChannel(c.ID, c);
+ m_guild_to_channels[guild.ID].insert(c.ID);
for (auto &p : c.PermissionOverwrites) {
m_store.SetPermissionOverwrite(c.ID, p.ID, p);
}
@@ -594,6 +611,34 @@ void DiscordClient::HandleGatewayPresenceUpdate(const GatewayMessage &msg) {
User::update_from_json(data.User, *cur);
}
+void DiscordClient::HandleGatewayChannelDelete(const GatewayMessage &msg) {
+ const auto id = msg.Data.at("id").get<Snowflake>();
+ const auto *channel = GetChannel(id);
+ auto it = m_guild_to_channels.find(channel->GuildID);
+ if (it != m_guild_to_channels.end())
+ it->second.erase(id);
+ m_store.ClearChannel(id);
+ m_signal_channel_delete.emit(id);
+}
+
+void DiscordClient::HandleGatewayChannelUpdate(const GatewayMessage &msg) {
+ const auto id = msg.Data.at("id").get<Snowflake>();
+ auto *cur = m_store.GetChannel(id);
+ if (cur != nullptr) {
+ cur->update_from_json(msg.Data);
+ m_signal_channel_update.emit(id);
+ }
+}
+
+void DiscordClient::HandleGatewayChannelCreate(const GatewayMessage &msg) {
+ Channel data = msg.Data;
+ m_store.SetChannel(data.ID, data);
+ m_guild_to_channels[data.GuildID].insert(data.ID);
+ for (const auto &p : data.PermissionOverwrites)
+ m_store.SetPermissionOverwrite(data.ID, p.ID, p);
+ m_signal_channel_create.emit(data.ID);
+}
+
void DiscordClient::HandleGatewayMessageUpdate(const GatewayMessage &msg) {
Snowflake id = msg.Data.at("id");
@@ -723,6 +768,9 @@ void DiscordClient::LoadEventMap() {
m_event_map["MESSAGE_DELETE_BULK"] = GatewayEvent::MESSAGE_DELETE_BULK;
m_event_map["GUILD_MEMBER_UPDATE"] = GatewayEvent::GUILD_MEMBER_UPDATE;
m_event_map["PRESENCE_UPDATE"] = GatewayEvent::PRESENCE_UPDATE;
+ m_event_map["CHANNEL_DELETE"] = GatewayEvent::CHANNEL_DELETE;
+ m_event_map["CHANNEL_UPDATE"] = GatewayEvent::CHANNEL_UPDATE;
+ m_event_map["CHANNEL_CREATE"] = GatewayEvent::CHANNEL_CREATE;
}
DiscordClient::type_signal_gateway_ready DiscordClient::signal_gateway_ready() {
@@ -756,3 +804,15 @@ DiscordClient::type_signal_guild_create DiscordClient::signal_guild_create() {
DiscordClient::type_signal_guild_delete DiscordClient::signal_guild_delete() {
return m_signal_guild_delete;
}
+
+DiscordClient::type_signal_channel_delete DiscordClient::signal_channel_delete() {
+ return m_signal_channel_delete;
+}
+
+DiscordClient::type_signal_channel_update DiscordClient::signal_channel_update() {
+ return m_signal_channel_update;
+}
+
+DiscordClient::type_signal_channel_create DiscordClient::signal_channel_create() {
+ return m_signal_channel_create;
+}
diff --git a/discord/discord.hpp b/discord/discord.hpp
index 76a64af..240bd1e 100644
--- a/discord/discord.hpp
+++ b/discord/discord.hpp
@@ -87,6 +87,7 @@ public:
Snowflake GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const;
std::unordered_set<Snowflake> GetUsersInGuild(Snowflake id) const;
std::unordered_set<Snowflake> GetRolesInGuild(Snowflake id) const;
+ std::unordered_set<Snowflake> GetChannelsInGuild(Snowflake id) const;
bool HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const;
bool HasChannelPermission(Snowflake user_id, Snowflake channel_id, Permission perm) const;
@@ -125,6 +126,9 @@ private:
void HandleGatewayMessageDeleteBulk(const GatewayMessage &msg);
void HandleGatewayGuildMemberUpdate(const GatewayMessage &msg);
void HandleGatewayPresenceUpdate(const GatewayMessage &msg);
+ void HandleGatewayChannelDelete(const GatewayMessage &msg);
+ void HandleGatewayChannelUpdate(const GatewayMessage &msg);
+ void HandleGatewayChannelCreate(const GatewayMessage &msg);
void HeartbeatThread();
void SendIdentify();
@@ -138,6 +142,8 @@ private:
void AddUserToGuild(Snowflake user_id, Snowflake guild_id);
std::unordered_map<Snowflake, std::unordered_set<Snowflake>> m_guild_to_users;
+ std::unordered_map<Snowflake, std::unordered_set<Snowflake>> m_guild_to_channels;
+
User m_user_data;
UserSettings m_user_settings;
@@ -171,6 +177,9 @@ public:
typedef sigc::signal<void, Snowflake> type_signal_guild_member_list_update;
typedef sigc::signal<void, Snowflake> 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;
+ typedef sigc::signal<void, Snowflake> type_signal_channel_create;
type_signal_gateway_ready signal_gateway_ready();
type_signal_channel_list_refresh signal_channel_list_refresh();
@@ -180,6 +189,9 @@ public:
type_signal_guild_member_list_update signal_guild_member_list_update();
type_signal_guild_create signal_guild_create();
type_signal_guild_delete signal_guild_delete();
+ type_signal_channel_delete signal_channel_delete();
+ type_signal_channel_update signal_channel_update();
+ type_signal_channel_create signal_channel_create();
protected:
type_signal_gateway_ready m_signal_gateway_ready;
@@ -190,4 +202,7 @@ protected:
type_signal_guild_member_list_update m_signal_guild_member_list_update;
type_signal_guild_create m_signal_guild_create;
type_signal_guild_delete m_signal_guild_delete;
+ type_signal_channel_delete m_signal_channel_delete;
+ type_signal_channel_update m_signal_channel_update;
+ type_signal_channel_create m_signal_channel_create;
};
diff --git a/discord/guild.cpp b/discord/guild.cpp
index 602cdb2..5875a11 100644
--- a/discord/guild.cpp
+++ b/discord/guild.cpp
@@ -1,4 +1,5 @@
#include "guild.hpp"
+#include "../abaddon.hpp"
void from_json(const nlohmann::json &j, Guild &m) {
JS_D("id", m.ID);
@@ -64,3 +65,53 @@ bool Guild::HasIcon() const {
std::string Guild::GetIconURL(std::string ext, std::string size) const {
return "https://cdn.discordapp.com/icons/" + std::to_string(ID) + "/" + Icon + "." + ext + "?size=" + size;
}
+
+std::vector<Snowflake> Guild::GetSortedChannels(Snowflake ignore) const {
+ std::vector<Snowflake> ret;
+
+ const auto &discord = Abaddon::Get().GetDiscordClient();
+ auto channels = discord.GetChannelsInGuild(ID);
+
+ std::unordered_map<Snowflake, std::vector<const Channel *>> category_to_channels;
+ std::map<int, std::vector<const Channel *>> position_to_categories;
+ std::map<int, std::vector<const Channel *>> orphan_channels;
+ for (const auto &channel_id : channels) {
+ const auto *data = discord.GetChannel(channel_id);
+ if (data == nullptr) continue;
+ if (!data->ParentID.IsValid() && data->Type == ChannelType::GUILD_TEXT)
+ orphan_channels[data->Position].push_back(data);
+ else if (data->ParentID.IsValid() && data->Type == ChannelType::GUILD_TEXT)
+ category_to_channels[data->ParentID].push_back(data);
+ else if (data->Type == ChannelType::GUILD_CATEGORY)
+ position_to_categories[data->Position].push_back(data);
+ }
+
+ for (auto &[pos, channels] : orphan_channels) {
+ std::sort(channels.begin(), channels.end(), [&](const Channel *a, const Channel *b) -> bool {
+ return a->ID < b->ID;
+ });
+ for (auto &chan : channels)
+ ret.push_back(chan->ID);
+ }
+
+ for (auto &[pos, categories] : position_to_categories) {
+ std::sort(categories.begin(), categories.end(), [&](const Channel *a, const Channel *b) -> bool {
+ return a->ID < b->ID;
+ });
+ for (auto &category : categories) {
+ ret.push_back(category->ID);
+ if (ignore == category->ID) continue; // stupid hack to save me some time
+ auto it = category_to_channels.find(category->ID);
+ if (it == category_to_channels.end()) continue;
+ auto &channels = it->second;
+ std::sort(channels.begin(), channels.end(), [&](const Channel *a, const Channel *b) -> bool {
+ return a->Position < b->Position;
+ });
+ for (auto &channel : channels) {
+ ret.push_back(channel->ID);
+ }
+ }
+ }
+
+ return ret;
+}
diff --git a/discord/guild.hpp b/discord/guild.hpp
index 74ea851..e76c8c5 100644
--- a/discord/guild.hpp
+++ b/discord/guild.hpp
@@ -68,4 +68,5 @@ struct Guild {
bool HasIcon() const;
std::string GetIconURL(std::string ext = "png", std::string size = "32") const;
+ std::vector<Snowflake> GetSortedChannels(Snowflake ignore = Snowflake::Invalid) const;
};
diff --git a/discord/json.hpp b/discord/json.hpp
index 1cd4a14..3f78391 100644
--- a/discord/json.hpp
+++ b/discord/json.hpp
@@ -21,3 +21,25 @@
if (j.contains(k) && !j.at(k).is_null()) \
j.at(k).get_to(t); \
} while (0)
+
+#define JS_RD(k, t) \
+ do { \
+ if (j.contains(k)) { \
+ if (j.at(k).is_null()) { \
+ t = decltype(t)(); \
+ } else { \
+ j.at(k).get_to(t); \
+ } \
+ } \
+ } while (0)
+
+#define JS_RV(k, t, d) \
+ do { \
+ if (j.contains(k)) { \
+ if (j.at(k).is_null()) { \
+ t = d; \
+ } else { \
+ j.at(k).get_to(t); \
+ } \
+ } \
+ } while (0)
diff --git a/discord/objects.hpp b/discord/objects.hpp
index 1e2cb27..66d899c 100644
--- a/discord/objects.hpp
+++ b/discord/objects.hpp
@@ -37,6 +37,9 @@ enum class GatewayEvent : int {
MESSAGE_DELETE_BULK,
GUILD_MEMBER_UPDATE,
PRESENCE_UPDATE,
+ CHANNEL_DELETE,
+ CHANNEL_UPDATE,
+ CHANNEL_CREATE,
};
struct GatewayMessage {