1
0
Fork 0
mirror of https://gitlab.com/niansa/SomeBot.git synced 2025-03-06 20:48:26 +01:00
SomeBot/modules/moderation.cpp
2023-12-07 01:50:33 +01:00

168 lines
9.5 KiB
C++

#include "../bot.hpp"
#include <unordered_map>
class Moderation {
Bot *bot;
void db_add_guild(const dpp::snowflake& guild_id) {
bot->db << "INSERT OR IGNORE INTO moderation_guild_settings (id) VALUES (?);"
<< std::to_string(guild_id);
}
void db_add_member(const dpp::snowflake& guild_id, const dpp::snowflake& user_id) {
bot->db << "INSERT OR IGNORE INTO moderation_guild_user_warnings (guild_id, user_id) VALUES (?);"
<< std::to_string(guild_id) << std::to_string(user_id);
}
dpp::snowflake get_moderation_role(const dpp::snowflake& guild_id) {
std::string fres;
bot->db << "SELECT moderation_role FROM moderation_guild_settings "
"WHERE id = ?;"
<< std::to_string(guild_id)
>> [&] (const std::string& moderation_role) {
fres = moderation_role;
};
return fres.empty()?"0":fres;
}
bool has_moderation_role(const dpp::guild_member& member) {
auto moderation_role = get_moderation_role(member.guild_id);
if (!moderation_role) {
return false;
}
const auto& roles = member.get_roles();
return std::find_if(roles.begin(), roles.end(), [moderation_role](auto a) {
return a == moderation_role;
}) != roles.end();
}
public:
Moderation(Bot *_bot) : bot(_bot) {
bot->db << "CREATE TABLE IF NOT EXISTS moderation_guild_settings ("
" id TEXT PRIMARY KEY NOT NULL,"
" moderation_role TEXT,"
" logs_channel TEXT,"
" UNIQUE(id)"
");";
bot->db << "CREATE TABLE IF NOT EXISTS moderation_guild_user_warnings ("
" guild_id TEXT NOT NULL,"
" user_id TEXT NOT NULL,"
" amount INTEGER,"
" reasons TEXT,"
" UNIQUE(guild_id, user_id)"
");";
bot->add_chatcommand(Bot::ChatCommand({"purge"}, "Delete recent messages", dpp::slashcommand().add_option(dpp::command_option(dpp::command_option_type::co_integer, "amount", "Amount of messages to delete", true))), [&](const dpp::slashcommand_t& event) {
unsigned long amount = std::get<long>(event.get_parameter("amount"));
// Check that user has the correct permissions
if (!has_moderation_role(event.command.member) && !event.command.get_guild().base_permissions(event.command.member).has(dpp::permissions::p_manage_messages)) {
event.reply(dpp::message("You need message management permission to use this command.").set_flags(dpp::message_flags::m_ephemeral));
return;
}
// Start message deletion in new thread
std::thread([this, amount, channel_id = event.command.channel_id, member = event.command.member] () mutable {
// Collect messages
std::unordered_map<dpp::snowflake, dpp::message> messages;
while (amount > 0) {
try {
// Get messages
dpp::snowflake last_msg;
if (!messages.empty()) {
last_msg = (*messages.begin()).second.id;
} else {
last_msg = 0;
}
auto requested_amount = std::min(amount, 100UL);
auto new_messages = bot->cluster.messages_get_sync(channel_id, 0, last_msg, 0, requested_amount);
// Update counters
amount -= new_messages.size();
// Add them to sorted vector
for (auto& [message_id, message] : new_messages) {
messages[message_id] = std::move(message);
}
// Break out if requested amount wasn't reached
if (new_messages.size() < requested_amount) {
break;
}
} catch (...) {
break;
}
}
// Start deleting messages
unsigned errors = 0;
for (const auto& [message_id, message] : messages) {
try {
bot->cluster.message_delete_sync(message_id, message.channel_id);
} catch (...) {
errors++;
}
}
// Report sucess or errors that might have occured
std::string message = "On request of "+member.get_mention()+" **"+std::to_string(messages.size()-errors)+"** messages were deleted.";
if (errors) {
message += "\n**Warning:** "+std::to_string(errors)+" messages could not be deleted (they may be too old).";
}
bot->cluster.message_create(dpp::message(message).set_channel_id(channel_id));
}).detach();
// Report success
event.reply(dpp::message("Done! Starting to delete messages...").set_flags(dpp::message_flags::m_ephemeral));
});
bot->add_chatcommand(Bot::ChatCommand({"ban"}, "Ban someone from the server", dpp::slashcommand().add_option(dpp::command_option(dpp::command_option_type::co_user, "member", "Member to ban", true)).add_option(dpp::command_option(dpp::command_option_type::co_string, "reason", "For what reason?", true))), [&](const dpp::slashcommand_t& event) {
auto member_id = std::get<dpp::snowflake>(event.get_parameter("member"));
auto reason = std::get<std::string>(event.get_parameter("reason"));
// Check that user has the correct permissions
if (!has_moderation_role(event.command.member) && !event.command.get_guild().base_permissions(event.command.member).has(dpp::permissions::p_ban_members)) {
event.reply(dpp::message("You need the ban permission to use this command.").set_flags(dpp::message_flags::m_ephemeral));
return;
}
// Send ban DM
dpp::embed embed;
embed.set_title("You've been banned")
.set_description("You have been banned from "+event.command.get_guild().name+"!\n\n> "+reason);
bot->cluster.direct_message_create(member_id, dpp::message().add_embed(embed), [this, member_id, event] (const dpp::confirmation_callback_t& ccb) {
// Ban
bot->cluster.guild_ban_add(event.command.guild_id, member_id, 0, [this, event, dm_ccb = ccb] (const dpp::confirmation_callback_t& ccb) {
if (ccb.is_error()) {
event.reply(dpp::message("I am not able to ban this member.").set_flags(dpp::message_flags::m_ephemeral));
// Delete DM message because it's not valid
if (!dm_ccb.is_error()) {
auto dm_msg = dm_ccb.get<dpp::message>();
bot->cluster.message_delete(dm_msg.id, dm_msg.channel_id);
}
} else {
event.reply(dpp::message("Done!").set_flags(dpp::message_flags::m_ephemeral));
}
});
});
});
bot->add_chatcommand(Bot::ChatCommand({"kick"}, "Kick someone from the server", dpp::slashcommand().add_option(dpp::command_option(dpp::command_option_type::co_user, "member", "Member to kick", true)).add_option(dpp::command_option(dpp::command_option_type::co_string, "reason", "For what reason?", true))), [&](const dpp::slashcommand_t& event) {
auto member_id = std::get<dpp::snowflake>(event.get_parameter("member"));
auto reason = std::get<std::string>(event.get_parameter("reason"));
// Check that user has the correct permissions
if (!has_moderation_role(event.command.member) && !event.command.get_guild().base_permissions(event.command.member).has(dpp::permissions::p_kick_members)) {
event.reply(dpp::message("You need the kick permissoin to use this command.").set_flags(dpp::message_flags::m_ephemeral));
return;
}
// Send kick DM
dpp::embed embed;
embed.set_title("You've been kicked")
.set_description("You have been kicked from "+event.command.get_guild().name+"!\n\n> "+reason);
bot->cluster.direct_message_create(member_id, dpp::message().add_embed(embed), [this, member_id, event] (const dpp::confirmation_callback_t& ccb) {
// Kick
bot->cluster.guild_member_kick(event.command.guild_id, member_id, [this, event, dm_ccb = ccb] (const dpp::confirmation_callback_t& ccb) {
if (ccb.is_error()) {
event.reply(dpp::message("I am not able to kick this member.").set_flags(dpp::message_flags::m_ephemeral));
// Delete DM message because it's not valid
if (!dm_ccb.is_error()) {
auto dm_msg = dm_ccb.get<dpp::message>();
bot->cluster.message_delete(dm_msg.id, dm_msg.channel_id);
}
} else {
event.reply(dpp::message("Done!").set_flags(dpp::message_flags::m_ephemeral));
}
});
});
});
}
};
BOT_ADD_MODULE(Moderation);