From 1462c638cb1512096efef98cad209592429fe7db Mon Sep 17 00:00:00 2001
From: Monster Iestyn <iestynjealous@ntlworld.com>
Date: Tue, 25 Apr 2017 21:45:53 +0100
Subject: [PATCH] Added the "lua_lumploading" variable for restricting certain
 Lua functions to lump load time only

---
 src/dehacked.c       | 7 +++++--
 src/lua_consolelib.c | 9 +++++++--
 src/lua_hooklib.c    | 4 ++--
 src/lua_hudlib.c     | 3 +++
 src/lua_script.c     | 9 ++++++++-
 src/lua_script.h     | 2 ++
 6 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/dehacked.c b/src/dehacked.c
index 82ce0a4b45..a975d76e1e 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -8131,10 +8131,13 @@ void FUNCMATH DEH_Check(void)
 static inline int lib_freeslot(lua_State *L)
 {
 	int n = lua_gettop(L);
-  int r = 0; // args returned
+	int r = 0; // args returned
 	char *s, *type,*word;
 
-  while (n-- > 0)
+	if (!lua_lumploading)
+		return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
+
+	while (n-- > 0)
   {
 		s = Z_StrDup(luaL_checkstring(L,1));
 		type = strtok(s, "_");
diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c
index 322fecb64f..b688155fbf 100644
--- a/src/lua_consolelib.c
+++ b/src/lua_consolelib.c
@@ -22,8 +22,13 @@
 #include "lua_libs.h"
 #include "lua_hud.h" // hud_running errors
 
+// for functions not allowed in hud.add hooks
 #define NOHUD if (hud_running)\
 return luaL_error(L, "HUD rendering code should not call this function!");
+// for functions not allowed in hooks or coroutines (supercedes above)
+#define NOHOOK if (!lua_lumploading)\
+		return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
+// for functions only allowed within a level
 #define INLEVEL if (gamestate != GS_LEVEL)\
 return luaL_error(L, "This function can only be used in a level!");
 
@@ -184,7 +189,7 @@ static int lib_comAddCommand(lua_State *L)
 	strlwr(name);
 
 	luaL_checktype(L, 2, LUA_TFUNCTION);
-	NOHUD
+	NOHOOK
 	if (lua_gettop(L) >= 3)
 	{ // For the third argument, only take a boolean or a number.
 		lua_settop(L, 3);
@@ -296,7 +301,7 @@ static int lib_cvRegisterVar(lua_State *L)
 	consvar_t *cvar;
 	luaL_checktype(L, 1, LUA_TTABLE);
 	lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
-	NOHUD
+	NOHOOK
 	cvar = lua_newuserdata(L, sizeof(consvar_t));
 	luaL_getmetatable(L, META_CVAR);
 	lua_setmetatable(L, -2);
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index dadc1861ac..b5a076edff 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -108,8 +108,8 @@ static int lib_addHook(lua_State *L)
 
 	luaL_checktype(L, 1, LUA_TFUNCTION);
 
-	if (hud_running)
-		return luaL_error(L, "HUD rendering code should not call this function!");
+	if (!lua_lumploading)
+		return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
 
 	switch(hook.type)
 	{
diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c
index 5b3cd46ce8..29e4970c1d 100644
--- a/src/lua_hudlib.c
+++ b/src/lua_hudlib.c
@@ -612,6 +612,9 @@ static int lib_hudadd(lua_State *L)
 	luaL_checktype(L, 1, LUA_TFUNCTION);
 	field = luaL_checkoption(L, 2, "game", hudhook_opt);
 
+	if (!lua_lumploading)
+		return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
+
 	lua_getfield(L, LUA_REGISTRYINDEX, "HUD");
 	I_Assert(lua_istable(L, -1));
 	lua_rawgeti(L, -1, field+2); // HUD[2+]
diff --git a/src/lua_script.c b/src/lua_script.c
index d30790be1b..75efb86205 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -161,6 +161,11 @@ void LUA_ClearExtVars(void)
 }
 #endif
 
+// Use this variable to prevent certain functions from running
+// if they were not called on lump load
+// (i.e. they were called in hooks or coroutines etc)
+boolean lua_lumploading = false;
+
 // Load a script from a MYFILE
 static inline void LUA_LoadFile(MYFILE *f, char *name)
 {
@@ -198,7 +203,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
 		name[strlen(wadfiles[wad]->filename)+9] = '\0';
 	}
 
-	LUA_LoadFile(&f, name);
+	lua_lumploading = true; // turn on loading flag
+	LUA_LoadFile(&f, name); // actually load file!
+	lua_lumploading = false; // turn off again
 
 	free(name);
 	Z_Free(f.data);
diff --git a/src/lua_script.h b/src/lua_script.h
index d143ed879a..51f1eaeaae 100644
--- a/src/lua_script.h
+++ b/src/lua_script.h
@@ -38,6 +38,8 @@
 void LUA_ClearExtVars(void);
 #endif
 
+extern boolean lua_lumploading; // is LUA_LoadLump being called?
+
 void LUA_LoadLump(UINT16 wad, UINT16 lump);
 #ifdef LUA_ALLOW_BYTECODE
 void LUA_DumpFile(const char *filename);
-- 
GitLab