diff options
| author | ilotterytea <iltsu@alright.party> | 2025-04-06 17:28:47 +0400 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-04-06 17:28:47 +0400 |
| commit | 2a49844a95593ac98e919c18651320e62f276fa7 (patch) | |
| tree | 01b7e2ebb1dc7a9ac92e7c3105edfd098271f29a /bot/src/commands | |
| parent | a1a36cf4d4999b5ce89dce95364c9fd839b54b5d (diff) | |
feat: implementing lua coding
Diffstat (limited to 'bot/src/commands')
| -rw-r--r-- | bot/src/commands/command.cpp | 30 | ||||
| -rw-r--r-- | bot/src/commands/command.hpp | 5 | ||||
| -rw-r--r-- | bot/src/commands/lua.cpp | 68 | ||||
| -rw-r--r-- | bot/src/commands/lua.hpp | 45 | ||||
| -rw-r--r-- | bot/src/commands/request.cpp | 28 | ||||
| -rw-r--r-- | bot/src/commands/request.hpp | 5 |
6 files changed, 181 insertions, 0 deletions
diff --git a/bot/src/commands/command.cpp b/bot/src/commands/command.cpp index bd33c68..97dd88b 100644 --- a/bot/src/commands/command.cpp +++ b/bot/src/commands/command.cpp @@ -3,9 +3,13 @@ #include <algorithm> #include <chrono> #include <ctime> +#include <fstream> #include <memory> #include <optional> #include <pqxx/pqxx> +#include <sol/state.hpp> +#include <sol/types.hpp> +#include <stdexcept> #include <string> #include "../bundle.hpp" @@ -23,6 +27,8 @@ #include "../modules/timer.hpp" #include "../modules/user.hpp" #include "../utils/chrono.hpp" +#include "commands/lua.hpp" +#include "logger.hpp" #include "request.hpp" #include "response.hpp" @@ -42,6 +48,30 @@ namespace bot { this->add_command(std::make_unique<mod::Settings>()); this->add_command(std::make_unique<mod::User>()); this->add_command(std::make_unique<mod::MinecraftServerCheck>()); + + this->luaState = std::make_shared<sol::state>(); + this->luaState->open_libraries(sol::lib::base, sol::lib::string); + } + + void CommandLoader::load_lua_directory(const std::string &folder_path) { + for (const auto &entry : + std::filesystem::directory_iterator(folder_path)) { + std::ifstream ifs(entry.path()); + if (!ifs.is_open()) { + throw new std::runtime_error("Failed to open the Lua file at " + + entry.path().string()); + } + std::string content, line; + + while (std::getline(ifs, line)) { + content += line + '\n'; + } + + ifs.close(); + + this->add_command( + std::make_unique<lua::LuaCommand>(this->luaState, content)); + } } void CommandLoader::add_command(std::unique_ptr<Command> command) { diff --git a/bot/src/commands/command.hpp b/bot/src/commands/command.hpp index 793446e..c2398ec 100644 --- a/bot/src/commands/command.hpp +++ b/bot/src/commands/command.hpp @@ -2,6 +2,8 @@ #include <memory> #include <optional> +#include <sol/sol.hpp> +#include <sol/state.hpp> #include <string> #include <vector> @@ -41,6 +43,7 @@ namespace bot { ~CommandLoader() = default; void add_command(std::unique_ptr<Command> cmd); + void load_lua_directory(const std::string &folder_path); std::optional<Response> run(const InstanceBundle &bundle, const Request &msg) const; @@ -50,6 +53,8 @@ namespace bot { private: std::vector<std::unique_ptr<Command>> commands; + + std::shared_ptr<sol::state> luaState; }; } } diff --git a/bot/src/commands/lua.cpp b/bot/src/commands/lua.cpp new file mode 100644 index 0000000..cd7bc84 --- /dev/null +++ b/bot/src/commands/lua.cpp @@ -0,0 +1,68 @@ +#include "commands/lua.hpp" + +#include <sol/table.hpp> +#include <string> + +#include "bundle.hpp" +#include "commands/request.hpp" +#include "commands/response.hpp" +#include "schemas/user.hpp" + +namespace bot::command::lua { + LuaCommand::LuaCommand(std::shared_ptr<sol::state> luaState, + const std::string &script) { + this->luaState = luaState; + + sol::table data = luaState->script(script); + this->name = data["name"]; + this->delay = data["delay_sec"]; + + sol::table subcommands = data["subcommands"]; + for (auto &k : subcommands) { + sol::object value = k.second; + if (value.is<std::string>()) { + this->subcommands.push_back(value.as<std::string>()); + } + } + + std::string rights_text = data["minimal_rights"]; + if (rights_text == "suspended") { + this->level = schemas::PermissionLevel::SUSPENDED; + } else if (rights_text == "user") { + this->level = schemas::PermissionLevel::USER; + } else if (rights_text == "vip") { + this->level = schemas::PermissionLevel::VIP; + } else if (rights_text == "moderator") { + this->level = schemas::PermissionLevel::MODERATOR; + } else if (rights_text == "broadcaster") { + this->level = schemas::PermissionLevel::BROADCASTER; + } else { + this->level = schemas::PermissionLevel::USER; + } + + this->handle = data["run"]; + } + + Response LuaCommand::run(const InstanceBundle &bundle, + const Request &request) const { + sol::object response = this->handle(request.as_lua_table(this->luaState)); + + if (response.is<std::string>()) { + return {response.as<std::string>()}; + } else if (response.is<sol::table>()) { + sol::table tbl = response.as<sol::table>(); + std::vector<std::string> items; + + for (auto &kv : tbl) { + sol::object value = kv.second; + if (value.is<std::string>()) { + items.push_back(value.as<std::string>()); + } + } + + return items; + } + + return {}; + } +}
\ No newline at end of file diff --git a/bot/src/commands/lua.hpp b/bot/src/commands/lua.hpp new file mode 100644 index 0000000..11e98d3 --- /dev/null +++ b/bot/src/commands/lua.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include <sol/sol.hpp> +#include <sol/state.hpp> +#include <sol/table.hpp> +#include <sol/types.hpp> +#include <string> +#include <vector> + +#include "commands/command.hpp" +#include "commands/response.hpp" +#include "schemas/user.hpp" + +void print_lua_object_type(const sol::object &obj); + +namespace bot::command::lua { + class LuaCommand : public Command { + public: + LuaCommand(std::shared_ptr<sol::state> luaState, + const std::string &content); + ~LuaCommand() = default; + + Response run(const InstanceBundle &bundle, + const Request &request) const override; + + std::string get_name() const override { return this->name; } + int get_delay_seconds() const override { return this->delay; } + schemas::PermissionLevel get_permission_level() const override { + return this->level; + } + std::vector<std::string> get_subcommand_ids() const override { + return this->subcommands; + } + + private: + std::string name; + int delay; + schemas::PermissionLevel level; + std::vector<std::string> subcommands; + + sol::function handle; + + std::shared_ptr<sol::state> luaState; + }; +}
\ No newline at end of file diff --git a/bot/src/commands/request.cpp b/bot/src/commands/request.cpp new file mode 100644 index 0000000..7acc107 --- /dev/null +++ b/bot/src/commands/request.cpp @@ -0,0 +1,28 @@ +#include "commands/request.hpp" + +#include <sol/types.hpp> + +namespace bot::command { + sol::table Request::as_lua_table(std::shared_ptr<sol::state> luaState) const { + sol::table o = luaState->create_table(); + + o["command_id"] = this->command_id; + if (this->subcommand_id.has_value()) { + o["subcommand_id"] = this->subcommand_id.value(); + } else { + o["subcommand_id"] = sol::lua_nil; + } + if (this->message.has_value()) { + o["message"] = this->message.value(); + } else { + o["message"] = sol::lua_nil; + } + + o["sender"] = this->user.as_lua_table(luaState); + o["channel"] = this->channel.as_lua_table(luaState); + o["channel_preference"] = this->channel_preferences.as_lua_table(luaState); + o["rights"] = this->user_rights.as_lua_table(luaState); + + return o; + } +}
\ No newline at end of file diff --git a/bot/src/commands/request.hpp b/bot/src/commands/request.hpp index e2685f1..b6ed534 100644 --- a/bot/src/commands/request.hpp +++ b/bot/src/commands/request.hpp @@ -1,7 +1,10 @@ #pragma once +#include <memory> #include <optional> #include <pqxx/pqxx> +#include <sol/state.hpp> +#include <sol/table.hpp> #include <string> #include "../irc/message.hpp" @@ -21,5 +24,7 @@ namespace bot::command { schemas::UserRights user_rights; pqxx::connection &conn; + + sol::table as_lua_table(std::shared_ptr<sol::state> luaState) const; }; } |
