From b38ffdec279bcded98e34f5116c8d676aa9f73a7 Mon Sep 17 00:00:00 2001 From: Jude Melton-Houghton Date: Tue, 18 Oct 2022 18:01:44 -0400 Subject: [PATCH] Implement vector and node conversion in Lua (#12609) Co-authored-by: sfan5 --- builtin/client/init.lua | 1 + builtin/common/item_s.lua | 14 ++ builtin/common/tests/misc_helpers_spec.lua | 1 - builtin/common/tests/serialize_spec.lua | 1 - builtin/common/tests/vector_spec.lua | 2 +- builtin/common/vector.lua | 25 +++- builtin/mainmenu/tests/serverlistmgr_spec.lua | 1 - src/client/client.cpp | 1 + src/gui/guiEngine.cpp | 1 + src/script/common/c_content.cpp | 44 ++----- src/script/common/c_content.h | 6 +- src/script/common/c_converter.cpp | 120 +++++++----------- src/script/common/c_internal.h | 8 +- src/script/cpp_api/s_async.cpp | 1 + src/script/cpp_api/s_base.cpp | 55 ++++++-- src/script/cpp_api/s_base.h | 3 + src/script/cpp_api/s_client.cpp | 8 +- src/script/cpp_api/s_env.cpp | 3 +- src/script/cpp_api/s_node.cpp | 10 +- src/script/cpp_api/s_security.cpp | 6 - src/script/lua_api/l_client.cpp | 2 +- src/script/lua_api/l_env.cpp | 19 ++- src/script/lua_api/l_item.cpp | 7 + src/script/lua_api/l_item.h | 1 + src/script/lua_api/l_particles.cpp | 4 +- src/script/lua_api/l_particles_local.cpp | 4 +- src/script/lua_api/l_vmanip.cpp | 8 +- src/script/scripting_client.cpp | 1 + src/server.cpp | 1 + 29 files changed, 191 insertions(+), 167 deletions(-) diff --git a/builtin/client/init.lua b/builtin/client/init.lua index 3719a90ee..68fb169f0 100644 --- a/builtin/client/init.lua +++ b/builtin/client/init.lua @@ -10,3 +10,4 @@ dofile(commonpath .. "chatcommands.lua") dofile(clientpath .. "chatcommands.lua") dofile(clientpath .. "death_formspec.lua") dofile(clientpath .. "misc.lua") +assert(loadfile(commonpath .. "item_s.lua"))({}) -- Just for push/read node functions diff --git a/builtin/common/item_s.lua b/builtin/common/item_s.lua index 6e4269b7d..f848ef6d8 100644 --- a/builtin/common/item_s.lua +++ b/builtin/common/item_s.lua @@ -223,3 +223,17 @@ function builtin_shared.cache_content_ids() end end end + +if core.set_read_node and core.set_push_node then + local function read_node(node) + return name2content[node.name], node.param1, node.param2 + end + core.set_read_node(read_node) + core.set_read_node = nil + + local function push_node(content, param1, param2) + return {name = content2name[content], param1 = param1, param2 = param2} + end + core.set_push_node(push_node) + core.set_push_node = nil +end diff --git a/builtin/common/tests/misc_helpers_spec.lua b/builtin/common/tests/misc_helpers_spec.lua index 7d046d5b7..ff0f0298a 100644 --- a/builtin/common/tests/misc_helpers_spec.lua +++ b/builtin/common/tests/misc_helpers_spec.lua @@ -1,5 +1,4 @@ _G.core = {} -_G.vector = {metatable = {}} dofile("builtin/common/vector.lua") dofile("builtin/common/misc_helpers.lua") diff --git a/builtin/common/tests/serialize_spec.lua b/builtin/common/tests/serialize_spec.lua index 340e226ee..d4e501468 100644 --- a/builtin/common/tests/serialize_spec.lua +++ b/builtin/common/tests/serialize_spec.lua @@ -1,5 +1,4 @@ _G.core = {} -_G.vector = {metatable = {}} _G.setfenv = require 'busted.compatibility'.setfenv diff --git a/builtin/common/tests/vector_spec.lua b/builtin/common/tests/vector_spec.lua index 6a0b81a89..a738e068f 100644 --- a/builtin/common/tests/vector_spec.lua +++ b/builtin/common/tests/vector_spec.lua @@ -1,4 +1,4 @@ -_G.vector = {metatable = {}} +_G.vector = {} dofile("builtin/common/vector.lua") describe("vector", function() diff --git a/builtin/common/vector.lua b/builtin/common/vector.lua index a08472e32..cebc99580 100644 --- a/builtin/common/vector.lua +++ b/builtin/common/vector.lua @@ -6,8 +6,10 @@ Note: The vector.*-functions must be able to accept old vectors that had no meta -- localize functions local setmetatable = setmetatable --- vector.metatable is set by C++. -local metatable = vector.metatable +vector = {} + +local metatable = {} +vector.metatable = metatable local xyz = {"x", "y", "z"} @@ -366,3 +368,22 @@ function vector.dir_to_rotation(forward, up) end return rot end + +if rawget(_G, "core") and core.set_read_vector and core.set_push_vector then + local function read_vector(v) + return v.x, v.y, v.z + end + core.set_read_vector(read_vector) + core.set_read_vector = nil + + if rawget(_G, "jit") then + -- This is necessary to prevent trace aborts. + local function push_vector(x, y, z) + return (fast_new(x, y, z)) + end + core.set_push_vector(push_vector) + else + core.set_push_vector(fast_new) + end + core.set_push_vector = nil +end diff --git a/builtin/mainmenu/tests/serverlistmgr_spec.lua b/builtin/mainmenu/tests/serverlistmgr_spec.lua index 013bd0a28..25e208d10 100644 --- a/builtin/mainmenu/tests/serverlistmgr_spec.lua +++ b/builtin/mainmenu/tests/serverlistmgr_spec.lua @@ -1,5 +1,4 @@ _G.core = {get_once = function(_) end} -_G.vector = {metatable = {}} _G.unpack = table.unpack _G.serverlistmgr = {} diff --git a/src/client/client.cpp b/src/client/client.cpp index a0e867ae4..bb1dc70a1 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -196,6 +196,7 @@ void Client::loadMods() // Load builtin scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); m_script->loadModFromMemory(BUILTIN_MOD_NAME); + m_script->checkSetByBuiltin(); ModConfiguration modconf; { diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index bcbc90e13..54157c792 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -226,6 +226,7 @@ bool GUIEngine::loadMainMenuScript() std::string script = porting::path_share + DIR_DELIM "builtin" + DIR_DELIM "init.lua"; try { m_script->loadScript(script); + m_script->checkSetByBuiltin(); // Menu script loaded return true; } catch (const ModError &e) { diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 928717a05..cbe2d328c 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -1175,43 +1175,27 @@ NodeBox read_nodebox(lua_State *L, int index) } /******************************************************************************/ -MapNode readnode(lua_State *L, int index, const NodeDefManager *ndef) +MapNode readnode(lua_State *L, int index) { - lua_getfield(L, index, "name"); - if (!lua_isstring(L, -1)) - throw LuaError("Node name is not set or is not a string!"); - std::string name = lua_tostring(L, -1); - lua_pop(L, 1); - - u8 param1 = 0; - lua_getfield(L, index, "param1"); - if (!lua_isnil(L, -1)) - param1 = lua_tonumber(L, -1); - lua_pop(L, 1); - - u8 param2 = 0; - lua_getfield(L, index, "param2"); - if (!lua_isnil(L, -1)) - param2 = lua_tonumber(L, -1); - lua_pop(L, 1); - - content_t id = CONTENT_IGNORE; - if (!ndef->getId(name, id)) - throw LuaError("\"" + name + "\" is not a registered node!"); - - return {id, param1, param2}; + lua_pushvalue(L, index); + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_NODE); + lua_insert(L, -2); + lua_call(L, 1, 3); + content_t content = lua_tointeger(L, -3); + u8 param1 = lua_tointeger(L, -2); + u8 param2 = lua_tointeger(L, -1); + lua_pop(L, 3); + return MapNode(content, param1, param2); } /******************************************************************************/ -void pushnode(lua_State *L, const MapNode &n, const NodeDefManager *ndef) +void pushnode(lua_State *L, const MapNode &n) { - lua_createtable(L, 0, 3); - lua_pushstring(L, ndef->get(n).name.c_str()); - lua_setfield(L, -2, "name"); + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_NODE); + lua_pushinteger(L, n.getContent()); lua_pushinteger(L, n.getParam1()); - lua_setfield(L, -2, "param1"); lua_pushinteger(L, n.getParam2()); - lua_setfield(L, -2, "param2"); + lua_call(L, 3, 1); } /******************************************************************************/ diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index ade3e4c1e..457b3f840 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -129,10 +129,8 @@ void read_inventory_list (lua_State *L, int tableindex, Inventory *inv, const char *name, IGameDef *gdef, int forcesize=-1); -MapNode readnode (lua_State *L, int index, - const NodeDefManager *ndef); -void pushnode (lua_State *L, const MapNode &n, - const NodeDefManager *ndef); +MapNode readnode (lua_State *L, int index); +void pushnode (lua_State *L, const MapNode &n); void read_groups (lua_State *L, int index, diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index 69da35b73..90b78a081 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -48,17 +48,19 @@ extern "C" { } \ } while (0) -#define CHECK_POS_COORD(name) CHECK_TYPE(-1, "vector coordinate " name, LUA_TNUMBER) +#define CHECK_POS_COORD(index, name) CHECK_TYPE(index, "vector coordinate " name, LUA_TNUMBER) #define CHECK_POS_TAB(index) CHECK_TYPE(index, "vector", LUA_TTABLE) /** - * A helper which sets the vector metatable for the table on top of the stack + * A helper which calls CUSTOM_RIDX_READ_VECTOR with the argument at the given index */ -static void set_vector_metatable(lua_State *L) +static void read_v3_aux(lua_State *L, int index) { - lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); - lua_setmetatable(L, -2); + lua_pushvalue(L, index); + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_VECTOR); + lua_insert(L, -2); + lua_call(L, 1, 3); } // Retrieve an integer vector where all components are optional @@ -79,14 +81,11 @@ static bool getv3intfield(lua_State *L, int index, void push_v3f(lua_State *L, v3f p) { - lua_createtable(L, 0, 3); + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_VECTOR); lua_pushnumber(L, p.X); - lua_setfield(L, -2, "x"); lua_pushnumber(L, p.Y); - lua_setfield(L, -2, "y"); lua_pushnumber(L, p.Z); - lua_setfield(L, -2, "z"); - set_vector_metatable(L); + lua_call(L, 3, 1); } void push_v2f(lua_State *L, v2f p) @@ -160,12 +159,12 @@ v2f check_v2f(lua_State *L, int index) v2f p; CHECK_POS_TAB(index); lua_getfield(L, index, "x"); - CHECK_POS_COORD("x"); + CHECK_POS_COORD(-1, "x"); p.X = lua_tonumber(L, -1); CHECK_FLOAT(p.X, "x"); lua_pop(L, 1); lua_getfield(L, index, "y"); - CHECK_POS_COORD("y"); + CHECK_POS_COORD(-1, "y"); p.Y = lua_tonumber(L, -1); CHECK_FLOAT(p.Y, "y"); lua_pop(L, 1); @@ -174,78 +173,48 @@ v2f check_v2f(lua_State *L, int index) v3f read_v3f(lua_State *L, int index) { - v3f pos; - CHECK_POS_TAB(index); - lua_getfield(L, index, "x"); - pos.X = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - pos.Y = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "z"); - pos.Z = lua_tonumber(L, -1); - lua_pop(L, 1); - return pos; + read_v3_aux(L, index); + float x = lua_tonumber(L, -3); + float y = lua_tonumber(L, -2); + float z = lua_tonumber(L, -1); + lua_pop(L, 3); + return v3f(x, y, z); } v3f check_v3f(lua_State *L, int index) { - v3f pos; - CHECK_POS_TAB(index); - lua_getfield(L, index, "x"); - CHECK_POS_COORD("x"); - pos.X = lua_tonumber(L, -1); - CHECK_FLOAT(pos.X, "x"); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - CHECK_POS_COORD("y"); - pos.Y = lua_tonumber(L, -1); - CHECK_FLOAT(pos.Y, "y"); - lua_pop(L, 1); - lua_getfield(L, index, "z"); - CHECK_POS_COORD("z"); - pos.Z = lua_tonumber(L, -1); - CHECK_FLOAT(pos.Z, "z"); - lua_pop(L, 1); - return pos; + read_v3_aux(L, index); + CHECK_POS_COORD(-3, "x"); + CHECK_POS_COORD(-2, "y"); + CHECK_POS_COORD(-1, "z"); + float x = lua_tonumber(L, -3); + float y = lua_tonumber(L, -2); + float z = lua_tonumber(L, -1); + lua_pop(L, 3); + return v3f(x, y, z); } v3d read_v3d(lua_State *L, int index) { - v3d pos; - CHECK_POS_TAB(index); - lua_getfield(L, index, "x"); - pos.X = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - pos.Y = lua_tonumber(L, -1); - lua_pop(L, 1); - lua_getfield(L, index, "z"); - pos.Z = lua_tonumber(L, -1); - lua_pop(L, 1); - return pos; + read_v3_aux(L, index); + double x = lua_tonumber(L, -3); + double y = lua_tonumber(L, -2); + double z = lua_tonumber(L, -1); + lua_pop(L, 3); + return v3d(x, y, z); } v3d check_v3d(lua_State *L, int index) { - v3d pos; - CHECK_POS_TAB(index); - lua_getfield(L, index, "x"); - CHECK_POS_COORD("x"); - pos.X = lua_tonumber(L, -1); - CHECK_FLOAT(pos.X, "x"); - lua_pop(L, 1); - lua_getfield(L, index, "y"); - CHECK_POS_COORD("y"); - pos.Y = lua_tonumber(L, -1); - CHECK_FLOAT(pos.Y, "y"); - lua_pop(L, 1); - lua_getfield(L, index, "z"); - CHECK_POS_COORD("z"); - pos.Z = lua_tonumber(L, -1); - CHECK_FLOAT(pos.Z, "z"); - lua_pop(L, 1); - return pos; + read_v3_aux(L, index); + CHECK_POS_COORD(-3, "x"); + CHECK_POS_COORD(-2, "y"); + CHECK_POS_COORD(-1, "z"); + double x = lua_tonumber(L, -3); + double y = lua_tonumber(L, -2); + double z = lua_tonumber(L, -1); + lua_pop(L, 3); + return v3d(x, y, z); } void push_ARGB8(lua_State *L, video::SColor color) @@ -274,14 +243,11 @@ v3f checkFloatPos(lua_State *L, int index) void push_v3s16(lua_State *L, v3s16 p) { - lua_createtable(L, 0, 3); + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_VECTOR); lua_pushinteger(L, p.X); - lua_setfield(L, -2, "x"); lua_pushinteger(L, p.Y); - lua_setfield(L, -2, "y"); lua_pushinteger(L, p.Z); - lua_setfield(L, -2, "z"); - set_vector_metatable(L); + lua_call(L, 3, 1); } v3s16 read_v3s16(lua_State *L, int index) diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h index 95ffe7d3b..5cbcbb7db 100644 --- a/src/script/common/c_internal.h +++ b/src/script/common/c_internal.h @@ -56,8 +56,14 @@ enum { CUSTOM_RIDX_CURRENT_MOD_NAME, CUSTOM_RIDX_BACKTRACE, CUSTOM_RIDX_HTTP_API_LUA, - CUSTOM_RIDX_VECTOR_METATABLE, CUSTOM_RIDX_METATABLE_MAP, + + // The following four functions are implemented in Lua because LuaJIT can + // trace them and optimize tables/string better than from the C API. + CUSTOM_RIDX_READ_VECTOR, + CUSTOM_RIDX_PUSH_VECTOR, + CUSTOM_RIDX_READ_NODE, + CUSTOM_RIDX_PUSH_NODE, }; diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp index 42a794ceb..ca88031fd 100644 --- a/src/script/cpp_api/s_async.cpp +++ b/src/script/cpp_api/s_async.cpp @@ -247,6 +247,7 @@ bool AsyncEngine::prepareEnvironment(lua_State* L, int top) try { script->loadMod(Server::getBuiltinLuaPath() + DIR_DELIM + "init.lua", BUILTIN_MOD_NAME); + script->checkSetByBuiltin(); } catch (const ModError &e) { errorstream << "Execution of async base environment failed: " << e.what() << std::endl; diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index 5569a536e..e8d973de1 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -120,16 +120,32 @@ ScriptApiBase::ScriptApiBase(ScriptingType type): #endif // Add basic globals - lua_newtable(m_luastack); - lua_setglobal(m_luastack, "core"); - // vector.metatable is stored in the registry for quick access from C++. + // "core" table: lua_newtable(m_luastack); - lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); - lua_newtable(m_luastack); - lua_rawgeti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_VECTOR_METATABLE); - lua_setfield(m_luastack, -2, "metatable"); - lua_setglobal(m_luastack, "vector"); + // Populate with some internal functions which will be removed in Lua: + lua_pushcfunction(m_luastack, [](lua_State *L) -> int { + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_VECTOR); + return 0; + }); + lua_setfield(m_luastack, -2, "set_read_vector"); + lua_pushcfunction(m_luastack, [](lua_State *L) -> int { + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_VECTOR); + return 0; + }); + lua_setfield(m_luastack, -2, "set_push_vector"); + lua_pushcfunction(m_luastack, [](lua_State *L) -> int { + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_NODE); + return 0; + }); + lua_setfield(m_luastack, -2, "set_read_node"); + lua_pushcfunction(m_luastack, [](lua_State *L) -> int { + lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_NODE); + return 0; + }); + lua_setfield(m_luastack, -2, "set_push_node"); + // Finally, put the table into the global environment: + lua_setglobal(m_luastack, "core"); if (m_type == ScriptingType::Client) lua_pushstring(m_luastack, "/"); @@ -180,6 +196,29 @@ void ScriptApiBase::clientOpenLibs(lua_State *L) } } +void ScriptApiBase::checkSetByBuiltin() +{ + lua_State *L = getStack(); + + if (m_gamedef) { + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_VECTOR); + FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing read_vector"); + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_VECTOR); + FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing push_vector"); + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_READ_NODE); + FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing read_node"); + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_PUSH_NODE); + FATAL_ERROR_IF(lua_type(L, -1) != LUA_TFUNCTION, "missing push_node"); + lua_pop(L, 1); + } +} + void ScriptApiBase::loadMod(const std::string &script_path, const std::string &mod_name) { diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h index 244d81605..1dc810e08 100644 --- a/src/script/cpp_api/s_base.h +++ b/src/script/cpp_api/s_base.h @@ -115,6 +115,9 @@ public: void clientOpenLibs(lua_State *L); + // Check things that should be set by the builtin mod. + void checkSetByBuiltin(); + protected: friend class LuaABM; friend class LuaLBM; diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index b02a0c7be..b937c9f7b 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -186,15 +186,13 @@ bool ScriptApiClient::on_dignode(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER - const NodeDefManager *ndef = getClient()->ndef(); - // Get core.registered_on_dignode lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_dignode"); // Push data push_v3s16(L, p); - pushnode(L, node, ndef); + pushnode(L, node); // Call functions try { @@ -210,15 +208,13 @@ bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node) { SCRIPTAPI_PRECHECKHEADER - const NodeDefManager *ndef = getClient()->ndef(); - // Get core.registered_on_punchgnode lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_on_punchnode"); // Push data push_v3s16(L, p); - pushnode(L, node, ndef); + pushnode(L, node); // Call functions try { diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index af68f689f..55c0a84f5 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -274,7 +274,6 @@ void ScriptApiEnv::on_liquid_transformed( // Convert the list to a pos array and a node array for lua int index = 1; - const NodeDefManager *ndef = getEnv()->getGameDef()->ndef(); lua_createtable(L, list.size(), 0); lua_createtable(L, list.size(), 0); for(std::pair p : list) { @@ -282,7 +281,7 @@ void ScriptApiEnv::on_liquid_transformed( push_v3s16(L, p.first); lua_rawset(L, -4); lua_pushnumber(L, index++); - pushnode(L, p.second, ndef); + pushnode(L, p.second); lua_rawset(L, -3); } diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index a9638e239..bed5966cf 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -119,7 +119,7 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node, // Call function push_v3s16(L, p); - pushnode(L, node, ndef); + pushnode(L, node); objectrefGetOrCreate(L, puncher); pushPointedThing(pointed); PCALL_RES(lua_pcall(L, 4, 0, error_handler)); @@ -142,7 +142,7 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node, // Call function push_v3s16(L, p); - pushnode(L, node, ndef); + pushnode(L, node); objectrefGetOrCreate(L, digger); PCALL_RES(lua_pcall(L, 3, 1, error_handler)); @@ -204,8 +204,8 @@ bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode) // Call function push_v3s16(L, p); - pushnode(L, node, ndef); - pushnode(L, newnode, ndef); + pushnode(L, node); + pushnode(L, newnode); PCALL_RES(lua_pcall(L, 3, 1, error_handler)); lua_remove(L, error_handler); return readParam(L, -1, false); @@ -225,7 +225,7 @@ void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node) // Call function push_v3s16(L, p); - pushnode(L, node, ndef); + pushnode(L, node); PCALL_RES(lua_pcall(L, 2, 0, error_handler)); lua_pop(L, 1); // Pop error handler } diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index d34e15f4e..0d989ae04 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -98,7 +98,6 @@ void ScriptApiSecurity::initializeSecurity() "type", "unpack", "_VERSION", - "vector", "xpcall", }; static const char *whitelist_tables[] = { @@ -253,10 +252,6 @@ void ScriptApiSecurity::initializeSecurity() lua_pushnil(L); lua_setfield(L, old_globals, "core"); - // 'vector' as well. - lua_pushnil(L); - lua_setfield(L, old_globals, "vector"); - lua_pop(L, 1); // Pop globals_backup @@ -299,7 +294,6 @@ void ScriptApiSecurity::initializeSecurityClient() "type", "unpack", "_VERSION", - "vector", "xpcall", // Completely safe libraries "coroutine", diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index 9f776ae28..a1828a03b 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -220,7 +220,7 @@ int ModApiClient::l_get_node_or_nil(lua_State *L) MapNode n = getClient(L)->CSMGetNode(pos, &pos_ok); if (pos_ok) { // Return node - pushnode(L, n, getClient(L)->ndef()); + pushnode(L, n); } else { lua_pushnil(L); } diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index b40ccf518..642101166 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -98,7 +98,7 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n, luaL_checktype(L, -1, LUA_TFUNCTION); lua_remove(L, -2); // Remove registered_abms[m_id] push_v3s16(L, p); - pushnode(L, n, env->getGameDef()->ndef()); + pushnode(L, n); lua_pushnumber(L, active_object_count); lua_pushnumber(L, active_object_count_wider); @@ -140,7 +140,7 @@ void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n) luaL_checktype(L, -1, LUA_TFUNCTION); lua_remove(L, -2); // Remove registered_lbms[m_id] push_v3s16(L, p); - pushnode(L, n, env->getGameDef()->ndef()); + pushnode(L, n); int result = lua_pcall(L, 2, 0, error_handler); if (result) @@ -247,10 +247,9 @@ int ModApiEnvMod::l_set_node(lua_State *L) { GET_ENV_PTR; - const NodeDefManager *ndef = env->getGameDef()->ndef(); // parameters v3s16 pos = read_v3s16(L, 1); - MapNode n = readnode(L, 2, ndef); + MapNode n = readnode(L, 2); // Do it bool succeeded = env->setNode(pos, n); lua_pushboolean(L, succeeded); @@ -263,7 +262,6 @@ int ModApiEnvMod::l_bulk_set_node(lua_State *L) { GET_ENV_PTR; - const NodeDefManager *ndef = env->getGameDef()->ndef(); // parameters if (!lua_istable(L, 1)) { return 0; @@ -275,7 +273,7 @@ int ModApiEnvMod::l_bulk_set_node(lua_State *L) return 1; } - MapNode n = readnode(L, 2, ndef); + MapNode n = readnode(L, 2); // Do it bool succeeded = true; @@ -315,10 +313,9 @@ int ModApiEnvMod::l_swap_node(lua_State *L) { GET_ENV_PTR; - const NodeDefManager *ndef = env->getGameDef()->ndef(); // parameters v3s16 pos = read_v3s16(L, 1); - MapNode n = readnode(L, 2, ndef); + MapNode n = readnode(L, 2); // Do it bool succeeded = env->swapNode(pos, n); lua_pushboolean(L, succeeded); @@ -336,7 +333,7 @@ int ModApiEnvMod::l_get_node(lua_State *L) // Do it MapNode n = env->getMap().getNode(pos); // Return node - pushnode(L, n, env->getGameDef()->ndef()); + pushnode(L, n); return 1; } @@ -353,7 +350,7 @@ int ModApiEnvMod::l_get_node_or_nil(lua_State *L) MapNode n = env->getMap().getNode(pos, &pos_ok); if (pos_ok) { // Return node - pushnode(L, n, env->getGameDef()->ndef()); + pushnode(L, n); } else { lua_pushnil(L); } @@ -438,7 +435,7 @@ int ModApiEnvMod::l_place_node(lua_State *L) IItemDefManager *idef = server->idef(); v3s16 pos = read_v3s16(L, 1); - MapNode n = readnode(L, 2, ndef); + MapNode n = readnode(L, 2); // Don't attempt to load non-loaded area as of now MapNode n_old = env->getMap().getNode(pos); diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index f33dd1fef..549f17261 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -721,3 +721,10 @@ void ModApiItemMod::InitializeAsync(lua_State *L, int top) API_FCT(get_content_id); API_FCT(get_name_from_content_id); } + +void ModApiItemMod::InitializeClient(lua_State *L, int top) +{ + // all read-only functions + API_FCT(get_content_id); + API_FCT(get_name_from_content_id); +} diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index a4cc706d8..aa7d028da 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -174,4 +174,5 @@ private: public: static void Initialize(lua_State *L, int top); static void InitializeAsync(lua_State *L, int top); + static void InitializeClient(lua_State *L, int top); }; diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 21f27bf8f..06511df07 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -138,7 +138,7 @@ int ModApiParticles::l_add_particle(lua_State *L) lua_getfield(L, 1, "node"); if (lua_istable(L, -1)) - p.node = readnode(L, -1, getGameDef(L)->ndef()); + p.node = readnode(L, -1); lua_pop(L, 1); p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); @@ -289,7 +289,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) lua_getfield(L, 1, "node"); if (lua_istable(L, -1)) - p.node = readnode(L, -1, getGameDef(L)->ndef()); + p.node = readnode(L, -1); lua_pop(L, 1); p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); diff --git a/src/script/lua_api/l_particles_local.cpp b/src/script/lua_api/l_particles_local.cpp index 62cbab8e9..43304b7a7 100644 --- a/src/script/lua_api/l_particles_local.cpp +++ b/src/script/lua_api/l_particles_local.cpp @@ -87,7 +87,7 @@ int ModApiParticlesLocal::l_add_particle(lua_State *L) lua_getfield(L, 1, "node"); if (lua_istable(L, -1)) - p.node = readnode(L, -1, getGameDef(L)->ndef()); + p.node = readnode(L, -1); lua_pop(L, 1); p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); @@ -185,7 +185,7 @@ int ModApiParticlesLocal::l_add_particlespawner(lua_State *L) lua_getfield(L, 1, "node"); if (lua_istable(L, -1)) - p.node = readnode(L, -1, getGameDef(L)->ndef()); + p.node = readnode(L, -1); lua_pop(L, 1); p.node_tile = getintfield_default(L, 1, "node_tile", p.node_tile); diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp index 8f40b7d4a..f6d11088e 100644 --- a/src/script/lua_api/l_vmanip.cpp +++ b/src/script/lua_api/l_vmanip.cpp @@ -139,12 +139,10 @@ int LuaVoxelManip::l_get_node_at(lua_State *L) { NO_MAP_LOCK_REQUIRED; - const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); - LuaVoxelManip *o = checkObject(L, 1); v3s16 pos = check_v3s16(L, 2); - pushnode(L, o->vm->getNodeNoExNoEmerge(pos), ndef); + pushnode(L, o->vm->getNodeNoExNoEmerge(pos)); return 1; } @@ -152,11 +150,9 @@ int LuaVoxelManip::l_set_node_at(lua_State *L) { NO_MAP_LOCK_REQUIRED; - const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); - LuaVoxelManip *o = checkObject(L, 1); v3s16 pos = check_v3s16(L, 2); - MapNode n = readnode(L, 3, ndef); + MapNode n = readnode(L, 3); o->vm->setNodeNoEmerge(pos, n); diff --git a/src/script/scripting_client.cpp b/src/script/scripting_client.cpp index 377205379..be3bdc2c8 100644 --- a/src/script/scripting_client.cpp +++ b/src/script/scripting_client.cpp @@ -78,6 +78,7 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) ModApiUtil::InitializeClient(L, top); ModApiClient::Initialize(L, top); + ModApiItemMod::InitializeClient(L, top); ModApiStorage::Initialize(L, top); ModApiEnvMod::InitializeClient(L, top); ModApiChannels::Initialize(L, top); diff --git a/src/server.cpp b/src/server.cpp index c544af534..5451e3833 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -447,6 +447,7 @@ void Server::init() m_inventory_mgr = std::make_unique(); m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME); + m_script->checkSetByBuiltin(); m_gamespec.checkAndLog(); m_modmgr->loadMods(m_script);