mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Implement vector and node conversion in Lua (#12609)
Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
23e9f5db43
commit
b38ffdec27
29 changed files with 191 additions and 167 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<v3s16, MapNode> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<bool>(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
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue