diff --git a/Discord.C++/Discord.cpp b/Discord.C++/Discord.cpp index cf05ee5..d42ca78 100644 --- a/Discord.C++/Discord.cpp +++ b/Discord.C++/Discord.cpp @@ -209,7 +209,7 @@ void DiscordCPP::Discord::on_websocket_incoming_message(const json &payload) { } void DiscordCPP::Discord::handle_raw_event(const std::string &event_name, const json &data) { - // https://discordapp.com/developers/docs/topics/gateway#commands-and-events-gateway-events + // https://discord.com/developers/docs/topics/gateway-events#receive-events if (event_name == "READY") { _user = new User(data.at("user"), get_token()); @@ -352,6 +352,24 @@ void DiscordCPP::Discord::handle_raw_event(const std::string &event_name, const std::string(e.what())); } } + } else if (event_name == "GUILD_EMOJIS_UPDATE") { + Guild *guild = get_guild(data.at("guild_id").get()); + std::vector emojis; + + for (const json &emoji : data.at("emojis")) { + emojis.push_back(Emoji(emoji, get_token())); + } + + guild->_update_emojis(emojis); + } else if (event_name == "GUILD_ROLE_CREATE") { + Guild *guild = get_guild(data.at("guild_id").get()); + guild->_add_role(Role(data.at("role"), guild->get_id(), get_token())); + } else if (event_name == "GUILD_ROLE_UPDATE") { + Guild *guild = get_guild(data.at("guild_id").get()); + guild->_update_role(Role(data.at("role"), guild->get_id(), get_token())); + } else if (event_name == "GUILD_ROLE_DELETE") { + Guild *guild = get_guild(data.at("guild_id").get()); + guild->_remove_role(data.at("role_id").get()); } else if (event_name == "MESSAGE_CREATE") { if (has_value(data, ("guild_id"))) { std::string guild_id = data.at("guild_id").get(); diff --git a/Discord.C++/Guild.cpp b/Discord.C++/Guild.cpp index 2605929..481fe85 100644 --- a/Discord.C++/Guild.cpp +++ b/Discord.C++/Guild.cpp @@ -1,6 +1,7 @@ #include "Guild.h" #include +#include #include "ChannelHelper.h" #include "Emoji.h" @@ -79,10 +80,12 @@ DiscordCPP::Guild::Guild(Discord* client, const std::string& id, const std::stri } void DiscordCPP::Guild::_add_channel(ChannelVariant channel) { + std::lock_guard lock(mutex_holder.mutex); channels.push_back(channel); } void DiscordCPP::Guild::_update_channel(ChannelVariant channel) { + std::lock_guard lock(mutex_holder.mutex); std::string channel_id = ChannelHelper::get_channel_id(channel); for (size_t i = 0; i < channels.size(); i++) { if (ChannelHelper::get_channel_id(channels[i]) == channel_id) { @@ -94,6 +97,7 @@ void DiscordCPP::Guild::_update_channel(ChannelVariant channel) { } void DiscordCPP::Guild::_remove_channel(const std::string& channel_id) { + std::lock_guard lock(mutex_holder.mutex); for (size_t i = 0; i < channels.size(); i++) { if (ChannelHelper::get_channel_id(channels[i]) == channel_id) { channels.erase(channels.begin() + i); @@ -103,11 +107,13 @@ void DiscordCPP::Guild::_remove_channel(const std::string& channel_id) { } void DiscordCPP::Guild::_add_member(Member member) { + std::lock_guard lock(mutex_holder.mutex); members.push_back(member); member_count += 1; } void DiscordCPP::Guild::_update_member(Member member) { + std::lock_guard lock(mutex_holder.mutex); for (size_t i = 0; i < members.size(); i++) { if (members[i].get_id() == member.get_id()) { members.erase(members.begin() + i); @@ -117,6 +123,7 @@ void DiscordCPP::Guild::_update_member(Member member) { } void DiscordCPP::Guild::_remove_member(const std::string& member_id) { + std::lock_guard lock(mutex_holder.mutex); for (size_t i = 0; i < members.size(); i++) { if (members[i].get_id() == member_id) { members.erase(members.begin() + i); @@ -125,6 +132,35 @@ void DiscordCPP::Guild::_remove_member(const std::string& member_id) { } } +void DiscordCPP::Guild::_update_emojis(std::vector emojis) { + std::lock_guard lock(mutex_holder.mutex); + this->emojis = emojis; +} + +void DiscordCPP::Guild::_add_role(Role role) { + std::lock_guard lock(mutex_holder.mutex); + roles.push_back(role); +} + +void DiscordCPP::Guild::_update_role(Role role) { + std::lock_guard lock(mutex_holder.mutex); + for (size_t i = 0; i < roles.size(); i++) { + if (roles[i].get_id() == role.get_id()) { + roles.erase(roles.begin() + i); + roles.push_back(role); + } + } +} + +void DiscordCPP::Guild::_remove_role(const std::string& role_id) { + std::lock_guard lock(mutex_holder.mutex); + for (size_t i = 0; i < roles.size(); i++) { + if (roles[i].get_id() == role_id) { + roles.erase(roles.begin() + i); + } + } +} + ///@throws HTTPError void DiscordCPP::Guild::leave() { std::string url = "/guilds/@me/guilds/" + get_id(); diff --git a/Discord.C++/Guild.h b/Discord.C++/Guild.h index d5b407b..e33eabe 100644 --- a/Discord.C++/Guild.h +++ b/Discord.C++/Guild.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "Channel.h" #include "ChannelHelper.h" @@ -51,6 +52,7 @@ class Discord; class Guild : public DiscordObject { private: Discord* client = nullptr; + MutexHolder mutex_holder; /// the guild's name std::string name; @@ -121,7 +123,10 @@ class Guild : public DiscordObject { DLL_EXPORT void _add_member(Member member); DLL_EXPORT void _update_member(Member member); DLL_EXPORT void _remove_member(const std::string& member_id); - // TODO: update emojis and roles + DLL_EXPORT void _update_emojis(std::vector emojis); + DLL_EXPORT void _add_role(Role role); + DLL_EXPORT void _update_role(Role role); + DLL_EXPORT void _remove_role(const std::string& role_id); friend Discord; diff --git a/Discord.C++/Intents.cpp b/Discord.C++/Intents.cpp index 7e5fd92..89bbe29 100644 --- a/Discord.C++/Intents.cpp +++ b/Discord.C++/Intents.cpp @@ -10,6 +10,7 @@ Intents Intents::Default() { Intents Intents::All() { Intents intents = Intents::Default(); intents.add(BANS); + intents.add(EMOJIS); intents.add(MESSAGES); intents.add(REACTIONS); intents.add(TYPING); diff --git a/Discord.C++/static.h b/Discord.C++/static.h index e6537eb..5f6608e 100644 --- a/Discord.C++/static.h +++ b/Discord.C++/static.h @@ -42,3 +42,11 @@ DLL_EXPORT std::optional get_optional(const json& j, const std::string& key) else return std::make_optional(j.at(key).get()); } + +class MutexHolder { + public: + std::mutex mutex; + MutexHolder() : mutex() {} + MutexHolder(const MutexHolder&) : mutex() {} + MutexHolder operator=(const MutexHolder&) { return MutexHolder(); } +};