From 56bc7814de49cf6e2ffd9250905c3737d0bcc16a Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 4 Sep 2025 19:00:23 +0200 Subject: [PATCH] Lua API: Unify server env checks and fix missing ones (#16457) A few functions tried to dereference a ServerEnvironment nullptr by calling 'getEnv()'. This change makes use of a macro where possible. This also cleans up incorrect macro uses, with no functional difference. --- src/script/lua_api/l_auth.cpp | 10 ++---- src/script/lua_api/l_env.cpp | 4 +-- src/script/lua_api/l_internal.h | 7 +++-- src/script/lua_api/l_mapgen.cpp | 7 ++--- src/script/lua_api/l_object.cpp | 8 ++--- src/script/lua_api/l_server.cpp | 55 +++++++++++++-------------------- 6 files changed, 36 insertions(+), 55 deletions(-) diff --git a/src/script/lua_api/l_auth.cpp b/src/script/lua_api/l_auth.cpp index d65cd013b5..d669a9f5ec 100644 --- a/src/script/lua_api/l_auth.cpp +++ b/src/script/lua_api/l_auth.cpp @@ -15,14 +15,8 @@ // common start: ensure auth db AuthDatabase *ModApiAuth::getAuthDb(lua_State *L) { - ServerEnvironment *server_environment = - dynamic_cast(getEnv(L)); - if (!server_environment) { - luaL_error(L, "Attempt to access an auth function but the auth" - " system is yet not initialized. This causes bugs."); - return nullptr; - } - return server_environment->getAuthDatabase(); + GET_ENV_PTR_NO_MAP_LOCK; + return env->getAuthDatabase(); } void ModApiAuth::pushAuthEntry(lua_State *L, const AuthEntry &authEntry) diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index e21a954ac2..eff68ec852 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -1158,7 +1158,6 @@ int ModApiEnv::l_raycast(lua_State *L) int ModApiEnv::l_load_area(lua_State *L) { GET_ENV_PTR; - MAP_LOCK_REQUIRED; Map *map = &(env->getMap()); v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 1)); @@ -1373,7 +1372,8 @@ int ModApiEnv::l_forceload_free_block(lua_State *L) // get_translated_string(lang_code, string) int ModApiEnv::l_get_translated_string(lua_State * L) { - GET_ENV_PTR; + NO_MAP_LOCK_REQUIRED; + std::string lang_code = luaL_checkstring(L, 1); std::string string = luaL_checkstring(L, 2); diff --git a/src/script/lua_api/l_internal.h b/src/script/lua_api/l_internal.h index 81e6086f27..4ea3c0fcb4 100644 --- a/src/script/lua_api/l_internal.h +++ b/src/script/lua_api/l_internal.h @@ -44,8 +44,11 @@ #define GET_ENV_PTR_NO_MAP_LOCK \ DEBUG_ASSERT_NO_CLIENTAPI; \ ServerEnvironment *env = (ServerEnvironment *)getEnv(L); \ - if (env == NULL) \ - return 0 + if (!env) { \ + log_deprecated(L, "Calling this function during script init is disallowed.", 1); \ + return 0; \ + } \ + ((void)0) // Retrieve ServerEnvironment pointer as `env` #define GET_ENV_PTR \ diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 9e84241c8e..b704b3f270 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -1649,14 +1649,13 @@ int ModApiMapgen::l_generate_decorations(lua_State *L) // create_schematic(p1, p2, probability_list, filename, y_slice_prob_list) int ModApiMapgen::l_create_schematic(lua_State *L) { - MAP_LOCK_REQUIRED; + GET_ENV_PTR; const NodeDefManager *ndef = getServer(L)->getNodeDefManager(); const char *filename = luaL_checkstring(L, 4); CHECK_SECURE_PATH(L, filename, true); - Map *map = &(getEnv(L)->getMap()); Schematic schem; v3s16 p1 = check_v3s16(L, 1); @@ -1694,7 +1693,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L) } } - if (!schem.getSchematicFromMap(map, p1, p2)) { + if (!schem.getSchematicFromMap(&env->getMap(), p1, p2)) { errorstream << "create_schematic: failed to get schematic " "from map" << std::endl; return 0; @@ -1715,8 +1714,6 @@ int ModApiMapgen::l_create_schematic(lua_State *L) // replacements, force_placement, flagstring) int ModApiMapgen::l_place_schematic(lua_State *L) { - MAP_LOCK_REQUIRED; - GET_ENV_PTR; ServerMap *map = &(env->getServerMap()); diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 4f1046c515..eb9ee42bbe 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -770,7 +770,7 @@ int ObjectRef::l_get_bone_overrides(lua_State *L) // set_attach(self, parent, bone, position, rotation, force_visible) int ObjectRef::l_set_attach(lua_State *L) { - GET_ENV_PTR; + GET_ENV_PTR_NO_MAP_LOCK; ObjectRef *ref = checkObject(L, 1); ObjectRef *parent_ref = checkObject(L, 2); ServerActiveObject *sao = getobject(ref); @@ -797,7 +797,7 @@ int ObjectRef::l_set_attach(lua_State *L) // get_attach(self) int ObjectRef::l_get_attach(lua_State *L) { - GET_ENV_PTR; + GET_ENV_PTR_NO_MAP_LOCK; ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) @@ -825,7 +825,7 @@ int ObjectRef::l_get_attach(lua_State *L) // get_children(self) int ObjectRef::l_get_children(lua_State *L) { - GET_ENV_PTR; + GET_ENV_PTR_NO_MAP_LOCK; ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) @@ -898,7 +898,7 @@ int ObjectRef::l_get_properties(lua_State *L) // set_observers(self, observers) int ObjectRef::l_set_observers(lua_State *L) { - GET_ENV_PTR; + GET_ENV_PTR_NO_MAP_LOCK; ObjectRef *ref = checkObject(L, 1); ServerActiveObject *sao = getobject(ref); if (sao == nullptr) diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 8d49e15ed4..3e9b8b5c62 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -47,8 +47,7 @@ int ModApiServer::l_get_server_uptime(lua_State *L) // get_server_max_lag() int ModApiServer::l_get_server_max_lag(lua_State *L) { - NO_MAP_LOCK_REQUIRED; - GET_ENV_PTR; + GET_ENV_PTR_NO_MAP_LOCK; lua_pushnumber(L, env->getMaxLagEstimate()); return 1; } @@ -124,35 +123,34 @@ int ModApiServer::l_get_player_privs(lua_State *L) // get_player_ip() int ModApiServer::l_get_player_ip(lua_State *L) { - NO_MAP_LOCK_REQUIRED; - - Server *server = getServer(L); + GET_ENV_PTR_NO_MAP_LOCK; const char *name = luaL_checkstring(L, 1); - RemotePlayer *player = server->getEnv().getPlayer(name); + RemotePlayer *player = env->getPlayer(name); if (!player) { lua_pushnil(L); // no such player return 1; } - lua_pushstring(L, server->getPeerAddress(player->getPeerId()).serializeString().c_str()); + lua_pushstring(L, env->getGameDef()->getPeerAddress( + player->getPeerId()).serializeString().c_str() + ); return 1; } // get_player_information(name) int ModApiServer::l_get_player_information(lua_State *L) { - NO_MAP_LOCK_REQUIRED; - - Server *server = getServer(L); + GET_ENV_PTR_NO_MAP_LOCK; const char *name = luaL_checkstring(L, 1); - RemotePlayer *player = server->getEnv().getPlayer(name); + RemotePlayer *player = env->getPlayer(name); if (!player) { lua_pushnil(L); // no such player return 1; } + Server *server = env->getGameDef(); ClientInfo info; if (!server->getClientInfo(player->getPeerId(), info)) { warningstream << FUNCTION_NAME << ": no client info?!" << std::endl; @@ -271,15 +269,14 @@ int ModApiServer::l_get_player_information(lua_State *L) // get_player_window_information(name) int ModApiServer::l_get_player_window_information(lua_State *L) { - NO_MAP_LOCK_REQUIRED; - - Server *server = getServer(L); + GET_ENV_PTR_NO_MAP_LOCK; const char *name = luaL_checkstring(L, 1); - RemotePlayer *player = server->getEnv().getPlayer(name); + RemotePlayer *player = env->getPlayer(name); if (!player) return 0; + Server *server = env->getGameDef(); auto dynamic = server->getClientDynamicInfo(player->getPeerId()); if (!dynamic || dynamic->render_target_size == v2u32()) @@ -331,19 +328,16 @@ int ModApiServer::l_get_ban_description(lua_State *L) // ban_player() int ModApiServer::l_ban_player(lua_State *L) { - NO_MAP_LOCK_REQUIRED; + GET_ENV_PTR_NO_MAP_LOCK; - if (!getEnv(L)) - throw LuaError("Can't ban player before server has started up"); - - Server *server = getServer(L); const char *name = luaL_checkstring(L, 1); - RemotePlayer *player = server->getEnv().getPlayer(name); + RemotePlayer *player = env->getPlayer(name); if (!player) { lua_pushboolean(L, false); // no such player return 1; } + Server *server = env->getGameDef(); std::string ip_str = server->getPeerAddress(player->getPeerId()).serializeString(); server->setIpBanned(ip_str, name); lua_pushboolean(L, true); @@ -353,10 +347,7 @@ int ModApiServer::l_ban_player(lua_State *L) // disconnect_player(name[, reason[, reconnect]]) -> success int ModApiServer::l_disconnect_player(lua_State *L) { - NO_MAP_LOCK_REQUIRED; - - if (!getEnv(L)) - throw LuaError("Can't kick player before server has started up"); + GET_ENV_PTR_NO_MAP_LOCK; const char *name = luaL_checkstring(L, 1); std::string message; @@ -365,9 +356,7 @@ int ModApiServer::l_disconnect_player(lua_State *L) else message.append("Disconnected."); - Server *server = getServer(L); - - RemotePlayer *player = server->getEnv().getPlayer(name); + RemotePlayer *player = env->getPlayer(name); if (!player) { lua_pushboolean(L, false); // No such player return 1; @@ -375,6 +364,7 @@ int ModApiServer::l_disconnect_player(lua_State *L) bool reconnect = readParam(L, 3, false); + Server *server = env->getGameDef(); server->DenyAccess(player->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING, message, reconnect); lua_pushboolean(L, true); return 1; @@ -382,15 +372,12 @@ int ModApiServer::l_disconnect_player(lua_State *L) int ModApiServer::l_remove_player(lua_State *L) { - NO_MAP_LOCK_REQUIRED; + GET_ENV_PTR_NO_MAP_LOCK; std::string name = luaL_checkstring(L, 1); - ServerEnvironment *s_env = dynamic_cast(getEnv(L)); - if (!s_env) - throw LuaError("Can't remove player before server has started up"); - RemotePlayer *player = s_env->getPlayer(name.c_str()); + RemotePlayer *player = env->getPlayer(name.c_str()); if (!player) - lua_pushinteger(L, s_env->removePlayerFromDatabase(name) ? 0 : 1); + lua_pushinteger(L, env->removePlayerFromDatabase(name) ? 0 : 1); else lua_pushinteger(L, 2);