summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bot/src/commands/command.cpp3
-rw-r--r--bot/src/commands/lua.cpp57
-rw-r--r--bot/src/commands/lua.hpp4
-rw-r--r--bot/src/modules/lua.hpp28
4 files changed, 92 insertions, 0 deletions
diff --git a/bot/src/commands/command.cpp b/bot/src/commands/command.cpp
index baf5a62..5d329ef 100644
--- a/bot/src/commands/command.cpp
+++ b/bot/src/commands/command.cpp
@@ -28,6 +28,7 @@
#include "../utils/chrono.hpp"
#include "commands/lua.hpp"
#include "logger.hpp"
+#include "modules/lua.hpp"
#include "request.hpp"
#include "response.hpp"
@@ -47,6 +48,8 @@ namespace bot {
this->add_command(std::make_unique<mod::User>());
this->add_command(std::make_unique<mod::MinecraftServerCheck>());
+ this->add_command(std::make_unique<mod::LuaExecution>());
+
this->luaState = std::make_shared<sol::state>();
this->luaState->open_libraries(sol::lib::base, sol::lib::string,
sol::lib::math);
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 <memory>
+#include <sol/forward.hpp>
+#include <sol/load_result.hpp>
+#include <sol/protected_function_result.hpp>
+#include <sol/state.hpp>
#include <sol/table.hpp>
#include <string>
#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::function>();
+ sol::object o = f(r);
+ return parse_lua_response(r, o);
+ } else if (res.get_type() == sol::type::string) {
+ return {"🌑 " + res.as<std::string>()};
+ } else if (res.get_type() == sol::type::number) {
+ return {"🌑 " + std::to_string(res.as<double>())};
+ } else if (res.get_type() == sol::type::boolean) {
+ return {"🌑 " + std::to_string(res.as<bool>())};
+ } 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<sol::state> state = std::make_shared<sol::state>();
+
+ 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<ResponseError::LUA_EXECUTION_ERROR>(
+ request, bundle.localization, std::string(err.what()));
+ }
+
+ sol::protected_function_result res = s();
+
+ if (!res.valid()) {
+ sol::error err = s;
+ throw ResponseException<ResponseError::LUA_EXECUTION_ERROR>(
+ 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<sol::state> luaState,
const std::string &script) {
this->luaState = luaState;
diff --git a/bot/src/commands/lua.hpp b/bot/src/commands/lua.hpp
index b858759..bf8a4e1 100644
--- a/bot/src/commands/lua.hpp
+++ b/bot/src/commands/lua.hpp
@@ -20,6 +20,10 @@ namespace bot::command::lua {
void add_time_library(std::shared_ptr<sol::state> state);
}
+ command::Response run_safe_lua_script(const Request &request,
+ const InstanceBundle &bundle,
+ const std::string &script);
+
class LuaCommand : public Command {
public:
LuaCommand(std::shared_ptr<sol::state> luaState,
diff --git a/bot/src/modules/lua.hpp b/bot/src/modules/lua.hpp
new file mode 100644
index 0000000..b60850a
--- /dev/null
+++ b/bot/src/modules/lua.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <string>
+
+#include "bundle.hpp"
+#include "commands/command.hpp"
+#include "commands/lua.hpp"
+#include "commands/response_error.hpp"
+
+namespace bot::mod {
+ class LuaExecution : public command::Command {
+ std::string get_name() const override { return "lua"; }
+
+ int get_delay_seconds() const override { return 1; }
+
+ command::Response run(const InstanceBundle &bundle,
+ const command::Request &request) const override {
+ if (!request.message.has_value()) {
+ throw ResponseException<ResponseError::NOT_ENOUGH_ARGUMENTS>(
+ request, bundle.localization, command::CommandArgument::VALUE);
+ }
+
+ std::string script = request.message.value();
+
+ return command::lua::run_safe_lua_script(request, bundle, script);
+ }
+ };
+} \ No newline at end of file