From a9c66ec217e7426e72e11371d34b32ff6fc9d282 Mon Sep 17 00:00:00 2001 From: GenericHeroGuy Date: Tue, 16 Dec 2025 23:22:29 +0100 Subject: [PATCH] Set lua_compatmode for console commands and cvar functions Thanks Indev for finding this oopsie and the patch for command code --- src/blua/liolib.c | 2 +- src/lua_consolelib.c | 39 +++++++++++++++++++++++++++++++++++---- src/lua_infolib.c | 4 ++-- src/lua_script.c | 6 +++++- src/lua_script.h | 2 +- 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/blua/liolib.c b/src/blua/liolib.c index 4cccf8740..407cca15b 100644 --- a/src/blua/liolib.c +++ b/src/blua/liolib.c @@ -328,7 +328,7 @@ void Got_LuaFile(UINT8 **cp, INT32 playernum) lua_pushstring(gL, luafiletransfers->filename); // Call the callback - LUA_Call(gL, 2, 0, 1); + LUA_Call(gL, 2, 0, 1, lua_compatmode); // TODO...? (networked io.open is 2.2+) lua_settop(gL, 0); if (success) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 261733105..9e1cbb221 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -34,6 +34,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum) UINT8 i, argc, flags; const char *argv[256]; char buf[256]; + boolean compat; argc = READUINT8(*cp); argv[0] = (const char*)*cp; @@ -74,6 +75,10 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum) if ((flags & 1) && playernum != serverplayer && !IsPlayerAdmin(playernum)) goto deny; + lua_rawgeti(gL, -1, 3); // push compatmode from command info table + compat = lua_toboolean(gL, -1); + lua_pop(gL, 1); // pop compatmode + lua_rawgeti(gL, -1, 1); // push function from command info table // although honestly this should be true anyway @@ -88,7 +93,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum) strlcpy(buf, argv[i], 255); lua_pushstring(gL, buf); } - LUA_Call(gL, (int)argc, 0, 1); // argc is 1-based, so this will cover the player we passed too. + LUA_Call(gL, (int)argc, 0, 1, compat); // argc is 1-based, so this will cover the player we passed too. lua_pop(gL, 1); // Pop LUA_GetErrorMessage (lua_pcall doesn't pop it) @@ -113,6 +118,7 @@ void COM_Lua_f(void) UINT16 flags; UINT8 lpn = 0; INT32 playernum = consoleplayer; + boolean compat; I_Assert(gL != NULL); @@ -181,6 +187,10 @@ void COM_Lua_f(void) return; } + lua_rawgeti(gL, -1, 3); // push compatmode from command info table + compat = lua_toboolean(gL, -1); + lua_pop(gL, 1); // pop compatmode + // Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION || GS_VOTING lua_rawgeti(gL, -1, 1); // push function from command info table I_Assert(lua_isfunction(gL, -1)); @@ -189,7 +199,7 @@ void COM_Lua_f(void) LUA_PushUserdata(gL, &players[playernum], META_PLAYER); for (i = 1; i < COM_Argc(); i++) lua_pushstring(gL, COM_Argv(i)); - LUA_Call(gL, (int)COM_Argc(), 0, 1); // COM_Argc is 1-based, so this will cover the player we passed too. + LUA_Call(gL, (int)COM_Argc(), 0, 1, compat); // COM_Argc is 1-based, so this will cover the player we passed too. lua_pop(gL, 1); // Pop LUA_GetErrorMessage (lua_pcall doesn't pop it) } @@ -235,6 +245,9 @@ static int lib_comAddCommand(lua_State *L) lua_pushvalue(L, 3); lua_rawseti(L, -2, 2); + + lua_pushboolean(L, lua_compatmode); + lua_rawseti(L, -2, 3); lua_setfield(L, -2, name); // Try to add the Lua command @@ -296,11 +309,19 @@ void LUA_CVarChanged(void *cvar) static void Lua_OnChange(void) { - /// \todo Network this! XD_LUAVAR + boolean compat; lua_pushcfunction(gL, LUA_GetErrorMessage); lua_insert(gL, 1); // Because LUA_Call wants it at index 1. + // From CV_OnChangeCompat registry field, get the function's compatmode setting. + lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChangeCompat"); + I_Assert(lua_istable(gL, -1)); + lua_pushlightuserdata(gL, this_cvar); + lua_rawget(gL, -2); + compat = luaL_checkboolean(gL, -1); + lua_pop(gL, 2); + // From CV_OnChange registry field, get the function for this cvar by name. lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChange"); I_Assert(lua_istable(gL, -1)); @@ -309,7 +330,7 @@ static void Lua_OnChange(void) LUA_RawPushUserdata(gL, this_cvar); - LUA_Call(gL, 1, 0, 1); // call function(cvar) + LUA_Call(gL, 1, 0, 1, compat); // call function(cvar) lua_pop(gL, 1); // pop CV_OnChange table lua_remove(gL, 1); // remove LUA_GetErrorMessage } @@ -408,6 +429,14 @@ static int lib_cvRegisterVar(lua_State *L) lua_pushvalue(L, 4); lua_rawset(L, 5); lua_pop(L, 1); + + lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChangeCompat"); + I_Assert(lua_istable(L, 5)); + lua_pushlightuserdata(L, cvar); + lua_pushboolean(L, lua_compatmode); + lua_rawset(L, 5); + lua_pop(L, 1); + cvar->func = Lua_OnChange; } lua_pop(L, 1); @@ -594,6 +623,8 @@ int LUA_ConsoleLib(lua_State *L) lua_setfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue"); lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "CV_OnChange"); + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "CV_OnChangeCompat"); // Push opaque CV_PossibleValue pointers // Because I don't care enough to bother. diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 4d6a622cb..533977696 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -708,7 +708,7 @@ static void A_Lua(mobj_t *actor) LUA_PushUserdata(gL, actor, META_MOBJ); lua_pushinteger(gL, var1); lua_pushinteger(gL, var2); - LUA_Call(gL, 3, 0, 1); + LUA_Call(gL, 3, 0, 1, lua_compatmode); // TODO lua_pop(gL, 1); // pop error handler @@ -903,7 +903,7 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) superactions[superstack] = actionpointers[actionnum].name; ++superstack; - LUA_Call(gL, 3, 0, -(2 + 3)); + LUA_Call(gL, 3, 0, -(2 + 3), lua_compatmode); // TODO lua_pop(gL, -1); // Error handler --superstack; diff --git a/src/lua_script.c b/src/lua_script.c index 50a60e687..8bc083117 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -147,8 +147,11 @@ int LUA_GetErrorMessage(lua_State *L) return 1; } -int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex) +int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex, boolean compat) { + boolean oldcompat = lua_compatmode; + lua_compatmode = compat; + int err = lua_pcall(L, nargs, nresults, errorhandlerindex); if (err) @@ -157,6 +160,7 @@ int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex) lua_pop(L, 1); } + lua_compatmode = oldcompat; return err; } diff --git a/src/lua_script.h b/src/lua_script.h index e28c37dc8..849746a55 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -54,7 +54,7 @@ extern INT32 lua_lumploading; // is LUA_LoadLump being called? extern boolean lua_compatmode; // compatmode enabled for this lump/hook? int LUA_GetErrorMessage(lua_State *L); -int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex); +int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex, boolean compat); void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults); #ifdef LUA_ALLOW_BYTECODE void LUA_DumpFile(const char *filename);