]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/script/scripting_server.cpp
Use native packer to transfer globals into async env(s)
[dragonfireclient.git] / src / script / scripting_server.cpp
index 1eee24c61a0f35ecd6076f3f7c6ce9d9b8245aa4..b462141b09ec0b9068a0b5705b53e8a78bbe24b5 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "cpp_api/s_internal.h"
 #include "lua_api/l_areastore.h"
+#include "lua_api/l_auth.h"
 #include "lua_api/l_base.h"
 #include "lua_api/l_craft.h"
 #include "lua_api/l_env.h"
@@ -35,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_nodetimer.h"
 #include "lua_api/l_noise.h"
 #include "lua_api/l_object.h"
+#include "lua_api/l_playermeta.h"
 #include "lua_api/l_particles.h"
 #include "lua_api/l_rollback.h"
 #include "lua_api/l_server.h"
@@ -45,11 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "lua_api/l_storage.h"
 
 extern "C" {
-#include "lualib.h"
+#include <lualib.h>
 }
 
 ServerScripting::ServerScripting(Server* server):
-               ScriptApiBase(ScriptingType::Server)
+               ScriptApiBase(ScriptingType::Server),
+               asyncEngine(server)
 {
        setGameDef(server);
 
@@ -60,6 +63,10 @@ ServerScripting::ServerScripting(Server* server):
 
        if (g_settings->getBool("secure.enable_security")) {
                initializeSecurity();
+       } else {
+               warningstream << "\\!/ Mod security should never be disabled, as it allows any mod to "
+                               << "access the host machine."
+                               << "Mods should use minetest.request_insecure_environment() instead \\!/" << std::endl;
        }
 
        lua_getglobal(L, "core");
@@ -82,6 +89,48 @@ ServerScripting::ServerScripting(Server* server):
        infostream << "SCRIPTAPI: Initialized game modules" << std::endl;
 }
 
+void ServerScripting::initAsync()
+{
+       // Save globals to transfer
+       {
+               lua_State *L = getStack();
+               lua_getglobal(L, "core");
+               luaL_checktype(L, -1, LUA_TTABLE);
+               lua_getfield(L, -1, "get_globals_to_transfer");
+               lua_call(L, 0, 1);
+               auto *data = script_pack(L, -1);
+               assert(!data->contains_userdata);
+               getServer()->m_async_globals_data.reset(data);
+               lua_pushnil(L);
+               lua_setfield(L, -3, "get_globals_to_transfer"); // unset function too
+               lua_pop(L, 2); // pop 'core', return value
+       }
+
+       infostream << "SCRIPTAPI: Initializing async engine" << std::endl;
+       asyncEngine.registerStateInitializer(InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiUtil::InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiCraft::InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiItemMod::InitializeAsync);
+       asyncEngine.registerStateInitializer(ModApiServer::InitializeAsync);
+       // not added: ModApiMapgen is a minefield for thread safety
+       // not added: ModApiHttp async api can't really work together with our jobs
+       // not added: ModApiStorage is probably not thread safe(?)
+
+       asyncEngine.initialize(0);
+}
+
+void ServerScripting::stepAsync()
+{
+       asyncEngine.step(getStack());
+}
+
+u32 ServerScripting::queueAsync(std::string &&serialized_func,
+       PackedValue *param, const std::string &mod_origin)
+{
+       return asyncEngine.queueAsyncJob(std::move(serialized_func),
+                       param, mod_origin);
+}
+
 void ServerScripting::InitializeModApi(lua_State *L, int top)
 {
        // Register reference classes (userdata)
@@ -99,11 +148,13 @@ void ServerScripting::InitializeModApi(lua_State *L, int top)
        NodeMetaRef::Register(L);
        NodeTimerRef::Register(L);
        ObjectRef::Register(L);
+       PlayerMetaRef::Register(L);
        LuaSettings::Register(L);
        StorageRef::Register(L);
        ModChannelRef::Register(L);
 
        // Initialize mod api modules
+       ModApiAuth::Initialize(L, top);
        ModApiCraft::Initialize(L, top);
        ModApiEnvMod::Initialize(L, top);
        ModApiInventory::Initialize(L, top);
@@ -118,7 +169,23 @@ void ServerScripting::InitializeModApi(lua_State *L, int top)
        ModApiChannels::Initialize(L, top);
 }
 
-void log_deprecated(const std::string &message)
+void ServerScripting::InitializeAsync(lua_State *L, int top)
 {
-       log_deprecated(NULL, message);
+       // classes
+       LuaItemStack::Register(L);
+       LuaPerlinNoise::Register(L);
+       LuaPerlinNoiseMap::Register(L);
+       LuaPseudoRandom::Register(L);
+       LuaPcgRandom::Register(L);
+       LuaSecureRandom::Register(L);
+       LuaVoxelManip::Register(L);
+       LuaSettings::Register(L);
+
+       // globals data
+       lua_getglobal(L, "core");
+       luaL_checktype(L, -1, LUA_TTABLE);
+       auto *data = ModApiBase::getServer(L)->m_async_globals_data.get();
+       script_unpack(L, data);
+       lua_setfield(L, -2, "transferred_globals");
+       lua_pop(L, 1); // pop 'core'
 }