Ejemplo n.º 1
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
static void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
	qboolean	valid;
	unsigned int time;
	char		remaining[1024];
	// TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
	// (OOB messages are the bottleneck here)
#define SV_OUTPUTBUF_LENGTH (1024 - 16)
	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static unsigned int lasttime = 0;
	char *cmd_aux;

	// TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534
	time = Com_Milliseconds();
	if ( (unsigned)( time - lasttime ) < 500u ) {
		return;
	}
	lasttime = time;

	if ( !strlen( sv_rconPassword->string ) ||
		strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
		valid = qfalse;
		Com_Printf ("Bad rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2) );
	} else {
		valid = qtrue;
		Com_Printf ("Rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2) );
	}

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf ("No rconpassword set on the server.\n");
	} else if ( !valid ) {
		Com_Printf ("Bad rconpassword.\n");
	} else {
		remaining[0] = 0;
		
		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543
		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
		// extract the command by walking
		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
		cmd_aux = Cmd_Cmd();
		cmd_aux+=4;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		while(cmd_aux[0] && cmd_aux[0]!=' ') // password
			cmd_aux++;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		
		Q_strcat( remaining, sizeof(remaining), cmd_aux);
		
		Cmd_ExecuteString (remaining);

	}

	Com_EndRedirect ();
}
Ejemplo n.º 2
0
/*
===================
Key_Bind_f
===================
*/
static void Key_Bind_f(void)
{
    int c, b;

    c = Cmd_Argc();

    if (c < 2) {
        Com_Printf("bind <key> [command] : attach a command to a key\n");
        return;
    }
    b = Key_StringToKeynum(Cmd_Argv(1));
    if (b == -1) {
        Com_Printf("\"%s\" isn't a valid key\n", Cmd_Argv(1));
        return;
    }

    if (c == 2) {
        if (keybindings[b])
            Com_Printf("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b]);
        else
            Com_Printf("\"%s\" is not bound\n", Cmd_Argv(1));
        return;
    }

// copy the rest of the command line
    Key_SetBinding(b, Cmd_ArgsFrom(2));
}
Ejemplo n.º 3
0
/*
==================
SV_ConTell_f
==================
*/
static void SV_ConTell_f(void) {
	char	*p;
	char	text[1024];
	client_t	*cl;

	// make sure server is running
	if ( !com_sv_running->integer ) {
		Com_Printf( "Server is not running.\n" );
		return;
	}

	if ( Cmd_Argc() < 3 ) {
		Com_Printf ("Usage: tell <client number> <text>\n");
		return;
	}

	cl = SV_GetPlayerByNum();
	if ( !cl ) {
		return;
	}

	strcpy (text, "console_tell: ");
	p = Cmd_ArgsFrom(2);

	if ( *p == '"' ) {
		p++;
		p[strlen(p)-1] = 0;
	}

	strcat(text, p);

	SV_SendServerCommand(cl, "chat \"%s\"", text);
}
Ejemplo n.º 4
0
/*
==================
SV_StartServerDemo_f

Record a server-side demo for given player/slot. The demo
will be called "YYYY-MM-DD_hh-mm-ss_playername_id.urtdemo",
in the "demos" directory under your game directory. Note
that "startserverdemo all" will start demos for all players
currently in the server. Players who join later require a
new "startserverdemo" command. If you are already recording
demos for some players, another "startserverdemo all" will
start new demos only for players not already recording. Note
that bots will never be recorded, not even if "all" is given.
The server-side demos will stop when "stopserverdemo" is issued
or when the server restarts for any reason (such as a new map
loading).
==================
*/
static void SV_StartServerDemo_f(void)
{
	client_t *client;

	Com_DPrintf("SV_StartServerDemo_f\n");

	if (!com_sv_running->integer) {
		Com_Printf("startserverdemo: Server not running\n");
		return;
	}

	if (Cmd_Argc() < 2) {
		Com_Printf("Usage: startserverdemo <player-or-all> <optional demo name>\n");
		return;
	}

	client = SV_BetterGetPlayerByHandle(Cmd_Argv(1));
	if (!Q_stricmp(Cmd_Argv(1), "all")) {
		if (client) {
			Com_Printf("startserverdemo: Player 'all' ignored, starting all demos instead\n");
		}
		SV_StartRecordAll();
	}
	else if (client) {
		if (Cmd_Argc() > 2) {
      		SV_StartRecordOne(client, Cmd_ArgsFrom(2));
    	} else {
      		SV_StartRecordOne(client, NULL);
		}
	}
	else {
		Com_Printf("startserverdemo: No player with that handle/in that slot\n");
	}
}
Ejemplo n.º 5
0
/*
==================
SV_ForceName_f

Sets a user's name
==================
*/
static void SV_ForceName_f( void ) {
	client_t	*cl;
	const char	*name;

	// make sure server is running
	if ( !com_sv_running->integer ) {
		Com_Printf( "Server is not running.\n" );
		return;
	}

	if ( Cmd_Argc() >= 2 ) {
		cl = SV_GetPlayerByNum();
		if ( !cl ) {
			return;
		}
		if ( Cmd_Argc() == 2 ) {
			Com_Printf ("forcename: %s: %s\n",Cmd_Argv(1),cl->name);
			return;
		} else {
			name = Cmd_ArgsFrom(2);
			cl->forcename = 2;
			Q_strncpyz( cl->name, name, sizeof(cl->name) );
			SV_UserinfoChanged( cl );
			VM_Call( gvm, GAME_CLIENT_USERINFO_CHANGED, cl - svs.clients );
			Com_Printf ("forcename: %s: %s\n",Cmd_Argv(1),cl->name);
			return;
		}
	}
	Com_Printf ("Usage: forcename <client number> [<name>]\n");
	return;
}
Ejemplo n.º 6
0
/*
==================
SV_StartServerDemo_f

Record a server-side demo for given player/slot. The demo
will be called "YYYY-MM-DD_hh-mm-ss_playername_id.urtdemo",
in the "demos" directory under your game directory. Note
that "startserverdemo all" will start demos for all players
currently in the server. Players who join later require a
new "startserverdemo" command. If you are already recording
demos for some players, another "startserverdemo all" will
start new demos only for players not already recording. Note
that bots will never be recorded, not even if "all" is given.
The server-side demos will stop when "stopserverdemo" is issued
or when the server restarts for any reason (such as a new map
loading).
==================
*/
static void SV_StartServerDemo_f(void) {

    client_t *client;

    Com_DPrintf("SV_StartServerDemo_f\n");

    if (!com_sv_running->integer) {
        Com_Printf("startserverdemo: Server not running\n");
        return;
    }

    if (Cmd_Argc() < 2) {
        Com_Printf("Usage: startserverdemo <client-or-all> [<optional-demo-name>]\n");
        return;
    }

    if (!Q_stricmp(Cmd_Argv(1), "all")) {

        SV_StartRecordAll();

    } else {

        client = SV_GetPlayerByHandle();
        if (!client) {
            return;
        }

        if (Cmd_Argc() > 2) {
            SV_StartRecordOne(client, Cmd_ArgsFrom(2));
        } else {
            SV_StartRecordOne(client, NULL);
        }

    }
}
Ejemplo n.º 7
0
/*
==================
SV_ConTell_f

Based on Urban Terror implementation
==================
*/
static void SV_ConTell_f(void) {
	char	*p;
	char	text[MAX_STRING_CHARS-18];// OK?
	client_t	*cl;

	// make sure server is running
	if ( !com_sv_running->integer ) {
		Com_Printf( "Server is not running.\n" );
		return;
	}

	if ( Cmd_Argc() < 3 ) {
		Com_Printf ("Usage: tell <client number> <text>\n");
		return;
	}

	cl = SV_GetPlayerByNum();
	if ( !cl ) {
		return;
	}

	strcpy (text, "^3private:^7 ");
	p = Cmd_ArgsFrom(2);

	if ( *p == '"' ) {
		p++;
		p[strlen(p)-1] = 0;
	}

	strcat(text, p);

	SV_SendServerCommand(cl, "print \"%s\n\"", SV_ConvertNewlines((char *)text));
}
Ejemplo n.º 8
0
/*
=====================
CL_ConfigstringModified
=====================
*/
void CL_ConfigstringModified( void ) {
	char        *old, *s;
	int i, index;
	char        *dup;
	gameState_t oldGs;
	int len;

	index = atoi( Cmd_Argv( 1 ) );
	if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
		Com_Error( ERR_DROP, "CL_ConfigstringModified: bad index %i", index );
	}
//	s = Cmd_Argv(2);
	// get everything after "cs <num>"
	s = Cmd_ArgsFrom( 2 );

	old = cl.gameState.stringData + cl.gameState.stringOffsets[ index ];
	if ( !strcmp( old, s ) ) {
		return;     // unchanged
	}

	// build the new gameState_t
	oldGs = cl.gameState;

	memset( &cl.gameState, 0, sizeof( cl.gameState ) );

	// leave the first 0 for uninitialized strings
	cl.gameState.dataCount = 1;

	for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
		if ( i == index ) {
			dup = s;
		} else {
			dup = oldGs.stringData + oldGs.stringOffsets[ i ];
		}
		if ( !dup[0] ) {
			continue;       // leave with the default empty string
		}

		len = strlen( dup );

		if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
			Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" );
		}

		// append it to the gameState string buffer
		cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount;
		memcpy( cl.gameState.stringData + cl.gameState.dataCount, dup, len + 1 );
		cl.gameState.dataCount += len + 1;
	}

	if ( index == CS_SYSTEMINFO ) {
		// parse serverId and other cvars
		CL_SystemInfoChanged();
	}

}
Ejemplo n.º 9
0
/*
===============
Cmd_ExecFile
===============
*/
static void Cmd_ExecFile( char *f )
{
	int i;

	COM_Compress (f);
	
	Cvar_Get( "arg_all", Cmd_ArgsFrom(2), CVAR_TEMP | CVAR_ROM | CVAR_USER_CREATED, "" );
	Cvar_Set( "arg_all", Cmd_ArgsFrom(2) );
	Cvar_Get( "arg_count", va( "%i", Cmd_Argc() - 2 ), CVAR_TEMP | CVAR_ROM | CVAR_USER_CREATED, "" );
	Cvar_Set( "arg_count", va( "%i", Cmd_Argc() - 2 ) );

	for (i = Cmd_Argc() - 2; i; i--)
	{
		Cvar_Get( va("arg_%i", i), Cmd_Argv( i + 1 ), CVAR_TEMP | CVAR_ROM | CVAR_USER_CREATED, "" );
		Cvar_Set( va("arg_%i", i), Cmd_Argv( i + 1 ) );
	}

	Cbuf_InsertText (f);
}
Ejemplo n.º 10
0
/*
===============
Cmd_Delay_f

Delays a comand
===============
*/
void Cmd_Delay_f (void)
{
        int i, delay, type;
        char *raw_delay;
        qboolean availiable_cmd = qfalse;
        
        // Check if the call is valid
        if(Cmd_Argc () < 2)
        {
                Com_Printf ("delay <delay in milliseconds> <command>\ndelay <delay in frames>f <command>\nexecutes <command> after the delay\n");
                return;
        }
        
        raw_delay = Cmd_Argv(1);
        delay = atoi(raw_delay);
        
        if(delay < 1)
        {
                Com_Printf ("delay: the delay must be a positive integer");
                return;
        }
        
        //search for an unused slot
        for(i=0; (i<MAX_DELAYED_COMMANDS); i++)
        {
                if(delayed_cmd[i].delay == CMD_DELAY_UNUSED)
                {
                        availiable_cmd = qtrue;
                        break;
                }
        }
        
        if(!availiable_cmd)
        {
                Com_Printf ("WARNING: Maximum amount of delayed commands reached.");
                return;
        }

        int lastchar = strlen( raw_delay ) - 1;
        
        if(raw_delay[ lastchar ] == 'f' )
        {
                delay += CMD_DELAY_FRAME_FIRE;
                type = CMD_DELAY_FRAME;
        }else{
                type = CMD_DELAY_MSEC;
                delay += Sys_Milliseconds();
        }
        
        delayed_cmd[i].delay = delay;
        delayed_cmd[i].type = type;
        Q_strncpyz(delayed_cmd[i].text, Cmd_ArgsFrom(2), MAX_CMD_LINE);
}
Ejemplo n.º 11
0
/*
==================
SV_Map_f

Restart the server on a different map
==================
*/
static void SV_Map_f( void )
{
	char     *cmd;
	char     *map;
	const char *layouts;
	char     mapname[ MAX_QPATH ];
	qboolean cheat;
	char     expanded[ MAX_QPATH ];
	char     layout[ MAX_CVAR_VALUE_STRING ];

	map = Cmd_Argv( 1 );

	if ( !map )
	{
		return;
	}

	// make sure the level exists before trying to change, so that
	// a typo at the server console won't end the game
	Com_sprintf( expanded, sizeof( expanded ), "maps/%s.bsp", map );

	if ( FS_ReadFile( expanded, NULL ) == -1 )
	{
		Com_Printf(_( "Can't find map %s\n"), expanded );

		return;
	}

	// layout(s) - note that ArgsFrom adds quoting which we don't want here
	// Also, if empty, don't override
	layouts = Cmd_UnquoteString( Cmd_ArgsFrom( 2 ) );
	if ( *layouts )
	{
		Cvar_Set( "g_layouts", layouts );
	}

	cheat = !Q_stricmp( Cmd_Argv( 0 ), "devmap" );

	// save the map name here cause on a map restart we reload the q3config.cfg
	// and thus nuke the arguments of the map command
	Q_strncpyz( mapname, map, sizeof( mapname ) );

	// start up the map
	SV_SpawnServer( mapname );

	// set the cheat value
	// if the level was started with "map <levelname>", then
	// cheats will not be allowed.  If started with "devmap <levelname>"
	// then cheats will be allowed
	Cvar_Set( "sv_cheats", cheat ? "1" : "0" );
}
Ejemplo n.º 12
0
/*
=======================================================================================================================================
Cvar_Set_f

Allows setting and defining of arbitrary cvars from console, even if they weren't declared in C code.
=======================================================================================================================================
*/
void Cvar_Set_f(void) {
	int c;
	char *cmd;
	cvar_t *v;

	c = Cmd_Argc();
	cmd = Cmd_Argv(0);

	if (c < 2) {
		Com_Printf("usage: %s <variable> <value>\n", cmd);
		return;
	}

	if (c == 2) {
		Cvar_Print_f();
		return;
	}

	v = Cvar_Set2(Cmd_Argv(1), Cmd_ArgsFrom(2), qfalse);

	if (!v) {
		return;
	}

	switch (cmd[3]) {
		case 'a':
			if (!(v->flags & CVAR_ARCHIVE)) {
				v->flags |= CVAR_ARCHIVE;
				cvar_modifiedFlags |= CVAR_ARCHIVE;
			}

			break;
		case 'u':
			if (!(v->flags & CVAR_USERINFO)) {
				v->flags |= CVAR_USERINFO;
				cvar_modifiedFlags |= CVAR_USERINFO;
			}

			break;
		case 's':
			if (!(v->flags & CVAR_SERVERINFO)) {
				v->flags |= CVAR_SERVERINFO;
				cvar_modifiedFlags |= CVAR_SERVERINFO;
			}

			break;
	}
}
Ejemplo n.º 13
0
static void SV_ConBig_f(void) {
	char	*p;
	char	text[1024];
	client_t	*cl;

	// make sure server is running
	if ( !com_sv_running->integer ) {
		Com_Printf( "Server is not running.\n" );
		return;
	}

	if ( Cmd_Argc() < 3 ) {
		Com_Printf ("Usage: big <clientid> <text>\n");
		return;
	}

	cl = SV_GetPlayerByNum();
	if (atoi(Cmd_Argv(1)) < 0) {
		cl = NULL;
	}


//	if (atoi(Cmd_Argv(1))) {
//	    Com_Printf ("Hi1 -1\n");

////	    Com_Printf ("Hi2 -1\n");
//	    if ( !cl ) {
//		    return;
//	    }
////	    Com_Printf ("Hi3 -1\n");
//	}


	strcpy (text, "^3");
	p = Cmd_ArgsFrom(2);

	if ( *p == '"' ) {
		p++;
		p[strlen(p)-1] = 0;
	}

	strcat(text, p);

	SV_SendServerCommand(cl, "cp \"" S_COLOR_WHITE "%s\n\"", text);
}
Ejemplo n.º 14
0
/*
============
Cmd_RunAlias_f
============
*/
void Cmd_RunAlias_f(void)
{
	cmd_alias_t	*alias;
	char 		*name = Cmd_Argv(0);
	char 		*args = Cmd_ArgsFrom(1);

	// Find existing alias
	for (alias = cmd_aliases; alias; alias=alias->next)
	{
		if (!Q_stricmp( name, alias->name ))
			break;
	}

	if (!alias)
		Com_Error(ERR_FATAL, "Alias: Alias %s doesn't exist", name);

	Cbuf_InsertText(va("%s %s", alias->exec, args));
}
Ejemplo n.º 15
0
static void Com_Setenv_f(void)
{
    int argc = Cmd_Argc();

    if (argc > 2) {
        Q_setenv(Cmd_Argv(1), Cmd_ArgsFrom(2));
    } else if (argc == 2) {
        char *env = getenv(Cmd_Argv(1));

        if (env) {
            Com_Printf("%s=%s\n", Cmd_Argv(1), env);
        } else {
            Com_Printf("%s undefined\n", Cmd_Argv(1));
        }
    } else {
        Com_Printf("Usage: %s <name> [value]\n", Cmd_Argv(0));
    }
}
Ejemplo n.º 16
0
/*
============
Cvar_Set_f

Allows setting and defining of arbitrary cvars from console, even if they
weren't declared in C code.
============
*/
void Cvar_Set_f( void ) {
	int		c, flag;
	char	*cmd;
	cvar_t *v;

	c = Cmd_Argc();
	cmd = Cmd_Argv(0);

	if ( c < 2 ) {
		Com_Printf ("usage: %s <variable> <value>\n", cmd);
		return;
	}
	if ( c == 2 ) {
		Cvar_Print_f();
		return;
	}

	v = Cvar_Set2 (Cmd_Argv(1), Cmd_ArgsFrom(2), qfalse);
	if( !v ) {
		return;
	}

	// don't make these old vars archive even if the client's old autogen told us to
	if( !Q_stricmp( Cmd_Argv(1), "r_mode" ) || !Q_stricmp( Cmd_Argv(1), "r_customheight" ) ||
	    !Q_stricmp( Cmd_Argv(1), "r_customwidth" ) || !Q_stricmp( Cmd_Argv(1), "r_custompixelAspect" ) ) 
		return;

	switch( cmd[3] ) {
		default:
			return;
		case 'u':
			flag = CVAR_USERINFO;
			break;
		case 's':
			flag = CVAR_SERVERINFO;
			break;
		case 'a':
		case '\0':
			flag = CVAR_ARCHIVE;
			break;
	}
	v->flags |= flag;
	cvar_modifiedFlags |= flag;
}
Ejemplo n.º 17
0
Archivo: script.c Proyecto: m4son/q2pro
static void Parse_Bitmap(menuFrameWork_t *menu)
{
    static const cmd_option_t o_bitmap[] = {
        { "s:", "status" },
        { "N:", "altname" },
        { NULL }
    };
    menuBitmap_t *b;
    char *status = NULL, *altname = NULL;
    int c;

    while ((c = Cmd_ParseOptions(o_bitmap)) != -1) {
        switch (c) {
        case 's':
            status = cmd_optarg;
            break;
        case 'N':
            altname = cmd_optarg;
            break;
        default:
            return;
        }
    }

    if (Cmd_Argc() - cmd_optind < 2) {
        Com_Printf("Usage: %s <name> <command>\n", Cmd_Argv(0));
        return;
    }

    if (!altname)
        altname = va("%s_sel", Cmd_Argv(cmd_optind));

    b = UI_Mallocz(sizeof(*b));
    b->generic.type = MTYPE_BITMAP;
    b->generic.activate = Activate;
    b->generic.status = UI_CopyString(status);
    b->cmd = UI_CopyString(Cmd_ArgsFrom(cmd_optind + 1));
    b->pics[0] = R_RegisterPic(Cmd_Argv(cmd_optind));
    b->pics[1] = R_RegisterPic(altname);
    R_GetPicSize(&b->generic.width, &b->generic.height, b->pics[0]);

    Menu_AddItem(menu, b);
}
Ejemplo n.º 18
0
qboolean demoCutConfigstringModified(clientActive_t *clCut) {
	char		*old, *s;
	int			i, index;
	char		*dup;
	gameState_t	oldGs;
	int			len;
	index = atoi(Cmd_Argv(1));
	if (index < 0 || index >= MAX_CONFIGSTRINGS) {
		Com_Printf("demoCutConfigstringModified: bad index %i", index);
		return qtrue;
	}
	// get everything after "cs <num>"
	s = Cmd_ArgsFrom(2);
	old = clCut->gameState.stringData + clCut->gameState.stringOffsets[index];
	if (!strcmp(old, s)) {
		return qtrue; // unchanged
	}
	// build the new gameState_t
	oldGs = clCut->gameState;
	Com_Memset(&clCut->gameState, 0, sizeof(clCut->gameState));
	// leave the first 0 for uninitialized strings
	clCut->gameState.dataCount = 1;
	for (i = 0; i < MAX_CONFIGSTRINGS; i++) {
		if (i == index) {
			dup = s;
		} else {
			dup = oldGs.stringData + oldGs.stringOffsets[i];
		}
		if (!dup[0]) {
			continue; // leave with the default empty string
		}
		len = strlen(dup);
		if (len + 1 + clCut->gameState.dataCount > MAX_GAMESTATE_CHARS) {
			Com_Printf("MAX_GAMESTATE_CHARS exceeded");
			return qfalse;
		}
		// append it to the gameState string buffer
		clCut->gameState.stringOffsets[i] = clCut->gameState.dataCount;
		Com_Memcpy(clCut->gameState.stringData + clCut->gameState.dataCount, dup, len + 1);
		clCut->gameState.dataCount += len + 1;
	}
	return qtrue;
}
Ejemplo n.º 19
0
Archivo: script.c Proyecto: m4son/q2pro
static void Parse_Spin(menuFrameWork_t *menu, menuType_t type)
{
    menuSpinControl_t *s;
    int c, i, numItems;
    char *status = NULL;

    while ((c = Cmd_ParseOptions(o_common)) != -1) {
        switch (c) {
        case 's':
            status = cmd_optarg;
            break;
        default:
            return;
        }
    }

    numItems = Cmd_Argc() - (cmd_optind + 2);
    if (numItems < 1) {
        Com_Printf("Usage: %s <name> <cvar> <desc1> [...]\n", Cmd_Argv(0));
        return;
    }

    s = UI_Mallocz(sizeof(*s));
    s->generic.type = type;
    s->generic.name = UI_CopyString(Cmd_Argv(cmd_optind));
    s->generic.status = UI_CopyString(status);
    s->cvar = Cvar_WeakGet(Cmd_Argv(cmd_optind + 1));

    cmd_optind += 2;
    if (strchr(Cmd_ArgsFrom(cmd_optind), '$')) {
        long_args_hack(s, numItems);
    } else {
        s->itemnames = UI_Mallocz(sizeof(char *) * (numItems + 1));
        for (i = 0; i < numItems; i++) {
            s->itemnames[i] = UI_CopyString(Cmd_Argv(cmd_optind + i));
        }
        s->numItems = numItems;
    }

    Menu_AddItem(menu, s);
}
Ejemplo n.º 20
0
Archivo: script.c Proyecto: m4son/q2pro
static void Parse_Bind(menuFrameWork_t *menu)
{
    static const cmd_option_t o_bind[] = {
        { "s:", "status" },
        { "S:", "altstatus" },
        { NULL }
    };
    menuKeybind_t *k;
    char *status = "Press Enter to change, Backspace to clear";
    char *altstatus = "Press the desired key, Escape to cancel";
    int c;

    while ((c = Cmd_ParseOptions(o_bind)) != -1) {
        switch (c) {
        case 's':
            status = cmd_optarg;
            break;
        case 'S':
            altstatus = cmd_optarg;
            break;
        default:
            return;
        }
    }

    if (Cmd_Argc() - cmd_optind < 2) {
        Com_Printf("Usage: %s <name> <command>\n", Cmd_Argv(0));
        return;
    }

    k = UI_Mallocz(sizeof(*k));
    k->generic.type = MTYPE_KEYBIND;
    k->generic.name = UI_CopyString(Cmd_Argv(cmd_optind));
    k->generic.uiFlags = UI_CENTER;
    k->generic.status = UI_CopyString(status);
    k->cmd = UI_CopyString(Cmd_ArgsFrom(cmd_optind + 1));
    k->altstatus = UI_CopyString(altstatus);

    Menu_AddItem(menu, k);
}
Ejemplo n.º 21
0
Archivo: script.c Proyecto: m4son/q2pro
static void Parse_Action(menuFrameWork_t *menu)
{
    static const cmd_option_t o_action[] = {
        { "a", "align" },
        { "s:", "status" },
        { NULL }
    };
    menuAction_t *a;
    int uiFlags = UI_CENTER;
    char *status = NULL;
    int c;

    while ((c = Cmd_ParseOptions(o_action)) != -1) {
        switch (c) {
        case 'a':
            uiFlags = UI_LEFT | UI_ALTCOLOR;
            break;
        case 's':
            status = cmd_optarg;
            break;
        default:
            return;
        }
    }

    if (Cmd_Argc() - cmd_optind < 2) {
        Com_Printf("Usage: %s <name> <command>\n", Cmd_Argv(0));
        return;
    }

    a = UI_Mallocz(sizeof(*a));
    a->generic.type = MTYPE_ACTION;
    a->generic.name = UI_CopyString(Cmd_Argv(cmd_optind));
    a->generic.activate = Activate;
    a->generic.uiFlags = uiFlags;
    a->generic.status = UI_CopyString(status);
    a->cmd = UI_CopyString(Cmd_ArgsFrom(cmd_optind + 1));

    Menu_AddItem(menu, a);
}
Ejemplo n.º 22
0
static void CLT3_ConfigstringModified() {
	int index = String::Atoi( Cmd_Argv( 1 ) );
	// get everything after "cs <num>"
	const char* s = Cmd_ArgsFrom( 2 );

	if ( GGameType & GAME_Quake3 ) {
		if ( index < 0 || index >= MAX_CONFIGSTRINGS_Q3 ) {
			common->Error( "configstring > MAX_CONFIGSTRINGS_Q3" );
		}

		const char* old = cl.q3_gameState.stringData + cl.q3_gameState.stringOffsets[ index ];
		if ( !String::Cmp( old, s ) ) {
			return;		// unchanged
		}

		// build the new q3gameState_t
		q3gameState_t oldGs = cl.q3_gameState;

		Com_Memset( &cl.q3_gameState, 0, sizeof ( cl.q3_gameState ) );

		// leave the first 0 for uninitialized strings
		cl.q3_gameState.dataCount = 1;

		for ( int i = 0; i < MAX_CONFIGSTRINGS_Q3; i++ ) {
			const char* dup;
			if ( i == index ) {
				dup = s;
			} else {
				dup = oldGs.stringData + oldGs.stringOffsets[ i ];
			}
			if ( !dup[ 0 ] ) {
				continue;		// leave with the default empty string
			}

			int len = String::Length( dup );

			if ( len + 1 + cl.q3_gameState.dataCount > MAX_GAMESTATE_CHARS_Q3 ) {
				common->Error( "MAX_GAMESTATE_CHARS_Q3 exceeded" );
			}

			// append it to the gameState string buffer
			cl.q3_gameState.stringOffsets[ i ] = cl.q3_gameState.dataCount;
			Com_Memcpy( cl.q3_gameState.stringData + cl.q3_gameState.dataCount, dup, len + 1 );
			cl.q3_gameState.dataCount += len + 1;
		}

		if ( index == Q3CS_SYSTEMINFO ) {
			// parse serverId and other cvars
			CLT3_SystemInfoChanged();
		}
	} else if ( GGameType & GAME_WolfSP ) {
		if ( index < 0 || index >= MAX_CONFIGSTRINGS_WS ) {
			common->Error( "configstring > MAX_CONFIGSTRINGS_WS" );
		}

		const char* old = cl.ws_gameState.stringData + cl.ws_gameState.stringOffsets[ index ];
		if ( !String::Cmp( old, s ) ) {
			return;		// unchanged
		}

		// build the new wsgameState_t
		wsgameState_t oldGs = cl.ws_gameState;

		memset( &cl.ws_gameState, 0, sizeof ( cl.ws_gameState ) );

		// leave the first 0 for uninitialized strings
		cl.ws_gameState.dataCount = 1;

		for ( int i = 0; i < MAX_CONFIGSTRINGS_WS; i++ ) {
			const char* dup;
			if ( i == index ) {
				dup = s;
			} else {
				dup = oldGs.stringData + oldGs.stringOffsets[ i ];
			}
			if ( !dup[ 0 ] ) {
				continue;		// leave with the default empty string
			}

			int len = String::Length( dup );

			if ( len + 1 + cl.ws_gameState.dataCount > MAX_GAMESTATE_CHARS_Q3 ) {
				common->Error( "MAX_GAMESTATE_CHARS_Q3 exceeded" );
			}

			// append it to the gameState string buffer
			cl.ws_gameState.stringOffsets[ i ] = cl.ws_gameState.dataCount;
			memcpy( cl.ws_gameState.stringData + cl.ws_gameState.dataCount, dup, len + 1 );
			cl.ws_gameState.dataCount += len + 1;
		}

		if ( index == Q3CS_SYSTEMINFO ) {
			// parse serverId and other cvars
			CLT3_SystemInfoChanged();
		}
	} else if ( GGameType & GAME_WolfMP ) {
		if ( index < 0 || index >= MAX_CONFIGSTRINGS_WM ) {
			common->Error( "configstring > MAX_CONFIGSTRINGS_WM" );
		}

		const char* old = cl.wm_gameState.stringData + cl.wm_gameState.stringOffsets[ index ];
		if ( !String::Cmp( old, s ) ) {
			return;		// unchanged
		}

		// build the new wmgameState_t
		wmgameState_t oldGs = cl.wm_gameState;

		memset( &cl.wm_gameState, 0, sizeof ( cl.wm_gameState ) );

		// leave the first 0 for uninitialized strings
		cl.wm_gameState.dataCount = 1;

		for ( int i = 0; i < MAX_CONFIGSTRINGS_WM; i++ ) {
			const char* dup;
			if ( i == index ) {
				dup = s;
			} else {
				dup = oldGs.stringData + oldGs.stringOffsets[ i ];
			}
			if ( !dup[ 0 ] ) {
				continue;		// leave with the default empty string
			}

			int len = String::Length( dup );

			if ( len + 1 + cl.wm_gameState.dataCount > MAX_GAMESTATE_CHARS_Q3 ) {
				common->Error( "MAX_GAMESTATE_CHARS_Q3 exceeded" );
			}

			// append it to the gameState string buffer
			cl.wm_gameState.stringOffsets[ i ] = cl.wm_gameState.dataCount;
			memcpy( cl.wm_gameState.stringData + cl.wm_gameState.dataCount, dup, len + 1 );
			cl.wm_gameState.dataCount += len + 1;
		}

		if ( index == Q3CS_SYSTEMINFO ) {
			// parse serverId and other cvars
			CLT3_SystemInfoChanged();
		}
	} else {
		if ( index < 0 || index >= MAX_CONFIGSTRINGS_ET ) {
			common->Error( "configstring > MAX_CONFIGSTRINGS_ET" );
		}

		const char* old = cl.et_gameState.stringData + cl.et_gameState.stringOffsets[ index ];
		if ( !String::Cmp( old, s ) ) {
			return;		// unchanged
		}

		// build the new etgameState_t
		etgameState_t oldGs = cl.et_gameState;

		memset( &cl.et_gameState, 0, sizeof ( cl.et_gameState ) );

		// leave the first 0 for uninitialized strings
		cl.et_gameState.dataCount = 1;

		for ( int i = 0; i < MAX_CONFIGSTRINGS_ET; i++ ) {
			const char* dup;
			if ( i == index ) {
				dup = s;
			} else {
				dup = oldGs.stringData + oldGs.stringOffsets[ i ];
			}
			if ( !dup[ 0 ] ) {
				continue;		// leave with the default empty string
			}

			int len = String::Length( dup );

			if ( len + 1 + cl.et_gameState.dataCount > MAX_GAMESTATE_CHARS_Q3 ) {
				common->Error( "MAX_GAMESTATE_CHARS_Q3 exceeded" );
			}

			// append it to the gameState string buffer
			cl.et_gameState.stringOffsets[ i ] = cl.et_gameState.dataCount;
			memcpy( cl.et_gameState.stringData + cl.et_gameState.dataCount, dup, len + 1 );
			cl.et_gameState.dataCount += len + 1;
		}

		if ( index == Q3CS_SYSTEMINFO ) {
			// parse serverId and other cvars
			CLT3_SystemInfoChanged();
		}
	}
}
Ejemplo n.º 23
0
void demoConvert( const char *oldName, const char *newBaseName, qboolean smoothen ) {
	fileHandle_t	oldHandle = 0;
	fileHandle_t	newHandle = 0;
	int				temp;
	int				oldSize;
	int				msgSequence;
	msg_t			oldMsg;
	byte			oldData[ MAX_MSGLEN ];
	int				oldTime, nextTime, fullTime;
	int				clientNum;
	demoFrame_t		*workFrame;
	int				parseEntitiesNum = 0;
	demoConvert_t	*convert;
	char			bigConfigString[BIG_INFO_STRING];
	int				bigConfigNumber;
	const char		*s;
	clSnapshot_t	*oldSnap = 0;
	clSnapshot_t	*newSnap;
	int				levelCount = 0;
	char			newName[MAX_OSPATH];

	oldSize = FS_FOpenFileRead( oldName, &oldHandle, qtrue );
	if (!oldHandle) {
		Com_Printf("Failed to open %s for conversion.", oldName);
		return;
	}
	/* Alloc some memory */
	convert = Z_Malloc( sizeof( demoConvert_t) );
	/* Initialize the first workframe's strings */
	while (oldSize > 0) {
		MSG_Init( &oldMsg, oldData, sizeof( oldData ) );
		/* Read the sequence number */
		if (FS_Read( &convert->messageNum, 4, oldHandle) != 4)
			goto conversionerror;
		convert->messageNum = LittleLong( convert->messageNum );
		oldSize -= 4;
		/* Read the message size */
		if (FS_Read( &oldMsg.cursize,4, oldHandle) != 4)
			goto conversionerror;
		oldSize -= 4;
		oldMsg.cursize = LittleLong( oldMsg.cursize );
		/* Negative size signals end of demo */
		if (oldMsg.cursize < 0)
			break;
		if ( oldMsg.cursize > oldMsg.maxsize ) 
			goto conversionerror;
		/* Read the actual message */
		if (FS_Read( oldMsg.data, oldMsg.cursize, oldHandle ) != oldMsg.cursize)
			goto conversionerror;
		oldSize -= oldMsg.cursize;
		// init the bitstream
		MSG_BeginReading( &oldMsg );
		// Skip the reliable sequence acknowledge number
		MSG_ReadLong( &oldMsg );
		//
		// parse the message
		//
		while ( 1 ) {
			byte cmd;
			if ( oldMsg.readcount > oldMsg.cursize ) {
				Com_Printf ("Demo conversion, read past end of server message.\n");
				goto conversionerror;
			}
            cmd = MSG_ReadByte( &oldMsg );
			if ( cmd == svc_EOF) {
                break;
			}
			workFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES ];
			// other commands
			switch ( cmd ) {
			default:
				Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n");
				break;			
			case svc_nop:
				break;
			case svc_serverCommand:
				temp = MSG_ReadLong( &oldMsg );
				s = MSG_ReadString( &oldMsg );
				if (temp<=msgSequence)
					break;
//				Com_Printf( " server command %s\n", s );
				msgSequence = temp;
				Cmd_TokenizeString( s );
	
				if ( !Q_stricmp( Cmd_Argv(0), "bcs0" ) ) {
					bigConfigNumber = atoi( Cmd_Argv(1) );
					Q_strncpyz( bigConfigString, Cmd_Argv(2), sizeof( bigConfigString ));
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "bcs1" ) ) {
					Q_strcat( bigConfigString, sizeof( bigConfigString ), Cmd_Argv(2));
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "bcs2" ) ) {
					Q_strcat( bigConfigString, sizeof( bigConfigString ), Cmd_Argv(2));
					demoFrameAddString( &workFrame->string, bigConfigNumber, bigConfigString );
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "cs" ) ) {
					int num = atoi( Cmd_Argv(1) );
					s = Cmd_ArgsFrom( 2 );
					demoFrameAddString( &workFrame->string, num, Cmd_ArgsFrom( 2 ) );
					break;
				}
				if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) {
					int len = strlen( s ) + 1;
					char *dst;
					if (workFrame->commandUsed + len + 1 > sizeof( workFrame->commandData)) {
						Com_Printf("Overflowed state command data.\n");
						goto conversionerror;
					}
					dst = workFrame->commandData + workFrame->commandUsed;
					*dst = clientNum;
					Com_Memcpy( dst+1, s, len );
					workFrame->commandUsed += len + 1;
				}
				break;
			case svc_gamestate:
				if (newHandle) {
					FS_FCloseFile( newHandle );
					newHandle = 0;
				}
				if (levelCount) {
					Com_sprintf( newName, sizeof( newName ), "%s.%d.mme", newBaseName, levelCount );
				} else {
					Com_sprintf( newName, sizeof( newName ), "%s.mme", newBaseName );
				}
				fullTime = -1;
				clientNum = -1;
				oldTime = -1;
				Com_Memset( convert, 0, sizeof( *convert ));
				convert->frames[0].string.used = 1;
				levelCount++;
				newHandle = FS_FOpenFileWrite( newName );
				if (!newHandle) {
					Com_Printf("Failed to open %s for target conversion target.\n", newName);
					goto conversionerror;
					return;
				} else {
					FS_Write ( demoHeader, strlen( demoHeader ), newHandle );
				}
				Com_sprintf( newName, sizeof( newName ), "%s.txt", newBaseName );
				workFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES ];
				msgSequence = MSG_ReadLong( &oldMsg );
				while( 1 ) {
					cmd = MSG_ReadByte( &oldMsg );
					if (cmd == svc_EOF)
						break;
					if ( cmd == svc_configstring) {
						int		num;
						const char *s;
						num = MSG_ReadShort( &oldMsg );
						s = MSG_ReadBigString( &oldMsg );
						demoFrameAddString( &workFrame->string, num, s );
					} else if ( cmd == svc_baseline ) {
						int num = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
						if ( num < 0 || num >= MAX_GENTITIES ) {
							Com_Printf( "Baseline number out of range: %i.\n", num );
							goto conversionerror;
						}
						MSG_ReadDeltaEntity( &oldMsg, &demoNullEntityState, &convert->entityBaselines[num], num );
					} else {
						Com_Printf( "Unknown block while converting demo gamestate.\n" );
						goto conversionerror;
					}
				}
				clientNum = MSG_ReadLong( &oldMsg );
				/* Skip the checksum feed */
				MSG_ReadLong( &oldMsg );
				break;
			case svc_snapshot:
				nextTime = MSG_ReadLong( &oldMsg );
				/* Delta number, not needed */
				newSnap = &convert->snapshots[convert->messageNum & PACKET_MASK];
				Com_Memset (newSnap, 0, sizeof(*newSnap));
				newSnap->deltaNum = MSG_ReadByte( &oldMsg );
				newSnap->messageNum = convert->messageNum;
				if (!newSnap->deltaNum) {
					newSnap->deltaNum = -1;
					newSnap->valid = qtrue;		// uncompressed frame
					oldSnap  = NULL;
				} else {
					newSnap->deltaNum = newSnap->messageNum - newSnap->deltaNum;
					oldSnap = &convert->snapshots[newSnap->deltaNum & PACKET_MASK];
					if (!oldSnap->valid) {
						Com_Printf( "Delta snapshot without base.\n" );
						goto conversionerror;
					} else if (oldSnap->messageNum != newSnap->deltaNum) {
						// The frame that the server did the delta from
						// is too old, so we can't reconstruct it properly.
						Com_Printf ("Delta frame too old.\n");
					} else if ( parseEntitiesNum - oldSnap->parseEntitiesNum > MAX_PARSE_ENTITIES-128 ) {
						Com_Printf ("Delta parseEntitiesNum too old.\n");
					} else {
						newSnap->valid = qtrue;	// valid delta parse
					}
				}

				/* Snapflags, not needed */
				newSnap->snapFlags = MSG_ReadByte( &oldMsg );
				// read areamask
				workFrame->areaUsed = MSG_ReadByte( &oldMsg );
				MSG_ReadData( &oldMsg, workFrame->areamask, workFrame->areaUsed );
				if (clientNum <0 || clientNum >= MAX_CLIENTS) {
					Com_Printf("Got snapshot with invalid client.\n");
					goto conversionerror;
				}
				MSG_ReadDeltaPlayerstate( &oldMsg, oldSnap ? &oldSnap->ps : &demoNullPlayerState, &newSnap->ps );
				/* Read the individual entities */
				newSnap->parseEntitiesNum = parseEntitiesNum;
				newSnap->numEntities = 0;
				Com_Memset( workFrame->entityData, 0, sizeof( workFrame->entityData ));

				/* The beast that is entity parsing */
				{
				int			newnum;
				entityState_t	*oldstate, *newstate;
				int			oldindex = 0;
				int			oldnum;
				newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
				while ( 1 ) {
					// read the entity index number
					if (oldSnap && oldindex < oldSnap->numEntities) {
						oldstate = &convert->parseEntities[(oldSnap->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)];
						oldnum = oldstate->number;
					} else {
						oldstate = 0;
						oldnum = 99999;
					}
					newstate = &convert->parseEntities[parseEntitiesNum];
					if ( !oldstate && (newnum == (MAX_GENTITIES-1))) {
						break;
					} else if ( oldnum < newnum ) {
						*newstate = *oldstate;
						oldindex++;
					} else if (oldnum == newnum) {
						oldindex++;
						MSG_ReadDeltaEntity( &oldMsg, oldstate, newstate, newnum );
						if ( newstate->number != MAX_GENTITIES-1)
							workFrame->entityData[ newstate->number ] = 1;
						newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
					} else if (oldnum > newnum) {
						MSG_ReadDeltaEntity( &oldMsg, &convert->entityBaselines[newnum], newstate , newnum );
						if ( newstate->number != MAX_GENTITIES-1)
							workFrame->entityData[ newstate->number ] = 1;
						newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
					}
					if (newstate->number == MAX_GENTITIES-1)
						continue;
					parseEntitiesNum++;
					parseEntitiesNum &= (MAX_PARSE_ENTITIES-1);
					newSnap->numEntities++;
				}}
				/* Stop processing this further since it's an invalid snap due to lack of delta data */
				if (!newSnap->valid)
					break;

				/* Skipped snapshots will be set invalid in the circular buffer */
				if ( newSnap->messageNum - convert->lastMessageNum >= PACKET_BACKUP ) {
					convert->lastMessageNum = newSnap->messageNum - ( PACKET_BACKUP - 1 );
				}
				for ( ; convert->lastMessageNum < newSnap->messageNum ; convert->lastMessageNum++ ) {
					convert->snapshots[convert->lastMessageNum & PACKET_MASK].valid = qfalse;
				}
				convert->lastMessageNum = newSnap->messageNum + 1;

				/* compress the frame into the new format */
				if (nextTime > oldTime) {
					demoFrame_t *cleanFrame;
					int writeIndex;
					for (temp = 0;temp<newSnap->numEntities;temp++) {
						int p = (newSnap->parseEntitiesNum+temp) & (MAX_PARSE_ENTITIES-1);
						entityState_t *newState = &convert->parseEntities[p];
						workFrame->entities[newState->number] = *newState;
					}
					workFrame->clientData[clientNum] = 1;
					workFrame->clients[clientNum] = newSnap->ps;
					workFrame->serverTime = nextTime;

					/* Which frame from the cache to save */
					writeIndex = convert->frameIndex - (DEMOCONVERTFRAMES/2);
					if (writeIndex >= 0) {
						const demoFrame_t *newFrame;
						msg_t writeMsg;
						// init the message
						MSG_Init( &writeMsg, demoBuffer, sizeof (demoBuffer));
						MSG_Clear( &writeMsg );
						MSG_Bitstream( &writeMsg );
						newFrame = &convert->frames[ writeIndex  % DEMOCONVERTFRAMES];
						if ( smoothen )
							demoFrameInterpolate( convert->frames, DEMOCONVERTFRAMES, writeIndex );
						if ( nextTime > fullTime || writeIndex <= 0 ) {
							/* Plan the next time for a full write */
							fullTime = nextTime + 2000;
							demoFramePack( &writeMsg, newFrame, 0 );
						} else {
							const demoFrame_t *oldFrame = &convert->frames[ ( writeIndex -1 ) % DEMOCONVERTFRAMES];
							demoFramePack( &writeMsg, newFrame, oldFrame );
						}
						/* Write away the new data in the msg queue */
						temp = LittleLong( writeMsg.cursize );
						FS_Write (&temp, 4, newHandle );
						FS_Write ( writeMsg.data , writeMsg.cursize, newHandle );
					}

					/* Clean up the upcoming frame for all new changes */
					convert->frameIndex++;
					cleanFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES];
					cleanFrame->serverTime = 0;
					for (temp = 0;temp<MAX_GENTITIES;temp++)
						cleanFrame->entities[temp].number = MAX_GENTITIES-1;
					Com_Memset( cleanFrame->clientData, 0, sizeof ( cleanFrame->clientData ));
					Com_Memcpy( cleanFrame->string.data, workFrame->string.data, workFrame->string.used );
					Com_Memcpy( cleanFrame->string.offsets, workFrame->string.offsets, sizeof( workFrame->string.offsets ));
					cleanFrame->string.used = workFrame->string.used;
					cleanFrame->commandUsed = 0;
					/* keep track of this last frame's time */
					oldTime = nextTime;
				}
				break;
			case svc_download:
				// read block number
				temp = MSG_ReadShort ( &oldMsg );
				if (!temp)	//0 block, read file size
					MSG_ReadLong( &oldMsg );
				// read block size
				temp = MSG_ReadShort ( &oldMsg );
				// read the data block
				for ( ;temp>0;temp--)
					MSG_ReadByte( &oldMsg );
				break;
			}
		}
	}
