示例#1
0
// Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
	hook_p hookp;
	boolean hooked = false;
	if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8))))
		return 0;

	lua_settop(gL, 0);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_LinedefExecute
		&& !strcmp(hookp->s.funcname, line->text))
		{
			if (lua_gettop(gL) == 0)
			{
				LUA_PushUserdata(gL, line, META_LINE);
				LUA_PushUserdata(gL, mo, META_MOBJ);
				LUA_PushUserdata(gL, sector, META_SECTOR);
			}
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -4);
			lua_pushvalue(gL, -4);
			lua_pushvalue(gL, -4);
			LUA_Call(gL, 3);
			hooked = true;
		}

	lua_settop(gL, 0);
	return hooked;
}
示例#2
0
void LUAh_NetArchiveHook(lua_CFunction archFunc)
{
	hook_p hookp;

	if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8))))
		return;

	// stack: tables
	I_Assert(lua_gettop(gL) > 0);
	I_Assert(lua_istable(gL, -1));

	// tables becomes an upvalue of archFunc
	lua_pushvalue(gL, -1);
	lua_pushcclosure(gL, archFunc, 1);
	// stack: tables, archFunc

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_NetVars)
		{
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -2); // archFunc
			LUA_Call(gL, 1);
		}

	lua_pop(gL, 1); // pop archFunc
	// stack: tables
}
示例#3
0
void LUAh_ScoresHUD(void)
{
	if (!gL || !(hudAvailable & (1<<hudhook_scores)))
		return;

	hud_running = true;
	lua_pop(gL, -1);

	lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, 3); // HUD[3] = rendering funcs
	I_Assert(lua_istable(gL, -1));

	lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -3); // pop HUD
	lua_pushnil(gL);
	while (lua_next(gL, -3) != 0) {
		lua_pushvalue(gL, -3); // graphics library (HUD[1])
		LUA_Call(gL, 1);
	}
	lua_pop(gL, -1);
	lua_gc(gL, LUA_GCCOLLECT, 0);

	hud_running = false;
}
示例#4
0
// Hook for HUD rendering
void LUAh_GameHUD(player_t *stplyr)
{
	if (!gL || !(hudAvailable & (1<<hudhook_game)))
		return;

	hud_running = true;
	lua_pop(gL, -1);

	lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, 2); // HUD[2] = rendering funcs
	I_Assert(lua_istable(gL, -1));

	lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -3); // pop HUD
	LUA_PushUserdata(gL, stplyr, META_PLAYER);

	lua_pushnil(gL);
	while (lua_next(gL, -4) != 0) {
		lua_pushvalue(gL, -4); // graphics library (HUD[1])
		lua_pushvalue(gL, -4); // stplyr
		LUA_Call(gL, 2);
	}
	lua_pop(gL, -1);
	lua_gc(gL, LUA_GCCOLLECT, 0);

	hud_running = false;
}
示例#5
0
boolean LUA_CallAction(const char *csaction, mobj_t *actor)
{
	I_Assert(csaction != NULL);
	I_Assert(actor != NULL);

	if (!gL) // Lua isn't loaded,
		return false; // action not called.

	if (superstack && fasticmp(csaction, superactions[superstack-1])) // the action is calling itself,
		return false; // let it call the hardcoded function instead.

	// grab function by uppercase name.
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
	{
		char *action = Z_StrDup(csaction);
		strupr(action);
		lua_getfield(gL, -1, action);
		Z_Free(action);
	}
	lua_remove(gL, -2); // pop LREG_ACTIONS

	if (lua_isnil(gL, -1)) // no match
	{
		lua_pop(gL, 1); // pop nil
		return false; // action not called.
	}

	if (superstack == MAXRECURSION)
	{
		CONS_Alert(CONS_WARNING, "Max Lua Action recursion reached! Cool it on the calling A_Action functions from inside A_Action functions!\n");
		return true;
	}

	// Found a function.
	// Call it with (actor, var1, var2)
	I_Assert(lua_isfunction(gL, -1));
	LUA_PushUserdata(gL, actor, META_MOBJ);
	lua_pushinteger(gL, var1);
	lua_pushinteger(gL, var2);

	superactions[superstack] = csaction;
	++superstack;

	LUA_Call(gL, 3);

	--superstack;
	superactions[superstack] = NULL;
	return true; // action successfully called.
}
示例#6
0
// Uses astate to determine which state is calling it
// Then looks up which Lua action is assigned to that state and calls it
static void A_Lua(mobj_t *actor)
{
	boolean found = false;
	I_Assert(actor != NULL);

	// get the action for this state
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_STATEACTION);
	I_Assert(lua_istable(gL, -1));
	lua_pushlightuserdata(gL, astate);
	lua_rawget(gL, -2);
	I_Assert(lua_isfunction(gL, -1));
	lua_remove(gL, -2); // pop LREG_STATEACTION

	// get the name for this action, if possible.
	lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
	lua_pushnil(gL);
	while (lua_next(gL, -2))
	{
		if (lua_rawequal(gL, -1, -4))
		{
			found = true;
			superactions[superstack] = lua_tostring(gL, -2); // "A_ACTION"
			++superstack;
			lua_pop(gL, 2); // pop the name and function
			break;
		}
		lua_pop(gL, 1);
	}
	lua_pop(gL, 1); // pop LREG_ACTION

	LUA_PushUserdata(gL, actor, META_MOBJ);
	lua_pushinteger(gL, var1);
	lua_pushinteger(gL, var2);
	LUA_Call(gL, 3);

	if (found)
	{
		--superstack;
		superactions[superstack] = NULL;
	}

	lua_gc(gL, LUA_GCSTEP, 1);
}
示例#7
0
// Hook for Got_AddPlayer
void LUAh_PlayerJoin(int playernum)
{
	hook_p hookp;
	if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8))))
		return;

	lua_settop(gL, 0);
	lua_pushinteger(gL, playernum);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_PlayerJoin)
		{
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -2);
			LUA_Call(gL, 1);
		}

	lua_settop(gL, 0);
}
示例#8
0
// Hook for map load
void LUAh_MapLoad(void)
{
	hook_p hookp;
	if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8))))
		return;

	lua_settop(gL, 0);
	lua_pushinteger(gL, gamemap);

	for (hookp = roothook; hookp; hookp = hookp->next)
		if (hookp->type == hook_MapLoad)
		{
			lua_pushfstring(gL, FMT_HOOKID, hookp->id);
			lua_gettable(gL, LUA_REGISTRYINDEX);
			lua_pushvalue(gL, -2);
			LUA_Call(gL, 1);
		}

	lua_settop(gL, 0);
}
示例#9
0
static void Lua_OnChange(void)
{
	I_Assert(gL != NULL);
	I_Assert(cvname != NULL);

	/// \todo Network this! XD_LUAVAR

	// 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));
	lua_getfield(gL, -1, cvname); // get function

	// From the CV_Vars registry field, get the cvar's userdata by name.
	lua_getfield(gL, LUA_REGISTRYINDEX, "CV_Vars");
	I_Assert(lua_istable(gL, -1));
	lua_getfield(gL, -1, cvname); // get consvar_t* userdata.
	lua_remove(gL, -2); // pop the CV_Vars table.

	LUA_Call(gL, 1); // call function(cvar)
	lua_pop(gL, 1); // pop CV_OnChange table
}
示例#10
0
static void NetArchiveHook(lua_CFunction archFunc)
{
	int TABLESINDEX;

	if (!gL)
		return;

	TABLESINDEX = lua_gettop(gL);
	lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
	I_Assert(lua_istable(gL, -1));
	lua_rawgeti(gL, -1, hook_NetVars);
	lua_remove(gL, -2);
	I_Assert(lua_istable(gL, -1));

	lua_pushvalue(gL, TABLESINDEX);
	lua_pushcclosure(gL, archFunc, 1);
	lua_pushnil(gL);
	while (lua_next(gL, -3) != 0) {
		lua_pushvalue(gL, -3); // function
		LUA_Call(gL, 1);
	}
	lua_pop(gL, 2);
}
示例#11
0
// Wrapper for COM_AddCommand commands
void COM_Lua_f(void)
{
	char *buf, *p;
	UINT8 i, flags;
	UINT16 len;
	INT32 playernum = consoleplayer;

	I_Assert(gL != NULL);
	lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command
	I_Assert(lua_istable(gL, -1));

	// use buf temporarily -- must use lowercased string
	buf = Z_StrDup(COM_Argv(0));
	strlwr(buf);
	lua_getfield(gL, -1, buf); // push command info table
	I_Assert(lua_istable(gL, -1));
	lua_remove(gL, -2); // pop COM_Command
	Z_Free(buf);

	lua_rawgeti(gL, -1, 2); // push flags from command info table
	if (lua_isboolean(gL, -1))
		flags = (lua_toboolean(gL, -1) ? 1 : 0);
	else
		flags = (UINT8)lua_tointeger(gL, -1);
	lua_pop(gL, 1); // pop flags

	if (flags & 2) // flag 2: splitscreen player command.
	{
		if (!splitscreen)
		{
			lua_pop(gL, 1); // pop command info table
			return; // can't execute splitscreen command without player 2!
		}
		playernum = secondarydisplayplayer;
	}

	if (netgame)
	{ // Send the command through the network
		UINT8 argc;
		lua_pop(gL, 1); // pop command info table

		if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command.
		{
			CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
			return;
		}

		if (COM_Argc() > UINT8_MAX)
			argc = UINT8_MAX;
		else
			argc = (UINT8)COM_Argc();
		if (argc == UINT8_MAX)
			len = UINT16_MAX;
		else
			len = (argc+1)*256;

		buf = malloc(len);
		p = buf;
		WRITEUINT8(p, argc);
		for (i = 0; i < argc; i++)
			WRITESTRINGN(p, COM_Argv(i), 255);
		if (flags & 2)
			SendNetXCmd2(XD_LUACMD, buf, p-buf);
		else
			SendNetXCmd(XD_LUACMD, buf, p-buf);
		free(buf);
		return;
	}

	// Do the command locally, NetXCmds don't go through outside of GS_LEVEL || GS_INTERMISSION
	lua_rawgeti(gL, -1, 1); // push function from command info table
	I_Assert(lua_isfunction(gL, -1));
	lua_remove(gL, -2); // pop command info table

	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()); // COM_Argc is 1-based, so this will cover the player we passed too.
}
示例#12
0
void Got_Luacmd(UINT8 **cp, INT32 playernum)
{
	UINT8 i, argc, flags;
	char buf[256];

	// don't use I_Assert here, goto the deny code below
	// to clean up and kick people who try nefarious exploits
	// like sending random junk lua commands to crash the server

	if (!gL) goto deny;
	lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command
	if (!lua_istable(gL, -1)) goto deny;

	argc = READUINT8(*cp);
	READSTRINGN(*cp, buf, 255);
	strlwr(buf); // must lowercase buffer
	lua_getfield(gL, -1, buf); // push command info table
	if (!lua_istable(gL, -1)) goto deny;

	lua_remove(gL, -2); // pop COM_Command

	lua_rawgeti(gL, -1, 2); // push flags from command info table
	if (lua_isboolean(gL, -1))
		flags = (lua_toboolean(gL, -1) ? 1 : 0);
	else
		flags = (UINT8)lua_tointeger(gL, -1);
	lua_pop(gL, 1); // pop flags

	// requires server/admin and the player is not one of them
	if ((flags & 1) && playernum != serverplayer && !IsPlayerAdmin(playernum))
		goto deny;

	lua_rawgeti(gL, -1, 1); // push function from command info table

	// although honestly this should be true anyway
	// BUT GODDAMNIT I SAID NO I_ASSERTS SO NO I_ASSERTS IT IS
	if (!lua_isfunction(gL, -1)) goto deny;

	lua_remove(gL, -2); // pop command info table

	LUA_PushUserdata(gL, &players[playernum], META_PLAYER);
	for (i = 1; i < argc; i++)
	{
		READSTRINGN(*cp, buf, 255);
		lua_pushstring(gL, buf);
	}
	LUA_Call(gL, (int)argc); // argc is 1-based, so this will cover the player we passed too.
	return;

deny:
	//must be hacked/buggy client
	if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18
		lua_settop(gL, 0); // clear stack

	CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
	if (server)
	{
		XBOXSTATIC UINT8 bufn[2];

		bufn[0] = (UINT8)playernum;
		bufn[1] = KICK_MSG_CON_FAIL;
		SendNetXCmd(XD_KICK, &bufn, 2);
	}
}