Now tracks and caches all (I think) required data
This commit is contained in:
parent
1b2ea3c6bf
commit
47de861f45
@ -3,8 +3,8 @@
|
|||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include "APIHelper.hpp"
|
#include "APIHelper.hpp"
|
||||||
#include "data_structures/User.hpp"
|
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
|
#include "data_structures/GuildMember.hpp"
|
||||||
|
|
||||||
extern std::string bot_token;
|
extern std::string bot_token;
|
||||||
|
|
||||||
@ -64,34 +64,314 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
json data = decoded["d"];
|
json data = decoded["d"];
|
||||||
|
|
||||||
if (event_name == "READY") {
|
if (event_name == "READY") {
|
||||||
|
on_event_ready(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_CREATE") {
|
||||||
|
on_event_guild_create(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_UPDATE") {
|
||||||
|
on_event_guild_update(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_DELETE") {
|
||||||
|
on_event_guild_delete(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_MEMBER_ADD") {
|
||||||
|
on_event_guild_member_add(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_MEMBER_UPDATE") {
|
||||||
|
on_event_guild_member_update(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_MEMBER_REMOVE") {
|
||||||
|
on_event_guild_member_remove(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_ROLE_CREATE") {
|
||||||
|
on_event_guild_role_create(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_ROLE_UPDATE") {
|
||||||
|
on_event_guild_role_update(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "GUILD_ROLE_DELETE") {
|
||||||
|
on_event_guild_role_delete(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "CHANNEL_CREATE") {
|
||||||
|
on_event_channel_create(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "CHANNEL_UPDATE") {
|
||||||
|
on_event_channel_update(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "CHANNEL_DELETE") {
|
||||||
|
on_event_channel_delete(data);
|
||||||
|
}
|
||||||
|
else if (event_name == "MESSAGE_CREATE") {
|
||||||
|
on_event_message_create(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_ready(json data) {
|
||||||
user_object.load_from_json(data["user"]);
|
user_object.load_from_json(data["user"]);
|
||||||
|
|
||||||
Logger::write("Sign-on confirmed. (@" + user_object.username + "#" + user_object.discriminator + ")", Logger::LogLevel::Info);
|
Logger::write("Sign-on confirmed. (@" + user_object.username + "#" + user_object.discriminator + ")", Logger::LogLevel::Info);
|
||||||
}
|
}
|
||||||
else if (event_name == "GUILD_CREATE") {
|
|
||||||
std::string guild_id = data["id"];
|
|
||||||
guilds[guild_id] = std::make_unique<DiscordObjects::Guild>(data);
|
|
||||||
|
|
||||||
Logger::write("Loaded guild: " + guilds[guild_id]->name, Logger::LogLevel::Debug);
|
void GatewayHandler::on_event_guild_create(json data) {
|
||||||
|
guilds[data["id"]] = DiscordObjects::Guild(data);
|
||||||
|
DiscordObjects::Guild &guild = guilds[data["id"]];
|
||||||
|
|
||||||
|
Logger::write("Loaded guild " + guild.id + ", now in " + std::to_string(guilds.size()) + " guild(s)", Logger::LogLevel::Info);
|
||||||
|
|
||||||
|
int channels_added = 0, roles_added = 0, members_added = 0;
|
||||||
|
|
||||||
for (json channel : data["channels"]) {
|
for (json channel : data["channels"]) {
|
||||||
std::string channel_id = channel["id"];
|
std::string channel_id = channel["id"];
|
||||||
channel["guild_id"] = guild_id;
|
channel["guild_id"] = guild.id;
|
||||||
// create channel obj, add to overall channel list
|
|
||||||
channels[channel_id] = std::make_shared<DiscordObjects::Channel>(channel);
|
channels[channel_id] = DiscordObjects::Channel(channel);
|
||||||
// add ptr to said channel list to guild's channel list
|
guilds[guild.id].channels.push_back(&channels[channel_id]);
|
||||||
guilds[guild_id]->channels.push_back(std::shared_ptr<DiscordObjects::Channel>(channels[channel_id]));
|
|
||||||
|
channels_added++;
|
||||||
|
}
|
||||||
|
for (json role : data["roles"]) {
|
||||||
|
std::string role_id = role["id"];
|
||||||
|
|
||||||
|
roles[role_id] = DiscordObjects::Role(role);
|
||||||
|
guilds[guild.id].roles.push_back(&roles[role_id]);
|
||||||
|
|
||||||
|
roles_added++;
|
||||||
|
}
|
||||||
|
for (json member : data["members"]) {
|
||||||
|
std::string user_id = member["user"]["id"];
|
||||||
|
|
||||||
|
auto it = users.find(user_id);
|
||||||
|
if (it == users.end()) { // new user
|
||||||
|
users[user_id] = DiscordObjects::User(member["user"]);
|
||||||
|
}
|
||||||
|
users[user_id].guilds.push_back(guild.id);
|
||||||
|
|
||||||
|
DiscordObjects::GuildMember guild_member(member, &users[user_id]);
|
||||||
|
for (std::string role_id : member["roles"]) {
|
||||||
|
guild_member.roles.push_back(&roles[role_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v8_instances.count(guild_id) == 0) {
|
guilds[guild.id].members.push_back(guild_member);
|
||||||
v8_instances[guild_id] = std::make_unique<V8Instance>(ah);
|
|
||||||
Logger::write("Created v8 instance for guild " + guild_id, Logger::LogLevel::Debug);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::write("Loaded " + std::to_string(guilds.size()) + " guild(s)", Logger::LogLevel::Info);
|
if (v8_instances.count(guild.id) == 0) {
|
||||||
|
v8_instances[guild.id] = std::make_unique<V8Instance>(ah);
|
||||||
|
Logger::write("Created v8 instance for guild " + guild.id, Logger::LogLevel::Debug);
|
||||||
}
|
}
|
||||||
else if (event_name == "TYPING_START") {}
|
|
||||||
else if (event_name == "MESSAGE_CREATE") {
|
Logger::write("Loaded " + std::to_string(channels_added) + " channels, " + std::to_string(roles_added)
|
||||||
|
+ " roles and " + std::to_string(members_added) + " members to guild " + guild.id, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_update(json data) {
|
||||||
|
std::string guild_id = data["id"];
|
||||||
|
|
||||||
|
guilds[guild_id].load_from_json(data);
|
||||||
|
Logger::write("Updated guild " + guild_id, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_delete(json data) {
|
||||||
|
std::string guild_id = data["id"];
|
||||||
|
bool unavailable = data.value("unavailable", false);
|
||||||
|
|
||||||
|
if (unavailable) {
|
||||||
|
Logger::write("Guild " + guild_id + " has become unavailable", Logger::LogLevel::Info);
|
||||||
|
guilds[guild_id].unavailable = true;
|
||||||
|
} else {
|
||||||
|
int channels_removed = 0;
|
||||||
|
for (auto it = channels.cbegin(); it != channels.cend();) {
|
||||||
|
if (it->second.guild_id == guild_id) {
|
||||||
|
channels.erase(it++);
|
||||||
|
channels_removed++;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guilds.erase(guilds.find(guild_id));
|
||||||
|
Logger::write("Guild " + guild_id + " and " + std::to_string(channels_removed) + " channels removed", Logger::LogLevel::Info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_member_add(json data) {
|
||||||
|
std::string guild_id = data["guild_id"];
|
||||||
|
std::string user_id = data["user"]["id"];
|
||||||
|
|
||||||
|
auto it = users.find(user_id);
|
||||||
|
if (it == users.end()) { // new user
|
||||||
|
users[user_id] = DiscordObjects::User(data["user"]);
|
||||||
|
}
|
||||||
|
users[user_id].guilds.push_back(guild_id);
|
||||||
|
|
||||||
|
DiscordObjects::GuildMember guild_member(data, &users[user_id]);
|
||||||
|
for (std::string role_id : data["roles"]) {
|
||||||
|
guild_member.roles.push_back(&roles[role_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
guilds[guild_id].members.push_back(guild_member);
|
||||||
|
|
||||||
|
Logger::write("Added new member " + guild_member.user->id + " to guild " + guild_id, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_member_update(json data) {
|
||||||
|
std::cout << data.dump(4) << std::endl;
|
||||||
|
|
||||||
|
std::string user_id = data["user"]["id"];
|
||||||
|
DiscordObjects::Guild &guild = guilds[data["guild_id"]];
|
||||||
|
|
||||||
|
auto it = std::find_if(guild.members.begin(), guild.members.begin(), [user_id](const DiscordObjects::GuildMember &gm) {
|
||||||
|
return gm.user->id == user_id;
|
||||||
|
});
|
||||||
|
if (it != guild.members.end()) {
|
||||||
|
bool nick_changed = false;
|
||||||
|
size_t roles_change = 0;
|
||||||
|
|
||||||
|
std::string nick = data.value("nick", it->nick);
|
||||||
|
if (it->nick != nick) {
|
||||||
|
it->nick = nick;
|
||||||
|
nick_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
roles_change = it->roles.size();
|
||||||
|
it->roles.clear(); // reset and re-fill, changing the differences is probably more expensive anyway.
|
||||||
|
for (std::string role_id : data["roles"]) {
|
||||||
|
it->roles.push_back(&roles[role_id]);
|
||||||
|
}
|
||||||
|
roles_change = it->roles.size() - roles_change;
|
||||||
|
|
||||||
|
std::string debug_string = "Updated member " + user_id + " of guild " + guild.id;
|
||||||
|
if (nick_changed) debug_string += ". Nick changed to " + nick;
|
||||||
|
if (roles_change != 0) debug_string += ". No. of roles changed by " + std::to_string(roles_change);
|
||||||
|
debug_string += ".";
|
||||||
|
|
||||||
|
Logger::write(debug_string, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Logger::write("Tried to update member " + user_id + " (of guild " + guild.id + ") who does not exist.", Logger::LogLevel::Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_member_remove(json data) {
|
||||||
|
DiscordObjects::Guild &guild = guilds[data["guild_id"]];
|
||||||
|
std::string user_id = data["user"]["id"];
|
||||||
|
|
||||||
|
auto it = std::find_if(guild.members.begin(), guild.members.begin(), [user_id](const DiscordObjects::GuildMember &gm) {
|
||||||
|
return gm.user->id == user_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it != guilds[guild.id].members.end()) {
|
||||||
|
guild.members.erase(it);
|
||||||
|
|
||||||
|
DiscordObjects::User &user = users[user_id];
|
||||||
|
user.guilds.erase(std::remove(user.guilds.begin(), user.guilds.end(), user.id));
|
||||||
|
|
||||||
|
if (user.guilds.size() == 0) {
|
||||||
|
users.erase(users.find(user_id));
|
||||||
|
Logger::write("User " + user_id + " removed from guild " + guild.id + " and no longer visible, deleted.", Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Logger::write("User " + user_id + " removed from guild " + guild.id, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Logger::write("Tried to remove guild member " + user_id + " which doesn't exist", Logger::LogLevel::Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_role_create(json data) {
|
||||||
|
std::string role_id = data["role"]["id"];
|
||||||
|
std::string guild_id = data["guild_id"];
|
||||||
|
roles[role_id] = DiscordObjects::Role(data["role"]);
|
||||||
|
|
||||||
|
guilds[guild_id].roles.push_back(&roles[role_id]);
|
||||||
|
|
||||||
|
Logger::write("Created role " + role_id + " on guild " + guild_id, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_role_update(json data) {
|
||||||
|
std::string role_id = data["role"]["id"];
|
||||||
|
|
||||||
|
roles[role_id].load_from_json(data["role"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_guild_role_delete(json data) {
|
||||||
|
std::string role_id = data["role_id"];
|
||||||
|
auto it = roles.find(role_id);
|
||||||
|
|
||||||
|
if (it != roles.end()) {
|
||||||
|
DiscordObjects::Role &role = roles[role_id];
|
||||||
|
DiscordObjects::Guild &guild = guilds[data["guild_id"]];
|
||||||
|
|
||||||
|
auto check_lambda = [role_id](const DiscordObjects::Role *r) {
|
||||||
|
return r->id == role_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto it2 = std::find_if(guild.roles.begin(), guild.roles.end(), check_lambda);
|
||||||
|
if (it2 != guild.roles.end()) {
|
||||||
|
guild.roles.erase(it2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Logger::write("Tried to delete role " + role_id + " from guild " + guild.id + " but it doesn't exist there", Logger::LogLevel::Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
roles.erase(it);
|
||||||
|
Logger::write("Deleted role " + role_id + " (guild " + guild.id + ").", Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Logger::write("Tried to delete role " + role_id + " but it doesn't exist.", Logger::LogLevel::Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_channel_create(json data) {
|
||||||
|
std::string channel_id = data["id"];
|
||||||
|
std::string guild_id = data["guild_id"];
|
||||||
|
|
||||||
|
channels[channel_id] = DiscordObjects::Channel(data);
|
||||||
|
Logger::write("Added channel " + channel_id + " to channel list. Now " + std::to_string(channels.size()) + " channels stored", Logger::LogLevel::Debug);
|
||||||
|
guilds[guild_id].channels.push_back(&channels[channel_id]);
|
||||||
|
Logger::write("Added channel " + channel_id + " to guild " + guild_id + "'s list. Now " + std::to_string(guilds[guild_id].channels.size()) + " channels stored", Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_channel_update(json data) {
|
||||||
|
std::cout << "Update: " << data.dump(4) << std::endl;
|
||||||
|
|
||||||
|
std::string channel_id = data["id"];
|
||||||
|
|
||||||
|
auto it = channels.find(channel_id);
|
||||||
|
if (it == channels.end()) {
|
||||||
|
Logger::write("Got channel update for channel " + channel_id + " that doesn't exist. Creating channel instead.", Logger::LogLevel::Warning);
|
||||||
|
on_event_channel_create(data);
|
||||||
|
} else {
|
||||||
|
channels[channel_id].load_from_json(data);
|
||||||
|
Logger::write("Updated channel " + channel_id, Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_channel_delete(json data) {
|
||||||
|
std::cout << "Delete: " << data.dump(4) << std::endl;
|
||||||
|
|
||||||
|
std::string channel_id = data["id"];
|
||||||
|
std::string guild_id = data["guild_id"];
|
||||||
|
|
||||||
|
auto it = channels.find(channel_id);
|
||||||
|
if (it == channels.end()) {
|
||||||
|
Logger::write("Tried to delete channel " + channel_id + " which doesn't exist", Logger::LogLevel::Warning);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto it2 = std::find_if(guilds[guild_id].channels.begin(), guilds[guild_id].channels.begin(), [channel_id](const DiscordObjects::Channel *c) {
|
||||||
|
return c->id == channel_id;
|
||||||
|
});
|
||||||
|
guilds[guild_id].channels.erase(it2);
|
||||||
|
Logger::write("Removed channel " + channel_id + " from guild " + guild_id + "'s list. Now "
|
||||||
|
+ std::to_string(guilds[guild_id].channels.size()) + " channels stored", Logger::LogLevel::Debug);
|
||||||
|
|
||||||
|
channels.erase(it);
|
||||||
|
Logger::write("Removed channel " + channel_id + " from channel list. Now " + std::to_string(channels.size()) + " channels stored.", Logger::LogLevel::Debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayHandler::on_event_message_create(json data) {
|
||||||
std::string message = data["content"];
|
std::string message = data["content"];
|
||||||
auto channel = channels[data["channel_id"]];
|
auto channel = channels[data["channel_id"]];
|
||||||
|
|
||||||
@ -105,7 +385,7 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
int delay = 8;
|
int delay = 8;
|
||||||
|
|
||||||
if (words.size() > 3) {
|
if (words.size() > 3) {
|
||||||
ah->send_message(channel->id, ":exclamation: Invalid arguments!");
|
ah->send_message(channel.id, ":exclamation: Invalid arguments!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (words.size() > 1) {
|
else if (words.size() > 1) {
|
||||||
@ -115,12 +395,12 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
help += "\\`trivia **stop**: stops the ongoing game.\n";
|
help += "\\`trivia **stop**: stops the ongoing game.\n";
|
||||||
help += "\\`trivia **help**: prints this message\n";
|
help += "\\`trivia **help**: prints this message\n";
|
||||||
|
|
||||||
ah->send_message(channel->id, help);
|
ah->send_message(channel.id, help);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (words[1] == "stop" || words[1] == "s") {
|
else if (words[1] == "stop" || words[1] == "s") {
|
||||||
if (games.find(channel->id) != games.end()) {
|
if (games.find(channel.id) != games.end()) {
|
||||||
delete_game(channel->id);
|
delete_game(channel.id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,30 +412,30 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::invalid_argument e) {
|
catch (std::invalid_argument e) {
|
||||||
ah->send_message(channel->id, ":exclamation: Invalid arguments!");
|
ah->send_message(channel.id, ":exclamation: Invalid arguments!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
games[channel->id] = std::make_unique<TriviaGame>(this, ah, channel->id, questions, delay);
|
games[channel.id] = std::make_unique<TriviaGame>(this, ah, channel.id, questions, delay);
|
||||||
games[channel->id]->start();
|
games[channel.id]->start();
|
||||||
}
|
}
|
||||||
else if (words[0] == "`guilds") {
|
else if (words[0] == "`guilds") {
|
||||||
std::string m = "Guild List:\n";
|
std::string m = "Guild List:\n";
|
||||||
for (auto &gu : guilds) {
|
for (auto &gu : guilds) {
|
||||||
m += "> " + gu.second->name + " (" + gu.second->id + ") Channels: " + std::to_string(gu.second->channels.size()) + "\n";
|
m += "> " + gu.second.name + " (" + gu.second.id + ") Channels: " + std::to_string(gu.second.channels.size()) + "\n";
|
||||||
}
|
}
|
||||||
ah->send_message(channel->id, m);
|
ah->send_message(channel.id, m);
|
||||||
}
|
}
|
||||||
else if (words[0] == "`info") {
|
else if (words[0] == "`info") {
|
||||||
ah->send_message(channel->id, ":information_source: trivia-bot by Jack. <http://github.com/jackb-p/TriviaDiscord>");
|
ah->send_message(channel.id, ":information_source: trivia-bot by Jack. <http://github.com/jackb-p/TriviaDiscord>");
|
||||||
}
|
}
|
||||||
else if (words[0] == "`js" && message.length() > 4) {
|
else if (words[0] == "`js" && message.length() > 4) {
|
||||||
std::string js = message.substr(4);
|
std::string js = message.substr(4);
|
||||||
auto it = v8_instances.find(channel->guild_id);
|
auto it = v8_instances.find(channel.guild_id);
|
||||||
if (it != v8_instances.end() && js.length() > 0) {
|
if (it != v8_instances.end() && js.length() > 0) {
|
||||||
it->second->exec_js(js, channel->id);
|
it->second->exec_js(js, channel.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (words[0] == "`createjs" && message.length() > 8) {
|
else if (words[0] == "`createjs" && message.length() > 8) {
|
||||||
@ -164,30 +444,101 @@ void GatewayHandler::on_dispatch(json decoded, client &c, websocketpp::connectio
|
|||||||
if (seperator_loc != std::string::npos) {
|
if (seperator_loc != std::string::npos) {
|
||||||
std::string command_name = args.substr(0, seperator_loc);
|
std::string command_name = args.substr(0, seperator_loc);
|
||||||
std::string script = args.substr(seperator_loc + 1);
|
std::string script = args.substr(seperator_loc + 1);
|
||||||
int result = command_helper->insert_command(channel->guild_id, command_name, script);
|
int result = command_helper->insert_command(channel.guild_id, command_name, script);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case 0:
|
case 0:
|
||||||
ah->send_message(channel->id, ":warning: Error!"); break;
|
ah->send_message(channel.id, ":warning: Error!"); break;
|
||||||
case 1:
|
case 1:
|
||||||
ah->send_message(channel->id, ":new: Command `" + command_name + "` successfully created."); break;
|
ah->send_message(channel.id, ":new: Command `" + command_name + "` successfully created."); break;
|
||||||
case 2:
|
case 2:
|
||||||
ah->send_message(channel->id, ":arrow_heading_up: Command `" + command_name + "` successfully updated."); break;
|
ah->send_message(channel.id, ":arrow_heading_up: Command `" + command_name + "` successfully updated."); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (words[0] == "`shutdown" && sender.id == "82232146579689472") { // it me
|
else if (words[0] == "`shutdown" && sender.id == "82232146579689472") { // it me
|
||||||
ah->send_message(channel->id, ":zzz: Goodbye!");
|
ah->send_message(channel.id, ":zzz: Goodbye!");
|
||||||
c.close(hdl, websocketpp::close::status::going_away, "`shutdown command used.");
|
// TODO: without needing c, hdl - c.close(hdl, websocketpp::close::status::going_away, "`shutdown command used.");
|
||||||
}
|
}
|
||||||
else if (command_helper->get_command(channel->guild_id, words[0], custom_command)) {
|
else if (words[0] == "`debug") {
|
||||||
auto it = v8_instances.find(channel->guild_id);
|
if (words[1] == "channel" && words.size() == 3) {
|
||||||
|
auto it = channels.find(words[2]);
|
||||||
|
if (it != channels.end()) {
|
||||||
|
ah->send_message(channel.id, it->second.to_debug_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised channel.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (words[1] == "guild" && words.size() == 3) {
|
||||||
|
auto it = guilds.find(words[2]);
|
||||||
|
if (it != guilds.end()) {
|
||||||
|
ah->send_message(channel.id, it->second.to_debug_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised guild.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (words[1] == "member" && words.size() == 4) {
|
||||||
|
auto it = guilds.find(words[2]);
|
||||||
|
if (it != guilds.end()) {
|
||||||
|
std::string user_id = words[3];
|
||||||
|
auto it2 = std::find_if(it->second.members.begin(), it->second.members.end(), [user_id](const DiscordObjects::GuildMember &gm) {
|
||||||
|
return user_id == gm.user->id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it2 != it->second.members.end()) {
|
||||||
|
ah->send_message(channel.id, it2->to_debug_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised user.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised guild.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (words[1] == "role" && words.size() == 3) {
|
||||||
|
auto it = roles.find(words[2]);
|
||||||
|
if (it != roles.end()) {
|
||||||
|
ah->send_message(channel.id, it->second.to_debug_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised role.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (words[1] == "role" && words.size() == 4) {
|
||||||
|
std::string role_name = words[3];
|
||||||
|
|
||||||
|
auto it = guilds.find(words[2]);
|
||||||
|
if (it != guilds.end()) {
|
||||||
|
auto check_lambda = [role_name](DiscordObjects::Role *r) {
|
||||||
|
return role_name == r->name;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto it2 = std::find_if(it->second.roles.begin(), it->second.roles.end(), check_lambda);
|
||||||
|
if (it2 != it->second.roles.end()) {
|
||||||
|
ah->send_message(channel.id, (*it2)->to_debug_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised role.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unrecognised guild.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ah->send_message(channel.id, ":question: Unknown parameters.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command_helper->get_command(channel.guild_id, words[0], custom_command)) {
|
||||||
|
auto it = v8_instances.find(channel.guild_id);
|
||||||
if (it != v8_instances.end() && custom_command.script.length() > 0) {
|
if (it != v8_instances.end() && custom_command.script.length() > 0) {
|
||||||
it->second->exec_js(custom_command.script, channel->id);
|
it->second->exec_js(custom_command.script, channel.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (games.find(channel->id) != games.end()) { // message received in channel with ongoing game
|
else if (games.find(channel.id) != games.end()) { // message received in channel with ongoing game
|
||||||
games[channel->id]->handle_answer(message, sender);
|
games[channel.id]->handle_answer(message, sender);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "data_structures/User.hpp"
|
#include "data_structures/User.hpp"
|
||||||
#include "data_structures/Guild.hpp"
|
#include "data_structures/Guild.hpp"
|
||||||
#include "data_structures/Channel.hpp"
|
#include "data_structures/Channel.hpp"
|
||||||
|
#include "data_structures/Role.hpp"
|
||||||
|
|
||||||
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
|
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@ -58,6 +59,27 @@ private:
|
|||||||
int last_seq;
|
int last_seq;
|
||||||
int heartbeat_interval;
|
int heartbeat_interval;
|
||||||
|
|
||||||
|
void on_event_ready(json data);
|
||||||
|
|
||||||
|
/* guild events */
|
||||||
|
void on_event_guild_create(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-create
|
||||||
|
void on_event_guild_update(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-update
|
||||||
|
void on_event_guild_delete(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-delete
|
||||||
|
void on_event_guild_member_add(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-member-add
|
||||||
|
void on_event_guild_member_update(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-member-update
|
||||||
|
void on_event_guild_member_remove(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-member-remove
|
||||||
|
void on_event_guild_role_create(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-role-create
|
||||||
|
void on_event_guild_role_update(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-role-update
|
||||||
|
void on_event_guild_role_delete(json data); // https://discordapp.com/developers/docs/topics/gateway#guild-role-delete
|
||||||
|
|
||||||
|
/* channel events */
|
||||||
|
void on_event_channel_create(json data); // https://discordapp.com/developers/docs/topics/gateway#channel-create
|
||||||
|
void on_event_channel_update(json data); // https://discordapp.com/developers/docs/topics/gateway#channel-update
|
||||||
|
void on_event_channel_delete(json data); // https://discordapp.com/developers/docs/topics/gateway#channel-delete
|
||||||
|
|
||||||
|
/* message events */
|
||||||
|
void on_event_message_create(json data); // https://discordapp.com/developers/docs/topics/gateway#message-create
|
||||||
|
|
||||||
const int protocol_version = 5;
|
const int protocol_version = 5;
|
||||||
|
|
||||||
// bot's user obj
|
// bot's user obj
|
||||||
@ -65,10 +87,11 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<CommandHelper> command_helper;
|
std::unique_ptr<CommandHelper> command_helper;
|
||||||
|
|
||||||
// <id, ptr to data>
|
/* <id, obj> */
|
||||||
std::map<std::string, std::unique_ptr<DiscordObjects::Guild>> guilds;
|
std::map<std::string, DiscordObjects::Guild> guilds;
|
||||||
// channels pointers are shared pointers, held here but also in guild objects
|
std::map<std::string, DiscordObjects::Channel> channels;
|
||||||
std::map<std::string, std::shared_ptr<DiscordObjects::Channel>> channels;
|
std::map<std::string, DiscordObjects::User> users;
|
||||||
|
std::map<std::string, DiscordObjects::Role> roles;
|
||||||
|
|
||||||
// <channel_id, game obj>
|
// <channel_id, game obj>
|
||||||
std::map<std::string, std::unique_ptr<TriviaGame>> games;
|
std::map<std::string, std::unique_ptr<TriviaGame>> games;
|
||||||
|
@ -34,13 +34,13 @@ int main(int argc, char *argv[]) {
|
|||||||
conn.start(uri);
|
conn.start(uri);
|
||||||
}
|
}
|
||||||
catch (const std::exception &e) {
|
catch (const std::exception &e) {
|
||||||
Logger::write(e.what(), Logger::LogLevel::Severe);
|
Logger::write("std exception: " + std::string(e.what()), Logger::LogLevel::Severe);
|
||||||
}
|
}
|
||||||
catch (websocketpp::lib::error_code e) {
|
catch (websocketpp::lib::error_code e) {
|
||||||
Logger::write(e.message(), Logger::LogLevel::Severe);
|
Logger::write("websocketpp exception: " + e.message(), Logger::LogLevel::Severe);
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
Logger::write("Other exception.", Logger::LogLevel::Severe);
|
Logger::write("other exception.", Logger::LogLevel::Severe);
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::V8::Dispose();
|
v8::V8::Dispose();
|
||||||
@ -51,5 +51,8 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
Logger::write("Cleaned up", Logger::LogLevel::Info);
|
Logger::write("Cleaned up", Logger::LogLevel::Info);
|
||||||
|
|
||||||
|
std::cout << "Press enter to exit" << std::endl;
|
||||||
|
std::getchar();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -32,6 +32,7 @@ namespace DiscordObjects {
|
|||||||
Channel(json data);
|
Channel(json data);
|
||||||
|
|
||||||
void load_from_json(json data);
|
void load_from_json(json data);
|
||||||
|
std::string to_debug_string();
|
||||||
|
|
||||||
bool operator==(Channel rhs);
|
bool operator==(Channel rhs);
|
||||||
|
|
||||||
@ -73,6 +74,19 @@ namespace DiscordObjects {
|
|||||||
user_limit = data.value("user_limit", -1);
|
user_limit = data.value("user_limit", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string Channel::to_debug_string() {
|
||||||
|
return "**__Channel " + id + "__**"
|
||||||
|
+ "\n**guild_id:** " + guild_id
|
||||||
|
+ "\n**name:** " + name
|
||||||
|
+ "\n**type:** " + type
|
||||||
|
+ "\n**position:** " + std::to_string(position)
|
||||||
|
+ "\n**is_private:** " + std::to_string(is_private)
|
||||||
|
+ "\n**topic:** " + (topic == "" ? "[empty]" : topic)
|
||||||
|
+ "\n**last_message_id:** " + last_message_id
|
||||||
|
+ "\n**bitrate:** " + std::to_string(bitrate)
|
||||||
|
+ "\n**user_limit:** " + std::to_string(user_limit);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool Channel::operator==(Channel rhs) {
|
inline bool Channel::operator==(Channel rhs) {
|
||||||
return id == rhs.id && id != "null";
|
return id == rhs.id && id != "null";
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
#ifndef BOT_DATA__STRUCTURES_Guild
|
#ifndef BOT_DATA__STRUCTURES_GUILD
|
||||||
#define BOT_DATA__STRUCTURES_Guild
|
#define BOT_DATA__STRUCTURES_GUILD
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <vector>
|
||||||
|
|
||||||
#include "../json/json.hpp"
|
#include "../json/json.hpp"
|
||||||
|
|
||||||
#include "Channel.hpp"
|
#include "Channel.hpp"
|
||||||
#include "User.hpp"
|
#include "User.hpp"
|
||||||
|
#include "Role.hpp"
|
||||||
|
#include "GuildMember.hpp"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ namespace DiscordObjects {
|
|||||||
Guild(json data);
|
Guild(json data);
|
||||||
|
|
||||||
void load_from_json(json data);
|
void load_from_json(json data);
|
||||||
|
std::string to_debug_string();
|
||||||
|
|
||||||
bool operator==(Guild rhs);
|
bool operator==(Guild rhs);
|
||||||
|
|
||||||
@ -62,13 +65,15 @@ namespace DiscordObjects {
|
|||||||
// bool embed_enabled;
|
// bool embed_enabled;
|
||||||
// std::string embed_channel_id;
|
// std::string embed_channel_id;
|
||||||
int verification_level;
|
int verification_level;
|
||||||
// TODO: Implement all guil fields
|
// TODO: Implement all guild fields
|
||||||
// std::vector<?> voice_states
|
// std::vector<?> voice_states
|
||||||
// std::vector<?> roles
|
|
||||||
// std::vector<?> emojis
|
// std::vector<?> emojis
|
||||||
// std::vector<?> features
|
// std::vector<?> features
|
||||||
|
bool unavailable;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Channel>> channels;
|
std::vector<Channel *> channels;
|
||||||
|
std::vector<GuildMember> members;
|
||||||
|
std::vector<Role *> roles;
|
||||||
//std::vector<std::unique_ptr<DiscordObjects::User>> users;
|
//std::vector<std::unique_ptr<DiscordObjects::User>> users;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,6 +98,23 @@ namespace DiscordObjects {
|
|||||||
afk_channel_id = data.value("afk_channel_id", "null");
|
afk_channel_id = data.value("afk_channel_id", "null");
|
||||||
afk_timeout = data.value("afk_timeout", -1);
|
afk_timeout = data.value("afk_timeout", -1);
|
||||||
verification_level = data.value("verification_level", -1);
|
verification_level = data.value("verification_level", -1);
|
||||||
|
unavailable = data.value("unavailable", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string Guild::to_debug_string() {
|
||||||
|
return "**__Guild " + id + "__**"
|
||||||
|
+ "\n**name:** " + name
|
||||||
|
+ "\n**icon:** " + icon
|
||||||
|
+ "\n**splash:** " + splash
|
||||||
|
+ "\n**owner_id:** " + owner_id
|
||||||
|
+ "\n**region:** " + region
|
||||||
|
+ "\n**afk_channel_id:** " + afk_channel_id
|
||||||
|
+ "\n**afk_timeout:** " + std::to_string(afk_timeout)
|
||||||
|
+ "\n**verification_level:** " + std::to_string(verification_level)
|
||||||
|
+ "\n**unavailable:** " + std::to_string(unavailable)
|
||||||
|
+ "\n**channels:** " + std::to_string(channels.size())
|
||||||
|
+ "\n**roles:** " + std::to_string(roles.size())
|
||||||
|
+ "\n**members:** " + std::to_string(members.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Guild::operator==(Guild rhs) {
|
inline bool Guild::operator==(Guild rhs) {
|
||||||
|
68
TriviaBot/bot/data_structures/GuildMember.hpp
Normal file
68
TriviaBot/bot/data_structures/GuildMember.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#ifndef BOT_DATA__STRUCTURES_GUILDMEMBER
|
||||||
|
#define BOT_DATA__STRUCTURES_GUILDMEMBER
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../json/json.hpp"
|
||||||
|
|
||||||
|
#include "User.hpp"
|
||||||
|
#include "Role.hpp"
|
||||||
|
|
||||||
|
namespace DiscordObjects {
|
||||||
|
class GuildMember {
|
||||||
|
public:
|
||||||
|
GuildMember();
|
||||||
|
GuildMember(json data, User *user);
|
||||||
|
|
||||||
|
void load_from_json(json data);
|
||||||
|
std::string to_debug_string();
|
||||||
|
|
||||||
|
bool operator==(GuildMember rhs);
|
||||||
|
|
||||||
|
User *user;
|
||||||
|
std::string nick;
|
||||||
|
std::vector<Role *> roles;
|
||||||
|
std::string joined_at; // TODO: better type
|
||||||
|
bool deaf;
|
||||||
|
bool mute;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline GuildMember::GuildMember() {
|
||||||
|
user = nullptr;
|
||||||
|
nick = "null";
|
||||||
|
joined_at = "null";
|
||||||
|
deaf = false;
|
||||||
|
mute = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline GuildMember::GuildMember(json data, User *user) {
|
||||||
|
this->user = user;
|
||||||
|
load_from_json(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void GuildMember::load_from_json(json data) {
|
||||||
|
nick = data.value("nick", "null");
|
||||||
|
joined_at = data.value("joined_at", "null");
|
||||||
|
deaf = data.value("deaf", false);
|
||||||
|
mute = data.value("mute", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string GuildMember::to_debug_string() {
|
||||||
|
return "**__GuildMember " + user->id + "__**"
|
||||||
|
+ "\n**mention:** <@" + user->id + "> / " + user->username + "#" + user->discriminator
|
||||||
|
+ "\n**bot:** " + std::to_string(user->bot)
|
||||||
|
+ "\n**mfa_enabled:** " + std::to_string(user->mfa_enabled)
|
||||||
|
+ "\n**avatar:** " + user->avatar
|
||||||
|
+ "\n**nick:** " + nick
|
||||||
|
+ "\n**joined_at:** " + joined_at
|
||||||
|
+ "\n**deaf:** " + std::to_string(deaf)
|
||||||
|
+ "\n**mute:** " + std::to_string(mute);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GuildMember::operator==(GuildMember rhs) {
|
||||||
|
return user->id == rhs.user->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
118
TriviaBot/bot/data_structures/Role.hpp
Normal file
118
TriviaBot/bot/data_structures/Role.hpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#ifndef BOT_DATA__STRUCTURES_ROLE
|
||||||
|
#define BOT_DATA__STRUCTURES_ROLE
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
#include "../json/json.hpp"
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
namespace DiscordObjects {
|
||||||
|
|
||||||
|
class Role {
|
||||||
|
public:
|
||||||
|
Role();
|
||||||
|
Role(json data);
|
||||||
|
|
||||||
|
void load_from_json(json data);
|
||||||
|
std::string to_debug_string();
|
||||||
|
|
||||||
|
bool operator==(Role rhs);
|
||||||
|
|
||||||
|
std::string id;
|
||||||
|
std::string name;
|
||||||
|
int colour;
|
||||||
|
bool hoist;
|
||||||
|
int position;
|
||||||
|
int permissions;
|
||||||
|
bool managed;
|
||||||
|
bool mentionable;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Role::Role() {
|
||||||
|
id = "null";
|
||||||
|
name = "null";
|
||||||
|
colour = -1;
|
||||||
|
hoist = false;
|
||||||
|
position = -1;
|
||||||
|
permissions = 0;
|
||||||
|
managed = false;
|
||||||
|
mentionable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Role::Role(json data) {
|
||||||
|
load_from_json(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Role::load_from_json(json data) {
|
||||||
|
id = data.value("id", "null");
|
||||||
|
name = data.value("name", "null");
|
||||||
|
colour = data.value("color", -1);
|
||||||
|
hoist = data.value("hoist", false);
|
||||||
|
position = data.value("position", -1);
|
||||||
|
permissions = data.value("permissions", 0);
|
||||||
|
managed = data.value("managed", false);
|
||||||
|
mentionable = data.value("mentionable", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string Role::to_debug_string() {
|
||||||
|
std::stringstream colour_ss;
|
||||||
|
colour_ss << std::setw(6) << std::setfill('0') << colour;
|
||||||
|
std::string colour_str = colour_ss.str();
|
||||||
|
|
||||||
|
return "**__Role " + id + "__**"
|
||||||
|
+ "\n**name:** " + name
|
||||||
|
+ "\n**colour:** #" + colour_str
|
||||||
|
+ "\n**hoist:** " + std::to_string(hoist)
|
||||||
|
+ "\n**position:** " + std::to_string(position)
|
||||||
|
+ "\n**permissions:** " + std::to_string(permissions)
|
||||||
|
+ "\n**managed:** " + std::to_string(managed)
|
||||||
|
+ "\n**mentionable:** " + std::to_string(mentionable);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Role::operator==(Role rhs) {
|
||||||
|
return id == rhs.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* permission values */
|
||||||
|
enum class Permission {
|
||||||
|
CreateInstantInvite = 0x00000001, // Allows creation of instant invites
|
||||||
|
KickMembers = 0x00000002, // Allows kicking members
|
||||||
|
BanMembers = 0x00000004, // Allows banning members
|
||||||
|
Administrator = 0x00000008, // Allows all permissions and bypasses channel permission overwrites
|
||||||
|
ManageChannels = 0x00000010, // Allows management and editing of channels
|
||||||
|
ManageGuild = 0x00000020, // Allows management and editing of the guild
|
||||||
|
ReadMessages = 0x00000400, // Allows reading messages in a channel.The channel will not appear for users without this permission
|
||||||
|
SendMessages = 0x00000800, // Allows for sending messages in a channel.
|
||||||
|
SendTTSMessages = 0x00001000, // Allows for sending of / tts messages
|
||||||
|
ManageMessages = 0x00002000, // Allows for deletion of other users messages
|
||||||
|
EmbedLinks = 0x00004000, // Links sent by this user will be auto - embedded
|
||||||
|
AttachFiles = 0x00008000, // Allows for uploading images and files
|
||||||
|
ReadMessageHistory = 0x00010000, // Allows for reading of message history
|
||||||
|
MentionEveryone = 0x00020000, // Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel
|
||||||
|
Connect = 0x00100000, // Allows for joining of a voice channel
|
||||||
|
Speak = 0x00200000, // Allows for speaking in a voice channel
|
||||||
|
MuteMembers = 0x00400000, // Allows for muting members in a voice channel
|
||||||
|
DeafenMembers = 0x00800000, // Allows for deafening of members in a voice channel
|
||||||
|
MoveMembers = 0x01000000, // Allows for moving of members between voice channels
|
||||||
|
UseVAD = 0x02000000, // Allows for using voice - activity - detection in a voice channel
|
||||||
|
ChangeNickname = 0x04000000, // Allows for modification of own nickname
|
||||||
|
ManageNicknames = 0x08000000, // Allows for modification of other users nicknames
|
||||||
|
ManageRoles = 0x10000000 // Allows management and editing of roles
|
||||||
|
};
|
||||||
|
|
||||||
|
/* implement bitwise operators */
|
||||||
|
inline Permission operator|(Permission lhs, Permission rhs) {
|
||||||
|
return static_cast<Permission>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Permission operator|=(Permission &lhs, Permission rhs) {
|
||||||
|
lhs = static_cast<Permission>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -2,6 +2,7 @@
|
|||||||
#define BOT_DATA__STRUCTURES_USER
|
#define BOT_DATA__STRUCTURES_USER
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../json/json.hpp"
|
#include "../json/json.hpp"
|
||||||
|
|
||||||
@ -37,6 +38,8 @@ namespace DiscordObjects {
|
|||||||
std::string avatar;
|
std::string avatar;
|
||||||
bool bot;
|
bool bot;
|
||||||
bool mfa_enabled;
|
bool mfa_enabled;
|
||||||
|
|
||||||
|
std::vector<std::string> guilds;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline User::User() {
|
inline User::User() {
|
||||||
|
Loading…
Reference in New Issue
Block a user