conversionerror:
	FS_FCloseFile( oldHandle );
	FS_FCloseFile( newHandle );
	Z_Free( convert );
	return;
}
Ejemplo n.º 24
0
/*
============
Cmd_Alias_f
============
*/
void Cmd_Alias_f(void)
{
	cmd_alias_t	*alias;
	const char	*name;

	// Get args
	if (Cmd_Argc() < 2)
	{
		Com_Printf("alias <name> : show an alias\n");
		Com_Printf("alias <name> <exec> : create an alias\n");
		return;
	}
	name = Cmd_Argv(1);

	// Find existing alias
	for (alias = cmd_aliases; alias; alias = alias->next)
	{
		if (!Q_stricmp(name, alias->name))
			break;
	}

	// Modify/create an alias
	if (Cmd_Argc() > 2)
	{
		cmd_function_t	*cmd;

		// Crude protection from infinite loops
		if (!Q_stricmp(Cmd_Argv(2), name))
		{
			Com_Printf("Can't make an alias to itself\n");
			return;
		}

		// Don't allow overriding builtin commands
 		cmd = Cmd_FindCommand( name );
		if (cmd && cmd->function != Cmd_RunAlias_f)
		{
			Com_Printf("Can't override a builtin function with an alias\n");
			return;
		}

		// Create/update an alias
		if (!alias)
		{
			alias = (cmd_alias_t*)S_Malloc(sizeof(cmd_alias_t));
			alias->name = CopyString(name);
			alias->exec = CopyString(Cmd_ArgsFrom(2));
			alias->next = cmd_aliases;
			cmd_aliases = alias;
			Cmd_AddCommand(name, Cmd_RunAlias_f, NULL);
		}
		else
		{
			// Reallocate the exec string
			Z_Free(alias->exec);
			alias->exec = CopyString(Cmd_ArgsFrom(2));
			Cmd_AddCommand(name, Cmd_RunAlias_f, NULL);
		}
	}
	
	// Show the alias
	if (!alias)
		Com_Printf("Alias %s does not exist\n", name);
	else if (Cmd_Argc() == 2)
		Com_Printf("%s ==> %s\n", alias->name, alias->exec);
	
	// update autogen.cfg
	cvar_modifiedFlags |= CVAR_ARCHIVE;
}
Ejemplo n.º 25
0
/*
============
Cmd_ArgsFromBuffer

The interpreted versions use this because
they can't have pointers returned to them
============
*/
void	Cmd_ArgsFromBuffer( int arg, char *buffer, int bufferLength ) {
	Q_strncpyz( buffer, Cmd_ArgsFrom( arg ), bufferLength );
}
Ejemplo n.º 26
0
/*
====================
Prompt_CompleteCommand
====================
*/
void Prompt_CompleteCommand(commandPrompt_t *prompt, qboolean backslash)
{
    inputField_t *inputLine = &prompt->inputLine;
    char *text, *partial, *s;
    int i, argc, currentArg, argnum;
    size_t size, len, pos;
    char *first, *last;
    genctx_t ctx;
    char *matches[MAX_MATCHES], *sortedMatches[MAX_MATCHES];
    int numCommands, numCvars, numAliases;

    text = inputLine->text;
    size = inputLine->maxChars + 1;
    pos = inputLine->cursorPos;

    // prepend backslash if missing
    if (backslash) {
        if (inputLine->text[0] != '\\' && inputLine->text[0] != '/') {
            memmove(inputLine->text + 1, inputLine->text, size - 1);
            inputLine->text[0] = '\\';
        }
        text++;
        size--;
        pos--;
    }

    // parse the input line into tokens
    Cmd_TokenizeString(text, qfalse);

    argc = Cmd_Argc();

    // determine absolute argument number to be completed
    currentArg = Cmd_FindArgForOffset(pos);
    if (currentArg == argc - 1 && Cmd_WhiteSpaceTail()) {
        // start completing new argument if command line has trailing whitespace
        currentArg++;
    }

    // determine relative argument number to be completed
    argnum = 0;
    for (i = 0; i < currentArg; i++) {
        s = Cmd_Argv(i);
        argnum++;
        if (*s == ';') {
            // semicolon starts a new command
            argnum = 0;
        }
    }

    // get the partial argument string to be completed
    partial = Cmd_Argv(currentArg);
    if (*partial == ';') {
        // semicolon starts a new command
        currentArg++;
        partial = Cmd_Argv(currentArg);
        argnum = 0;
    }

    // generate matches
    memset(&ctx, 0, sizeof(ctx));
    ctx.partial = partial;
    ctx.length = strlen(partial);
    ctx.argnum = currentArg;
    ctx.matches = matches;
    ctx.size = MAX_MATCHES;

    if (argnum) {
        // complete a command/cvar argument
        Com_Generic_c(&ctx, argnum);
        numCommands = numCvars = numAliases = 0;
    } else {
        // complete a command/cvar/alias name
        Cmd_Command_g(&ctx);
        numCommands = ctx.count;

        Cvar_Variable_g(&ctx);
        numCvars = ctx.count - numCommands;

        Cmd_Alias_g(&ctx);
        numAliases = ctx.count - numCvars - numCommands;
    }

    if (!ctx.count) {
        pos = strlen(inputLine->text);
        prompt->tooMany = qfalse;
        goto finish2; // nothing found
    }

    pos = Cmd_ArgOffset(currentArg);
    text += pos;
    size -= pos;

    // append whitespace since Cmd_TokenizeString eats it
    if (currentArg == argc && Cmd_WhiteSpaceTail()) {
        *text++ = ' ';
        pos++;
        size--;
    }

    if (ctx.count == 1) {
        // we have finished completion!
        s = Cmd_RawArgsFrom(currentArg + 1);
        if (needs_quotes(matches[0])) {
            pos += Q_concat(text, size, "\"", matches[0], "\" ", s, NULL);
        } else {
            pos += Q_concat(text, size, matches[0], " ", s, NULL);
        }
        pos++;
        prompt->tooMany = qfalse;
        goto finish1;
    }

    if (ctx.count > com_completion_treshold->integer && !prompt->tooMany) {
        prompt->printf("Press TAB again to display all %d possibilities.\n", ctx.count);
        pos = strlen(inputLine->text);
        prompt->tooMany = qtrue;
        goto finish1;
    }

    prompt->tooMany = qfalse;

    // sort matches alphabethically
    for (i = 0; i < ctx.count; i++) {
        sortedMatches[i] = matches[i];
    }
    qsort(sortedMatches, ctx.count, sizeof(sortedMatches[0]),
          ctx.ignorecase ? SortStricmp : SortStrcmp);

    // copy matching part
    first = sortedMatches[0];
    last = sortedMatches[ctx.count - 1];
    len = 0;
    do {
        if (*first != *last) {
            if (!ctx.ignorecase || Q_tolower(*first) != Q_tolower(*last)) {
                break;
            }
        }
        text[len++] = *first;
        if (len == size - 1) {
            break;
        }

        first++;
        last++;
    } while (*first);

    text[len] = 0;
    pos += len;
    size -= len;

    // copy trailing arguments
    if (currentArg + 1 < argc) {
        s = Cmd_RawArgsFrom(currentArg + 1);
        pos += Q_concat(text + len, size, " ", s, NULL);
    }

    pos++;

    prompt->printf("]\\%s\n", Cmd_ArgsFrom(0));
    if (argnum) {
        goto multi;
    }

    switch (com_completion_mode->integer) {
    case 0:
        // print in solid list
        for (i = 0; i < ctx.count; i++) {
            prompt->printf("%s\n", sortedMatches[i]);
        }
        break;
    case 1:
multi:
        // print in multiple columns
        Prompt_ShowMatches(prompt, sortedMatches, 0, ctx.count);
        break;
    case 2:
    default:
        // resort matches by type and print in multiple columns
        Prompt_ShowIndividualMatches(prompt, matches, numCommands, numAliases, numCvars);
        break;
    }

finish1:
    // free matches
    for (i = 0; i < ctx.count; i++) {
        Z_Free(matches[i]);
    }

finish2:
    // move cursor
    if (pos >= inputLine->maxChars) {
        pos = inputLine->maxChars - 1;
    }
    inputLine->cursorPos = pos;
}
Ejemplo n.º 27
0
/*
============
Cmd_ArgsBuffer

The interpreted versions use this because
they can't have pointers returned to them
============
*/
void	Cmd_ArgsBuffer( char *buffer, int bufferLength ) {
	Q_strncpyz( buffer, Cmd_ArgsFrom( 1 ), bufferLength );
}
Ejemplo n.º 28
0
/*
============
Cmd_Args

Returns a single string containing argv(1) to argv(argc()-1)
============
*/
char	*Cmd_Args( void ) {
	return Cmd_ArgsFrom( 1 );
}
Ejemplo n.º 29
0
/*
=====================
CL_ConfigstringModified
=====================
*/
void CL_ConfigstringModified( void ) {
	char		*old, *s;
	int			i, index;
	char		*dup;
	gameState_t	oldGs;
	int			len;

	index = atoi( Cmd_Argv(1) );
	if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
		Com_Error( ERR_DROP, "CL_ConfigstringModified: bad index %i", index );
	}
	// get everything after "cs <num>"
	s = Cmd_ArgsFrom(2);

	old = cl.gameState.stringData + cl.gameState.stringOffsets[ index ];
	if ( !strcmp( old, s ) ) {
		return;		// unchanged
	}

	// build the new gameState_t
	oldGs = cl.gameState;

	Com_Memset( &cl.gameState, 0, sizeof( cl.gameState ) );

	// leave the first 0 for uninitialized strings
	cl.gameState.dataCount = 1;
		
	for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
		if ( i == index ) {
			dup = s;
		} else {
			dup = oldGs.stringData + oldGs.stringOffsets[ i ];
		}
		if ( !dup[0] ) {
			continue;		// leave with the default empty string
		}

		len = strlen( dup );

		if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
			Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" );
		}

		// append it to the gameState string buffer
		cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount;
		Com_Memcpy( cl.gameState.stringData + cl.gameState.dataCount, dup, len + 1 );
		cl.gameState.dataCount += len + 1;
	}

	if (cl_autolodscale && cl_autolodscale->integer)
	{
		if (index >= CS_PLAYERS &&
			index < CS_G2BONES)
		{ //this means that a client was updated in some way. Go through and count the clients.
			int clientCount = 0;
			i = CS_PLAYERS;

			while (i < CS_G2BONES)
			{
				s = cl.gameState.stringData + cl.gameState.stringOffsets[ i ];

				if (s && s[0])
				{
					clientCount++;
				}

				i++;
			}

			gCLTotalClientNum = clientCount;

#ifdef _DEBUG
			Com_DPrintf("%i clients\n", gCLTotalClientNum);
#endif

			CL_DoAutoLODScale();
		}
	}

	if ( index == CS_SYSTEMINFO ) {
		// parse serverId and other cvars
		CL_SystemInfoChanged();
	}

}
Ejemplo n.º 30
0
const char* Cmd_Args()
{
	return Cmd_ArgsFrom(1);
}