From 616ce0055ba93d8d1c7514910decc0b46c34d587 Mon Sep 17 00:00:00 2001 From: Syping Date: Thu, 7 Mar 2024 23:30:33 +0100 Subject: [PATCH] delete channel from settings when no target is left - converted some pointers to references - simplified some constructors --- src/core/database.cpp | 8 --- src/core/database.h | 4 +- src/core/settings.cpp | 122 ++++++++++++++++++++----------------- src/core/settings.h | 8 ++- src/core/slashcommands.cpp | 119 ++++++++++++++++++++---------------- src/core/translator.cpp | 8 --- src/core/translator.h | 4 +- 7 files changed, 142 insertions(+), 131 deletions(-) diff --git a/src/core/database.cpp b/src/core/database.cpp index f7fb12d..2911138 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -22,14 +22,6 @@ #include "database.h" using namespace bot::database; -database::database() -{ -} - -database::~database() -{ -} - void database::add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target) { #ifndef NDEBUG diff --git a/src/core/database.h b/src/core/database.h index 04e8cf3..e22f92e 100644 --- a/src/core/database.h +++ b/src/core/database.h @@ -30,8 +30,8 @@ namespace bot { class database { public: - explicit database(); - virtual ~database(); + explicit database() = default; + virtual ~database() = default; virtual void add_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const bot::settings::target &target); virtual void delete_channel(dpp::snowflake guild_id, dpp::snowflake channel_id); virtual void delete_channel_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index d761ea4..3acdd10 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -24,14 +24,14 @@ #include "../translator/libretranslate/libretranslate.h" using namespace bot::settings; -void process_database_channels(std::shared_ptr database, bot::settings::guild *guild, std::vector *webhookIds) +void process_database_channels(std::shared_ptr database, bot::settings::guild &guild, std::vector &webhookIds) { - const std::vector db_channels = database->get_channels(guild->id); + const std::vector db_channels = database->get_channels(guild.id); for (auto db_channel_id = db_channels.begin(); db_channel_id != db_channels.end(); db_channel_id++) { bool channel_found = false; - for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) { + for (auto channel = guild.channel.begin(); channel != guild.channel.end(); channel++) { if (channel->id == *db_channel_id) { - const bot::settings::channel db_channel = database->get_channel(guild->id, channel->id); + const bot::settings::channel db_channel = database->get_channel(guild.id, channel->id); if (!db_channel.source.empty()) channel->source = db_channel.source; for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) { @@ -39,14 +39,14 @@ void process_database_channels(std::shared_ptr database for (auto target = channel->targets.begin(); target != channel->targets.end(); target++) { if (target->target == db_target->target) { target->webhook = db_target->webhook; - webhookIds->push_back(db_target->webhook.id); + webhookIds.push_back(db_target->webhook.id); target_found = true; break; } } if (!target_found) { channel->targets.push_back(*db_target); - webhookIds->push_back(db_target->webhook.id); + webhookIds.push_back(db_target->webhook.id); } } channel_found = true; @@ -54,23 +54,23 @@ void process_database_channels(std::shared_ptr database } } if (!channel_found) { - const bot::settings::channel db_channel = database->get_channel(guild->id, *db_channel_id); - guild->channel.push_back(db_channel); + const bot::settings::channel db_channel = database->get_channel(guild.id, *db_channel_id); + guild.channel.push_back(db_channel); for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) - webhookIds->push_back(db_target->webhook.id); + webhookIds.push_back(db_target->webhook.id); } } } -void process_database(std::shared_ptr database, std::vector *guilds, std::vector *webhookIds) +void process_database(std::shared_ptr database, std::vector &guilds, std::vector &webhookIds) { std::cout << "[Launch] Loading database..." << std::endl; const std::vector db_guilds = database->get_guilds(); for (auto db_guild_id = db_guilds.begin(); db_guild_id != db_guilds.end(); db_guild_id++) { bool guild_found = false; - for (auto guild = guilds->begin(); guild != guilds->end(); guild++) { + for (auto guild = guilds.begin(); guild != guilds.end(); guild++) { if (guild->id == *db_guild_id) { - process_database_channels(database, &*guild, webhookIds); + process_database_channels(database, *guild, webhookIds); guild_found = true; break; } @@ -78,13 +78,13 @@ void process_database(std::shared_ptr database, std::ve if (!guild_found) { bot::settings::guild guild; guild.id = *db_guild_id; - process_database_channels(database, &guild, webhookIds); - guilds->push_back(std::move(guild)); + process_database_channels(database, guild, webhookIds); + guilds.push_back(std::move(guild)); } } } -void process_guild_settings(const dpp::json &json, std::vector *guilds, std::vector *webhookIds) +void process_guild_settings(const dpp::json &json, std::vector &guilds, std::vector &webhookIds) { for (auto json_guild = json.begin(); json_guild != json.end(); json_guild++) { if (json_guild->is_object()) { @@ -128,7 +128,7 @@ void process_guild_settings(const dpp::json &json, std::vector *guilds, s target target; target.target = *json_channel_target; target.webhook = dpp::webhook(json_channel->at("webhook")); - webhookIds->push_back(target.webhook.id); + webhookIds.push_back(target.webhook.id); channel.targets.push_back(std::move(target)); } else if (json_channel_target->is_object()) { @@ -136,7 +136,7 @@ void process_guild_settings(const dpp::json &json, std::vector *guilds, s target target; target.target = json_target.key(); target.webhook = dpp::webhook(*json_target); - webhookIds->push_back(target.webhook.id); + webhookIds.push_back(target.webhook.id); channel.targets.push_back(std::move(target)); } } @@ -146,7 +146,7 @@ void process_guild_settings(const dpp::json &json, std::vector *guilds, s guild.channel.push_back(std::move(channel)); } } - guilds->push_back(std::move(guild)); + guilds.push_back(std::move(guild)); } } } @@ -162,63 +162,63 @@ void process_preflang_settings(const dpp::json &json, std::vector * } } -void process_user_settings(const dpp::json &json, uint16_t *avatar_size) +void process_user_settings(const dpp::json &json, uint16_t &avatar_size) { auto json_avatar_size = json.find("avatar_size"); if (json_avatar_size != json.end()) { - *avatar_size = *json_avatar_size; - if (*avatar_size < 16) - *avatar_size = 16; - else if (*avatar_size > 4096) - *avatar_size = 4096; + avatar_size = *json_avatar_size; + if (avatar_size < 16) + avatar_size = 16; + else if (avatar_size > 4096) + avatar_size = 4096; } } -void process_url(const std::string &url, translator *translator) +void process_url(const std::string &url, translator &translator) { std::string_view url_v = url; if (url_v.substr(0, 7) == "http://") { - translator->tls = false; - if (!translator->port) - translator->port = 80; + translator.tls = false; + if (!translator.port) + translator.port = 80; url_v = url_v.substr(7); } else if (url_v.substr(0, 8) == "https://") { - translator->tls = true; - if (!translator->port) - translator->port = 443; + translator.tls = true; + if (!translator.port) + translator.port = 443; url_v = url_v.substr(8); } else { - translator->tls = false; - if (!translator->port) - translator->port = 80; + translator.tls = false; + if (!translator.port) + translator.port = 80; } auto slash_pos = url_v.find_first_of('/'); if (slash_pos != std::string_view::npos) { - translator->url = url_v.substr(slash_pos); + translator.url = url_v.substr(slash_pos); url_v = url_v.substr(0, slash_pos); } else { - translator->url = "/"; + translator.url = "/"; url_v = url_v.substr(0, slash_pos); } // We don't have IPv6 support here yet auto colon_pos = url_v.find_last_of(':'); if (colon_pos != std::string_view::npos) { - translator->hostname = url_v.substr(0, colon_pos); + translator.hostname = url_v.substr(0, colon_pos); const int port = std::stoi(std::string(url_v.substr(colon_pos + 1))); if (port > 0 && port < 65536) - translator->port = static_cast(port); + translator.port = static_cast(port); else throw std::invalid_argument("Port is out of range"); } else { - translator->hostname = url_v; + translator.hostname = url_v; } } -bool process_translator_settings(const dpp::json &json, translator *translator) +bool process_translator_settings(const dpp::json &json, translator &translator) { if (!json.is_object()) { std::cerr << "[Error] Value translator needs to be a object" << std::endl; @@ -227,39 +227,39 @@ bool process_translator_settings(const dpp::json &json, translator *translator) auto json_translate_hostname = json.find("hostname"); if (json_translate_hostname != json.end()) - translator->hostname = *json_translate_hostname; + translator.hostname = *json_translate_hostname; else - translator->hostname = {}; + translator.hostname = {}; auto json_translate_tls = json.find("tls"); if (json_translate_tls != json.end()) - translator->tls = *json_translate_tls; + translator.tls = *json_translate_tls; else - translator->tls = false; + translator.tls = false; auto json_translate_port = json.find("port"); if (json_translate_port != json.end()) - translator->port = *json_translate_port; + translator.port = *json_translate_port; else - translator->port = 0; + translator.port = 0; auto json_translate_url = json.find("url"); if (json_translate_url == json.end()) { std::cerr << "[Error] Value url not found in translator object" << std::endl; return false; } - if (translator->hostname.empty()) { + if (translator.hostname.empty()) { process_url(*json_translate_url, translator); } else { - translator->url = *json_translate_url; + translator.url = *json_translate_url; } auto json_translate_apiKey = json.find("apiKey"); if (json_translate_apiKey != json.end()) - translator->apiKey = *json_translate_apiKey; + translator.apiKey = *json_translate_apiKey; else - translator->apiKey.clear(); + translator.apiKey.clear(); return true; } @@ -301,6 +301,16 @@ void settings::add_translatebot_webhook(dpp::snowflake webhook_id) m_webhookIds.push_back(webhook_id); } +void settings::erase_channel(guild *guild, dpp::snowflake channel_id) +{ + for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) { + if (channel->id == channel_id) { + guild->channel.erase(channel); + return; + } + } +} + void settings::erase_translatebot_webhook(dpp::snowflake webhook_id) { const std::lock_guard guard(m_mutex); @@ -315,9 +325,9 @@ uint16_t settings::avatar_size() return m_avatarSize; } -channel* settings::get_channel(guild *guild, dpp::snowflake channel_id) +channel* settings::get_channel(guild &guild, dpp::snowflake channel_id) { - for (auto channel = guild->channel.begin(); channel != guild->channel.end(); channel++) { + for (auto channel = guild.channel.begin(); channel != guild.channel.end(); channel++) { if (channel->id == channel_id) return &*channel; } @@ -484,12 +494,12 @@ bool settings::parse(const std::string &data, bool initialize) std::cerr << "[Error] Value translator not found" << std::endl; return false; } - if (!process_translator_settings(*json_translator, &m_translator)) + if (!process_translator_settings(*json_translator, m_translator)) return false; auto json_guilds = json.find("guilds"); if (json_guilds != json.end() && json_guilds->is_object()) - process_guild_settings(*json_guilds, &m_guilds, &m_webhookIds); + process_guild_settings(*json_guilds, m_guilds, m_webhookIds); auto json_preflangs = json.find("preferred_lang"); if (json_preflangs != json.end() && json_preflangs->is_array()) @@ -497,9 +507,9 @@ bool settings::parse(const std::string &data, bool initialize) auto json_user = json.find("user"); if (json_user != json.end() && json_user->is_object()) - process_user_settings(*json_user, &m_avatarSize); + process_user_settings(*json_user, m_avatarSize); - process_database(m_database, &m_guilds, &m_webhookIds); + process_database(m_database, m_guilds, m_webhookIds); return true; } diff --git a/src/core/settings.h b/src/core/settings.h index d02db2a..48afdfc 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -33,11 +33,12 @@ namespace bot { void add_translatebot_webhook(dpp::snowflake webhook_id); /* erase functions */ + static void erase_channel(guild *guild, dpp::snowflake channel_id); void erase_translatebot_webhook(dpp::snowflake webhook_id); /* get functions */ uint16_t avatar_size(); - static channel* get_channel(guild *guild, dpp::snowflake channel_id); + static channel* get_channel(guild &guild, dpp::snowflake channel_id); channel* get_channel(dpp::snowflake guild_id, dpp::snowflake channel_id); guild* get_guild(dpp::snowflake guild_id); target* get_target(dpp::snowflake guild_id, dpp::snowflake channel_id, const std::string &target); @@ -59,6 +60,11 @@ namespace bot { bool parse(const std::string &data, bool initialize = true); bool parse_file(const std::string &filename, bool initialize = true); + /* prevent copies */ + settings() = default; + settings(const settings&) = delete; + settings& operator=(const settings&) = delete; + private: mutable std::recursive_mutex m_mutex; size_t m_externallyLockedCount = 0; diff --git a/src/core/slashcommands.cpp b/src/core/slashcommands.cpp index 49c55c2..0f78910 100644 --- a/src/core/slashcommands.cpp +++ b/src/core/slashcommands.cpp @@ -40,65 +40,76 @@ void bot::slashcommands::process_edit_command(dpp::cluster *bot, bot::settings:: dpp::command_interaction interaction = event.command.get_command_interaction(); if (interaction.options[0].name == "delete") { const std::lock_guard guard(*settings); - if (bot::settings::channel *channel = settings->get_channel(event.command.guild_id, event.command.channel_id)) { - const std::string target = std::get(event.get_parameter("target")); + if (bot::settings::guild *guild = settings->get_guild(event.command.guild_id)) { + if (bot::settings::channel *channel = settings->get_channel(*guild, event.command.channel_id)) { + const std::string target = std::get(event.get_parameter("target")); - std::shared_ptr database = settings->get_database(); - const bot::settings::channel db_channel = database->get_channel(event.command.guild_id, event.command.channel_id); + auto database = settings->get_database(); + const bot::settings::channel db_channel = database->get_channel(event.command.guild_id, event.command.channel_id); - if (db_channel.targets.empty()) { - event.reply(dpp::message("The current channel has no deleteable targets!").set_flags(dpp::m_ephemeral)); - } - else if (target == "**") { - std::vector targets; - for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) { - targets.push_back(db_target->target); + if (db_channel.targets.empty()) { + event.reply(dpp::message("The current channel has no deleteable targets!").set_flags(dpp::m_ephemeral)); } - for (auto target = channel->targets.begin(); target != channel->targets.end();) { - if (std::find(targets.begin(), targets.end(), target->target) != targets.end()) { - bot->delete_webhook(target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, target->webhook.id, std::placeholders::_1)); - target = channel->targets.erase(target); + else if (target == "**") { + std::vector targets; + for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) { + targets.push_back(db_target->target); } - else { - target++; + for (auto target = channel->targets.begin(); target != channel->targets.end();) { + if (std::find(targets.begin(), targets.end(), target->target) != targets.end()) { + bot->delete_webhook(target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, target->webhook.id, std::placeholders::_1)); + target = channel->targets.erase(target); + } + else { + target++; + } } + + database->delete_channel(event.command.guild_id, event.command.channel_id); + database->sync(); + + if (channel->targets.empty()) + settings->erase_channel(guild, event.command.channel_id); + + event.reply(dpp::message("Deleteable targets have being deleted!").set_flags(dpp::m_ephemeral)); } - - database->delete_channel(event.command.guild_id, event.command.channel_id); - database->sync(); - - event.reply(dpp::message("Deleteable targets have being deleted!").set_flags(dpp::m_ephemeral)); - } - else { - bool target_found = false; - for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) { - if (db_target->target == target) { - target_found = true; - break; - } - } - - if (target_found) { - for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) { - if (_target->target == target) { - bot->delete_webhook(_target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, _target->webhook.id, std::placeholders::_1)); - channel->targets.erase(_target); + else { + bool target_found = false; + for (auto db_target = db_channel.targets.begin(); db_target != db_channel.targets.end(); db_target++) { + if (db_target->target == target) { + target_found = true; break; } } - if (db_channel.targets.size() == 1) - database->delete_channel(event.command.guild_id, event.command.channel_id); - else - database->delete_channel_target(event.command.guild_id, event.command.channel_id, target); - database->sync(); + if (target_found) { + for (auto _target = channel->targets.begin(); _target != channel->targets.end(); _target++) { + if (_target->target == target) { + bot->delete_webhook(_target->webhook.id, std::bind(&bot::slashcommands::process_deleted_webhook, settings, _target->webhook.id, std::placeholders::_1)); + channel->targets.erase(_target); + break; + } + } - event.reply(dpp::message("Target have being deleted!").set_flags(dpp::m_ephemeral)); - } - else { - event.reply(dpp::message("Target language is not being found or deleteable!").set_flags(dpp::m_ephemeral)); + if (db_channel.targets.size() == 1) + database->delete_channel(event.command.guild_id, event.command.channel_id); + else + database->delete_channel_target(event.command.guild_id, event.command.channel_id, target); + database->sync(); + + if (channel->targets.empty()) + settings->erase_channel(guild, event.command.channel_id); + + event.reply(dpp::message("Target have being deleted!").set_flags(dpp::m_ephemeral)); + } + else { + event.reply(dpp::message("Target language is not being found or deleteable!").set_flags(dpp::m_ephemeral)); + } } } + else { + event.reply(dpp::message("The current channel is not being translated!").set_flags(dpp::m_ephemeral)); + } } else { event.reply(dpp::message("The current channel is not being translated!").set_flags(dpp::m_ephemeral)); @@ -123,7 +134,7 @@ void bot::slashcommands::process_edit_command(dpp::cluster *bot, bot::settings:: if (source_valid) { channel->source = source; - std::shared_ptr database = settings->get_database(); + auto database = settings->get_database(); database->set_channel_source(event.command.guild_id, event.command.channel_id, source); database->sync(); @@ -171,7 +182,7 @@ void bot::slashcommands::process_list_command(dpp::cluster *bot, bot::settings:: // We want give more information to users who can Manage Webhooks dpp::permission user_permissions = event.command.get_resolved_permission(event.command.usr.id); if (user_permissions.has(dpp::p_manage_webhooks)) { - std::shared_ptr database = settings->get_database(); + auto database = settings->get_database(); const bot::settings::channel db_channel = database->get_channel(event.command.guild_id, event.command.channel_id); for (auto target = channel->targets.begin(); target != channel->targets.end(); target++) { @@ -268,13 +279,13 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti dpp::command_interaction interaction = event.command.get_command_interaction(); if (interaction.options[0].name == "channel") { v_target = event.command.get_resolved_channel( - std::get(event.get_parameter("channel"))); + std::get(event.get_parameter("channel"))); } else if (interaction.options[0].name == "webhook") { v_target = dpp::webhook(std::get(event.get_parameter("webhook"))); } - const std::vector languages = settings->get_translator()->get_languages(); + const auto languages = settings->get_translator()->get_languages(); std::ostringstream language_codes; bool source_valid = false, target_valid = false; @@ -307,7 +318,7 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti settings->add_channel(s_channel, event.command.guild_id); settings->add_translatebot_webhook(webhook->id); - std::shared_ptr database = settings->get_database(); + auto database = settings->get_database(); database->set_channel_source(event.command.guild_id, event.command.channel_id, source); database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target); database->sync(); @@ -333,7 +344,7 @@ void bot::slashcommands::process_translate_command(dpp::cluster *bot, bot::setti settings->add_target(s_target, event.command.guild_id, event.command.channel_id); settings->add_translatebot_webhook(webhook->id); - std::shared_ptr database = settings->get_database(); + auto database = settings->get_database(); database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target); database->sync(); @@ -374,7 +385,7 @@ void bot::slashcommands::process_translate_webhook_add_target(bot::settings::set settings->add_target(s_target, event.command.guild_id, event.command.channel_id); settings->add_translatebot_webhook(webhook.id); - std::shared_ptr database = settings->get_database(); + auto database = settings->get_database(); database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target); database->sync(); @@ -396,7 +407,7 @@ void bot::slashcommands::process_translate_webhook_new_channel(bot::settings::se settings->add_channel(s_channel, event.command.guild_id); settings->add_translatebot_webhook(webhook.id); - std::shared_ptr database = settings->get_database(); + auto database = settings->get_database(); database->set_channel_source(event.command.guild_id, event.command.channel_id, source); database->add_channel_target(event.command.guild_id, event.command.channel_id, s_target); database->sync(); diff --git a/src/core/translator.cpp b/src/core/translator.cpp index 4d82d16..993e198 100644 --- a/src/core/translator.cpp +++ b/src/core/translator.cpp @@ -22,14 +22,6 @@ #include "translator.h" using namespace bot::translator; -translator::translator() -{ -} - -translator::~translator() -{ -} - const std::vector translator::get_languages() { #ifndef NDEBUG diff --git a/src/core/translator.h b/src/core/translator.h index d42e21b..b4f14c0 100644 --- a/src/core/translator.h +++ b/src/core/translator.h @@ -31,8 +31,8 @@ namespace bot { class translator { public: - explicit translator(); - virtual ~translator(); + explicit translator() = default; + virtual ~translator() = default; virtual const std::vector get_languages(); virtual const std::string translate(const std::string &text, const std::string &source, const std::string &target); };