From 3d4bdc1cd39726949d7d25a6a2db45ada86a087a Mon Sep 17 00:00:00 2001 From: ilotterytea Date: Sun, 6 Apr 2025 19:29:55 +0400 Subject: feat: a command for executing lua scripts --- bot/src/commands/lua.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'bot/src/commands/lua.cpp') diff --git a/bot/src/commands/lua.cpp b/bot/src/commands/lua.cpp index db89eff..7f30f41 100644 --- a/bot/src/commands/lua.cpp +++ b/bot/src/commands/lua.cpp @@ -1,11 +1,17 @@ #include "commands/lua.hpp" +#include +#include +#include +#include +#include #include #include #include "bundle.hpp" #include "commands/request.hpp" #include "commands/response.hpp" +#include "commands/response_error.hpp" #include "schemas/user.hpp" #include "utils/chrono.hpp" #include "utils/string.hpp" @@ -59,6 +65,57 @@ namespace bot::command::lua { } } + std::string parse_lua_response(const sol::table &r, sol::object &res) { + if (res.get_type() == sol::type::function) { + sol::function f = res.as(); + sol::object o = f(r); + return parse_lua_response(r, o); + } else if (res.get_type() == sol::type::string) { + return {"🌑 " + res.as()}; + } else if (res.get_type() == sol::type::number) { + return {"🌑 " + std::to_string(res.as())}; + } else if (res.get_type() == sol::type::boolean) { + return {"🌑 " + std::to_string(res.as())}; + } else { + // should it be ResponseException? + return "Empty or unsupported response"; + } + } + + command::Response run_safe_lua_script(const Request &request, + const InstanceBundle &bundle, + const std::string &script) { + // shared_ptr is unnecessary here, but my library needs it. + std::shared_ptr state = std::make_shared(); + + state->open_libraries(sol::lib::base, sol::lib::table, sol::lib::string); + library::add_bot_library(state); + library::add_time_library(state); + + sol::load_result s = state->load("return " + script); + if (!s.valid()) { + s = state->load(script); + } + + if (!s.valid()) { + sol::error err = s; + throw ResponseException( + request, bundle.localization, std::string(err.what())); + } + + sol::protected_function_result res = s(); + + if (!res.valid()) { + sol::error err = s; + throw ResponseException( + request, bundle.localization, std::string(err.what())); + } + + sol::object o = res; + + return parse_lua_response(request.as_lua_table(state), o); + } + LuaCommand::LuaCommand(std::shared_ptr luaState, const std::string &script) { this->luaState = luaState; -- cgit v1.2.3