diff --git a/src/script/cpp_api/s_sscsm.cpp b/src/script/cpp_api/s_sscsm.cpp index ccbc08209..70960ef06 100644 --- a/src/script/cpp_api/s_sscsm.cpp +++ b/src/script/cpp_api/s_sscsm.cpp @@ -10,6 +10,18 @@ void ScriptApiSSCSM::load_mods(const std::vector &init_paths) { //TODO + + SSCSMEnvironment *env = getSSCSMEnv(); + actionstream << "load_mods:\n"; + for (const auto &p : init_paths) { + actionstream << " " << p << ":\n"; + auto f = env->readVFSFile(p); + if (!f.has_value()) { + env->setFatalError("load_mods(): File doesn't exist: " + p); + return; + } + actionstream << *f << "\n"; + } } void ScriptApiSSCSM::environment_step(float dtime) diff --git a/src/script/lua_api/l_sscsm.cpp b/src/script/lua_api/l_sscsm.cpp index 711d6d493..c676e1588 100644 --- a/src/script/lua_api/l_sscsm.cpp +++ b/src/script/lua_api/l_sscsm.cpp @@ -9,14 +9,16 @@ #include "l_internal.h" #include "log.h" #include "script/sscsm/sscsm_environment.h" +#include "script/sscsm/sscsm_requests.h" #include "mapnode.h" // print(text) int ModApiSSCSM::l_print(lua_State *L) { - // TODO: send request to main process - std::string text = luaL_checkstring(L, 1); - rawstream << text << std::endl; + auto request = SSCSMRequestPrint{}; + request.text = luaL_checkstring(L, 1); + getSSCSMEnv(L)->doRequest(std::move(request)); + return 0; } @@ -28,11 +30,13 @@ int ModApiSSCSM::l_get_node_or_nil(lua_State *L) v3s16 pos = read_v3s16(L, 1); // Do it - bool pos_ok = true; - MapNode n = getSSCSMEnv(L)->requestGetNode(pos); //TODO: add pos_ok to request - if (pos_ok) { + auto request = SSCSMRequestGetNode{}; + request.pos = pos; + auto answer = getSSCSMEnv(L)->doRequest(std::move(request)); + + if (answer.is_pos_ok) { // Return node - pushnode(L, n); + pushnode(L, answer.node); } else { lua_pushnil(L); } diff --git a/src/script/scripting_sscsm.cpp b/src/script/scripting_sscsm.cpp index ef6889705..185047d68 100644 --- a/src/script/scripting_sscsm.cpp +++ b/src/script/scripting_sscsm.cpp @@ -4,7 +4,8 @@ #include "scripting_sscsm.h" -SSCSMScripting::SSCSMScripting(SSCSMEnvironment *env) +SSCSMScripting::SSCSMScripting(SSCSMEnvironment *env) : + ScriptApiBase(ScriptingType::SSCSM) { setSSCSMEnv(env); diff --git a/src/script/sscsm/sscsm_environment.cpp b/src/script/sscsm/sscsm_environment.cpp index 77feae001..7e04f694f 100644 --- a/src/script/sscsm/sscsm_environment.cpp +++ b/src/script/sscsm/sscsm_environment.cpp @@ -42,20 +42,26 @@ void SSCSMEnvironment::updateVFSFiles(std::vector SSCSMEnvironment::readVFSFile(const std::string &path) +{ + auto it = m_vfs.find(path); + if (it == m_vfs.end()) + return std::nullopt; + else + return it->second; +} + void SSCSMEnvironment::setFatalError(const std::string &reason) { - //TODO - // what to do on error? - // probably send a request - errorstream << "SSCSMEnvironment::setFatalError() reason: " << reason << std::endl; + auto request = SSCSMRequestSetFatalError{}; + request.reason = reason; + doRequest(std::move(request)); } std::unique_ptr SSCSMEnvironment::requestPollNextEvent() { auto request = SSCSMRequestPollNextEvent{}; - auto answer = deserializeSSCSMAnswer( - exchange(serializeSSCSMRequest(request)) - ); + auto answer = doRequest(std::move(request)); return std::move(answer.next_event); } @@ -63,8 +69,6 @@ MapNode SSCSMEnvironment::requestGetNode(v3s16 pos) { auto request = SSCSMRequestGetNode{}; request.pos = pos; - auto answer = deserializeSSCSMAnswer( - exchange(serializeSSCSMRequest(request)) - ); + auto answer = doRequest(std::move(request)); return answer.node; } diff --git a/src/script/sscsm/sscsm_environment.h b/src/script/sscsm/sscsm_environment.h index 1a37c4e81..a300fed8a 100644 --- a/src/script/sscsm/sscsm_environment.h +++ b/src/script/sscsm/sscsm_environment.h @@ -5,6 +5,9 @@ #pragma once #include +#include +#include +#include #include "client/client.h" #include "threading/thread.h" #include "sscsm_controller.h" @@ -34,6 +37,7 @@ public: SSCSMScripting *getScript() { return m_script.get(); } void updateVFSFiles(std::vector> &&files); + std::optional readVFSFile(const std::string &path); void setFatalError(const std::string &reason); void setFatalError(const LuaError &e) @@ -41,6 +45,14 @@ public: setFatalError(std::string("Lua: ") + e.what()); } + template + typename RQ::Answer doRequest(RQ &&rq) + { + return deserializeSSCSMAnswer( + exchange(serializeSSCSMRequest(std::forward(rq))) + ); + } + std::unique_ptr requestPollNextEvent(); MapNode requestGetNode(v3s16 pos); }; diff --git a/src/script/sscsm/sscsm_requests.h b/src/script/sscsm/sscsm_requests.h index bc13082a4..7dee593b1 100644 --- a/src/script/sscsm/sscsm_requests.h +++ b/src/script/sscsm/sscsm_requests.h @@ -9,7 +9,9 @@ #include "mapnode.h" #include "map.h" #include "client/client.h" +#include "log_internal.h" +// Poll the next event (e.g. on_globalstep) struct SSCSMRequestPollNextEvent : public ISSCSMRequest { struct Answer : public ISSCSMAnswer @@ -23,21 +25,81 @@ struct SSCSMRequestPollNextEvent : public ISSCSMRequest } }; +// Some error occured in the SSCSM env +struct SSCSMRequestSetFatalError : public ISSCSMRequest +{ + struct Answer : public ISSCSMAnswer + { + }; + + std::string reason; + + SerializedSSCSMAnswer exec(Client *client) override + { + client->setFatalError("[SSCSM] " + reason); + + return serializeSSCSMAnswer(Answer{}); + } +}; + +// print(text) +struct SSCSMRequestPrint : public ISSCSMRequest +{ + struct Answer : public ISSCSMAnswer + { + }; + + std::string text; + + SerializedSSCSMAnswer exec(Client *client) override + { + rawstream << text << std::endl; + + return serializeSSCSMAnswer(Answer{}); + } +}; + +// core.log(level, text) +struct SSCSMRequestLog : public ISSCSMRequest +{ + struct Answer : public ISSCSMAnswer + { + }; + + std::string text; + LogLevel level; + + SerializedSSCSMAnswer exec(Client *client) override + { + if (level >= LL_MAX) { + errorstream << "Tried to log at non-existent level." << std::endl; // TODO: should probably throw + } else { + g_logger.log(level, text); + } + + return serializeSSCSMAnswer(Answer{}); + } +}; + +// core.get_node(pos) struct SSCSMRequestGetNode : public ISSCSMRequest { struct Answer : public ISSCSMAnswer { MapNode node; + bool is_pos_ok; }; v3s16 pos; SerializedSSCSMAnswer exec(Client *client) override { - MapNode node = client->getEnv().getMap().getNode(pos); + bool is_pos_ok = false; + MapNode node = client->getEnv().getMap().getNode(pos, &is_pos_ok); Answer answer{}; answer.node = node; + answer.is_pos_ok = is_pos_ok; return serializeSSCSMAnswer(std::move(answer)); } };