55 changes: 47 additions & 8 deletions src/script/cpp_api/s_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, "/");
Expand Down Expand Up @@ -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)
{
Expand Down
3 changes: 3 additions & 0 deletions src/script/cpp_api/s_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ class ScriptApiBase : protected LuaHelper {

void clientOpenLibs(lua_State *L);

// Check things that should be set by the builtin mod.
void checkSetByBuiltin();

protected:
friend class LuaABM;
friend class LuaLBM;
Expand Down
8 changes: 2 additions & 6 deletions src/script/cpp_api/s_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions src/script/cpp_api/s_env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,14 @@ 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) {
lua_pushnumber(L, index);
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);
}

Expand Down
10 changes: 5 additions & 5 deletions src/script/cpp_api/s_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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));

Expand Down Expand Up @@ -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);
Expand All @@ -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
}
Expand Down
6 changes: 0 additions & 6 deletions src/script/cpp_api/s_security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ void ScriptApiSecurity::initializeSecurity()
"type",
"unpack",
"_VERSION",
"vector",
"xpcall",
};
static const char *whitelist_tables[] = {
Expand Down Expand Up @@ -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


Expand Down Expand Up @@ -299,7 +294,6 @@ void ScriptApiSecurity::initializeSecurityClient()
"type",
"unpack",
"_VERSION",
"vector",
"xpcall",
// Completely safe libraries
"coroutine",
Expand Down
2 changes: 1 addition & 1 deletion src/script/lua_api/l_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
19 changes: 8 additions & 11 deletions src/script/lua_api/l_env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/script/lua_api/l_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions src/script/lua_api/l_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,5 @@ class ModApiItemMod : public ModApiBase {
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);
};
4 changes: 2 additions & 2 deletions src/script/lua_api/l_particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/script/lua_api/l_particles_local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 2 additions & 6 deletions src/script/lua_api/l_vmanip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,24 +139,20 @@ int LuaVoxelManip::l_get_node_at(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;

const NodeDefManager *ndef = getServer(L)->getNodeDefManager();

LuaVoxelManip *o = checkObject<LuaVoxelManip>(L, 1);
v3s16 pos = check_v3s16(L, 2);

pushnode(L, o->vm->getNodeNoExNoEmerge(pos), ndef);
pushnode(L, o->vm->getNodeNoExNoEmerge(pos));
return 1;
}

int LuaVoxelManip::l_set_node_at(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;

const NodeDefManager *ndef = getServer(L)->getNodeDefManager();

LuaVoxelManip *o = checkObject<LuaVoxelManip>(L, 1);
v3s16 pos = check_v3s16(L, 2);
MapNode n = readnode(L, 3, ndef);
MapNode n = readnode(L, 3);

o->vm->setNodeNoEmerge(pos, n);

Expand Down
1 change: 1 addition & 0 deletions src/script/scripting_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ void Server::init()
m_inventory_mgr = std::make_unique<ServerInventoryManager>();

m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);
m_script->checkSetByBuiltin();

m_gamespec.checkAndLog();
m_modmgr->loadMods(m_script);
Expand Down