mirror of
https://gitlab.com/niansa/SomeBot.git
synced 2025-03-06 20:48:26 +01:00
127 lines
5.1 KiB
C++
127 lines
5.1 KiB
C++
#ifndef _BOT_HPP
|
|
#define _BOT_HPP
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <functional>
|
|
#include <mutex>
|
|
#include <memory>
|
|
|
|
#include <dpp/dpp.h>
|
|
#include <dpp/cluster.h>
|
|
#include "sqlite_modern_cpp/sqlite_modern_cpp.h"
|
|
|
|
|
|
|
|
#define BOT_ADD_MODULE(name) class StaticModuleRegistration##name { \
|
|
std::unordered_map<Bot*, name*> instances; \
|
|
\
|
|
public: \
|
|
StaticModuleRegistration##name() { \
|
|
Bot::add_on_init([this](Bot *bot) { \
|
|
if (bot->is_module_enabled(#name)) bot->add_loaded_module(#name, instances[bot] = new name(bot)); \
|
|
}); \
|
|
Bot::add_on_deinit([this](Bot *bot) { \
|
|
if (bot->is_module_enabled(#name)) delete instances[bot]; \
|
|
}); \
|
|
} \
|
|
} static static_module_registration
|
|
|
|
|
|
class Bot {
|
|
static std::vector<std::function<void (Bot *)>> on_init,
|
|
on_deinit;
|
|
|
|
public:
|
|
template<class interactionCallbackDataT>
|
|
struct Interaction {
|
|
std::vector<std::string> names;
|
|
std::string description;
|
|
dpp::slashcommand misc;
|
|
using Callback = std::function<void (const interactionCallbackDataT& i)>;
|
|
Callback callback;
|
|
|
|
Interaction(const std::vector<std::string>& names, const std::string& description)
|
|
: names(names), description(description) {}
|
|
Interaction(const std::vector<std::string>& names, const std::string& description, const dpp::slashcommand& misc)
|
|
: names(names), description(description), misc(misc) {}
|
|
|
|
void operator()(const interactionCallbackDataT& i) const {
|
|
callback(i);
|
|
}
|
|
|
|
bool operator==(const dpp::interaction& i) const {
|
|
for (const auto& name : names) {
|
|
if (name == i.get_command_name()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
using ChatCommand = Interaction<dpp::slashcommand_t>;
|
|
using UserCommand = Interaction<dpp::user_context_menu_t>;
|
|
using MessageCommand = Interaction<dpp::message_context_menu_t>;
|
|
|
|
private:
|
|
bool inited = false;
|
|
|
|
std::unordered_map<std::string_view, void*> loaded_modules;
|
|
|
|
struct Commands {
|
|
std::vector<ChatCommand> chat_commands;
|
|
std::vector<UserCommand> user_commands;
|
|
std::vector<MessageCommand> message_commands;
|
|
std::vector<std::pair<ChatCommand, dpp::snowflake>> guild_chat_commands;
|
|
std::vector<std::pair<UserCommand, dpp::snowflake>> guild_user_commands;
|
|
std::vector<std::pair<MessageCommand, dpp::snowflake>> guild_message_commands;
|
|
} commands;
|
|
|
|
public:
|
|
dpp::cluster cluster;
|
|
sqlite::database db;
|
|
|
|
struct Config {
|
|
std::string id;
|
|
dpp::snowflake owner_id = 123,
|
|
management_guild_id = 123;
|
|
bool _private = false;
|
|
bool reregister_commands = false;
|
|
|
|
std::vector<std::string> modules;
|
|
|
|
enum class ModulesMode {
|
|
whitelist,
|
|
blacklist
|
|
} modules_mode = ModulesMode::blacklist;
|
|
|
|
enum class CommandAliasMode {
|
|
all,
|
|
first,
|
|
last
|
|
} command_alias_mode = CommandAliasMode::all;
|
|
} config;
|
|
std::unordered_map<std::string_view, std::pair<void*, std::mutex*>> properties;
|
|
|
|
Bot(const std::string& token, const std::string& database = "db.sqlite3");
|
|
~Bot();
|
|
|
|
void start();
|
|
static inline void add_on_init(const std::function<void (Bot*)>& cb) {on_init.push_back(cb);}
|
|
static inline void add_on_deinit(const std::function<void (Bot*)>& cb) {on_deinit.push_back(cb);}
|
|
void add_module(const std::string& name) {config.modules.push_back(name);}
|
|
template<class T>
|
|
void add_loaded_module(std::string_view name, T *instance) {loaded_modules[name] = reinterpret_cast<void*>(instance);}
|
|
template<class T>
|
|
T *get_loaded_module(std::string_view name) const {return reinterpret_cast<T*>(loaded_modules.at(name));}
|
|
bool is_module_enabled(std::string_view name);
|
|
void add_chatcommand(ChatCommand command, const ChatCommand::Callback& cb, dpp::snowflake guild_id = 0);
|
|
void add_usercommand(UserCommand command, const UserCommand::Callback& cb, dpp::snowflake guild_id = 0);
|
|
void add_messagecommand(MessageCommand command, const MessageCommand::Callback& cb, dpp::snowflake guild_id = 0);
|
|
const Commands& get_commands() const {return commands;}
|
|
template<class T>
|
|
void add_property(std::string_view name, T *value, std::mutex& mutex) {properties[name] = std::pair<void*, std::mutex*>{value, &mutex};}
|
|
template<class T>
|
|
std::pair<T*, std::unique_ptr<std::scoped_lock<std::mutex>>> get_locked_property(std::string_view name) {auto prop = properties.at(name); return {reinterpret_cast<T*>(prop.first), std::make_unique<std::scoped_lock<std::mutex>>(*prop.second)};}
|
|
};
|
|
#endif // _BOT_HPP
|