Exemplo n.º 1
0
/** Creates a command name that replaces another command.
  */
static void COM_Alias_f(void)
{
	cmdalias_t *a;
	char cmd[1024];
	size_t i, c;

	if (COM_Argc() < 3)
	{
		CONS_Printf("alias <name> <command>\n");
		return;
	}

	a = ZZ_Alloc(sizeof *a);
	a->next = com_alias;
	com_alias = a;

	a->name = Z_StrDup(COM_Argv(1));

	// copy the rest of the command line
	cmd[0] = 0; // start out with a null string
	c = COM_Argc();
	for (i = 2; i < c; i++)
	{
		strcat(cmd, COM_Argv(i));
		if (i != c)
			strcat(cmd, " ");
	}
	strcat(cmd, "\n");

	a->value = Z_StrDup(cmd);
}
Exemplo n.º 2
0
/** Parses a string into command-line tokens.
  *
  * \param ptext A null-terminated string. Does not need to be
  *             newline-terminated.
  */
static void COM_TokenizeString(char *ptext)
{
	size_t i;

	// Clear the args from the last string.
	for (i = 0; i < com_argc; i++)
		Z_Free(com_argv[i]);

	com_argc = 0;
	com_args = NULL;

	while (com_argc < MAX_ARGS)
	{
		// Skip whitespace up to a newline.
		while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n')
			ptext++;

		// A newline means end of command in buffer,
		// thus end of this command's args too.
		if (*ptext == '\n' || *ptext == '\0')
			break;

		if (com_argc == 1)
			com_args = ptext;

		ptext = COM_Parse(ptext);
		if (ptext == NULL)
			break;

		com_argv[com_argc] = Z_StrDup(com_token);
		com_argc++;
	}
}
Exemplo n.º 3
0
// This function decides which global variables you are allowed to set.
static int noglobals(lua_State *L)
{
	const char *csname;
	char *name;

	lua_remove(L, 1); // we're not gonna be using _G
	csname = lua_tostring(L, 1);

	// make an uppercase copy of the name
	name = Z_StrDup(csname);
	strupr(name);

	if (fastncmp(name, "A_", 2) && lua_isfunction(L, 2))
	{
		// Accept new A_Action functions
		// Add the action to Lua actions refrence table
		lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);
		lua_pushstring(L, name); // "A_ACTION"
		lua_pushvalue(L, 2); // function
		lua_rawset(L, -3); // rawset doesn't trigger this metatable again.
		// otherwise we would've used setfield, obviously.

		Z_Free(name);
		return 0;
	}

	Z_Free(name);
	return luaL_error(L, "Implicit global " LUA_QS " prevented. Create a local variable instead.", csname);
}
Exemplo n.º 4
0
// Wrapper for COM_AddCommand
static int lib_comAddCommand(lua_State *L)
{
	int com_return = -1;
	const char *luaname = luaL_checkstring(L, 1);

	// must store in all lowercase
	char *name = Z_StrDup(luaname);
	strlwr(name);

	luaL_checktype(L, 2, LUA_TFUNCTION);
	NOHUD
	if (lua_gettop(L) >= 3)
	{ // For the third argument, only take a boolean or a number.
		lua_settop(L, 3);
		if (lua_type(L, 3) != LUA_TBOOLEAN)
			luaL_checktype(L, 3, LUA_TNUMBER);
	}
	else
	{ // No third argument? Default to 0.
		lua_settop(L, 2);
		lua_pushinteger(L, 0);
	}

	lua_getfield(L, LUA_REGISTRYINDEX, "COM_Command");
	I_Assert(lua_istable(L, -1));

	lua_createtable(L, 2, 0);
		lua_pushvalue(L, 2);
		lua_rawseti(L, -2, 1);

		lua_pushvalue(L, 3);
		lua_rawseti(L, -2, 2);
	lua_setfield(L, -2, name);

	// Try to add the Lua command
	com_return = COM_AddLuaCommand(name);

	if (com_return < 0)
	{ // failed to add -- free the lowercased name and return error
		Z_Free(name);
		return luaL_error(L, "Couldn't add a new console command \"%s\"", luaname);
	}
	else if (com_return == 1)
	{ // command existed already -- free our name as the old string will continue to be used
		CONS_Printf("Replaced command \"%s\"\n", name);
		Z_Free(name);
	}
	else
	{ // new command was added -- do NOT free the string as it will forever be used by the console
		CONS_Printf("Added command \"%s\"\n", name);
	}
	return 0;
}
Exemplo n.º 5
0
void QCBUILTIN PF_cl_setwindowcaption(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
	const char *newcaption = PR_GetStringOfs(prinst, OFS_PARM0);
	if (!cl.windowtitle || strcmp(cl.windowtitle, newcaption))
	{
		Z_Free(cl.windowtitle);
		cl.windowtitle = NULL;
		if (*newcaption)
			cl.windowtitle = Z_StrDup(newcaption);
		CL_UpdateWindowTitle();
	}
}
Exemplo n.º 6
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.
}
Exemplo n.º 7
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.
}
Exemplo n.º 8
0
static int lib_cvRegisterVar(lua_State *L)
{
	const char *k;
	lua_Integer i;
	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
	cvar = lua_newuserdata(L, sizeof(consvar_t));
	luaL_getmetatable(L, META_CVAR);
	lua_setmetatable(L, -2);

#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("CV_RegisterVar") " (%s)", e);
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))

	lua_pushnil(L);
	while (lua_next(L, 1)) {
		// stack: cvar table, cvar userdata, key/index, value
		//            1             2            3        4
		i = 0;
		k = NULL;
		if (lua_isnumber(L, 3))
			i = lua_tointeger(L, 3);
		else if (lua_isstring(L, 3))
			k = lua_tostring(L, 3);

		if (i == 1 || (k && fasticmp(k, "name"))) {
			if (!lua_isstring(L, 4))
				TYPEERROR("name", LUA_TSTRING)
			cvar->name = Z_StrDup(lua_tostring(L, 4));
		} else if (i == 2 || (k && fasticmp(k, "defaultvalue"))) {
			if (!lua_isstring(L, 4))
				TYPEERROR("defaultvalue", LUA_TSTRING)
			cvar->defaultvalue = Z_StrDup(lua_tostring(L, 4));
		} else if (i == 3 || (k && fasticmp(k, "flags"))) {
			if (!lua_isnumber(L, 4))
				TYPEERROR("flags", LUA_TNUMBER)
			cvar->flags = (INT32)lua_tointeger(L, 4);
		} else if (i == 4 || (k && fasticmp(k, "PossibleValue"))) {
			if (lua_islightuserdata(L, 4)) {
				CV_PossibleValue_t *pv = lua_touserdata(L, 4);
				if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural)
					cvar->PossibleValue = pv;
				else
					FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer")
			} else if (lua_istable(L, 4)) {
				// Accepts tables in the form of {MIN=0, MAX=9999} or {Red=0, Green=1, Blue=2}
				// and converts them to CV_PossibleValue_t {{0,"MIN"},{9999,"MAX"}} or {{0,"Red"},{1,"Green"},{2,"Blue"}}
				//
				// I don't really like the way this does it because a single PossibleValue table
				// being used for multiple cvars will be converted and stored multiple times.
				// So maybe instead it should be a seperate function which must be run beforehand or something.
				size_t count = 0;
				CV_PossibleValue_t *cvpv;

				lua_pushnil(L);
				while (lua_next(L, 4)) {
					count++;
					lua_pop(L, 1);
				}

				lua_getfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue");
				I_Assert(lua_istable(L, 5));
				lua_pushvalue(L, 2); // cvar userdata
				cvpv = lua_newuserdata(L, sizeof(CV_PossibleValue_t) * (count+1));
				lua_rawset(L, 5);
				lua_pop(L, 1); // pop CV_PossibleValue registry table

				i = 0;
				lua_pushnil(L);
				while (lua_next(L, 4)) {
					// stack: [...] PossibleValue table, index, value
					//                       4             5      6
					if (lua_type(L, 5) != LUA_TSTRING
					|| lua_type(L, 6) != LUA_TNUMBER)
						FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}");
					cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5));
					cvpv[i].value = (INT32)lua_tonumber(L, 6);
					i++;
					lua_pop(L, 1);
				}
				cvpv[i].value = 0;
				cvpv[i].strvalue = NULL;
				cvar->PossibleValue = cvpv;
			} else
				FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
		} else if (cvar->flags & CV_CALL && (i == 5 || (k && fasticmp(k, "func")))) {