mirror of
https://github.com/blendogames/quadrilateralcowboy.git
synced 2024-11-10 06:41:36 +00:00
867 lines
21 KiB
C++
867 lines
21 KiB
C++
|
/*
|
||
|
===========================================================================
|
||
|
|
||
|
Doom 3 GPL Source Code
|
||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||
|
|
||
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||
|
|
||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||
|
|
||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||
|
|
||
|
===========================================================================
|
||
|
*/
|
||
|
|
||
|
#include "../idlib/precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
|
||
|
#ifdef STEAM
|
||
|
#include "steam_api.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
idCmdSystemLocal
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
typedef struct commandDef_s {
|
||
|
struct commandDef_s * next;
|
||
|
char * name;
|
||
|
cmdFunction_t function;
|
||
|
argCompletion_t argCompletion;
|
||
|
int flags;
|
||
|
char * description;
|
||
|
} commandDef_t;
|
||
|
|
||
|
|
||
|
class idCmdSystemLocal : public idCmdSystem {
|
||
|
public:
|
||
|
virtual void Init( void );
|
||
|
virtual void Shutdown( void );
|
||
|
|
||
|
virtual void AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion = NULL );
|
||
|
virtual void RemoveCommand( const char *cmdName );
|
||
|
virtual void RemoveFlaggedCommands( int flags );
|
||
|
|
||
|
virtual void CommandCompletion( void(*callback)( const char *s ) );
|
||
|
virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) );
|
||
|
|
||
|
virtual void BufferCommandText( cmdExecution_t exec, const char *text );
|
||
|
virtual void ExecuteCommandBuffer( void );
|
||
|
|
||
|
virtual void ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... );
|
||
|
virtual void ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type );
|
||
|
|
||
|
virtual void BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args );
|
||
|
|
||
|
virtual void SetupReloadEngine( const idCmdArgs &args );
|
||
|
virtual bool PostReloadEngine( void );
|
||
|
|
||
|
void SetWait( int numFrames ) { wait = numFrames; }
|
||
|
commandDef_t * GetCommands( void ) const { return commands; }
|
||
|
|
||
|
private:
|
||
|
static const int MAX_CMD_BUFFER = 0x10000;
|
||
|
|
||
|
commandDef_t * commands;
|
||
|
|
||
|
int wait;
|
||
|
int textLength;
|
||
|
byte textBuf[MAX_CMD_BUFFER];
|
||
|
|
||
|
idStr completionString;
|
||
|
idStrList completionParms;
|
||
|
|
||
|
// piggybacks on the text buffer, avoids tokenize again and screwing it up
|
||
|
idList<idCmdArgs> tokenizedCmds;
|
||
|
|
||
|
// a command stored to be executed after a reloadEngine and all associated commands have been processed
|
||
|
idCmdArgs postReload;
|
||
|
|
||
|
private:
|
||
|
void ExecuteTokenizedString( const idCmdArgs &args );
|
||
|
void ExecuteCommandText( const char *text );
|
||
|
void InsertCommandText( const char *text );
|
||
|
void AppendCommandText( const char *text );
|
||
|
|
||
|
#ifdef STEAM
|
||
|
static void SteamCloudList(const idCmdArgs &args);
|
||
|
#endif
|
||
|
|
||
|
static void Find_f( const idCmdArgs &args );
|
||
|
static void ListByFlags( const idCmdArgs &args, cmdFlags_t flags );
|
||
|
static void List_f( const idCmdArgs &args );
|
||
|
static void SystemList_f( const idCmdArgs &args );
|
||
|
static void RendererList_f( const idCmdArgs &args );
|
||
|
static void SoundList_f( const idCmdArgs &args );
|
||
|
static void GameList_f( const idCmdArgs &args );
|
||
|
static void ToolList_f( const idCmdArgs &args );
|
||
|
static void Exec_f( const idCmdArgs &args );
|
||
|
static void Vstr_f( const idCmdArgs &args );
|
||
|
static void Echo_f( const idCmdArgs &args );
|
||
|
static void Parse_f( const idCmdArgs &args );
|
||
|
static void Wait_f( const idCmdArgs &args );
|
||
|
static void PrintMemInfo_f( const idCmdArgs &args );
|
||
|
};
|
||
|
|
||
|
idCmdSystemLocal cmdSystemLocal;
|
||
|
idCmdSystem * cmdSystem = &cmdSystemLocal;
|
||
|
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ListByFlags
|
||
|
============
|
||
|
*/
|
||
|
// NOTE: the const wonkyness is required to make msvc happy
|
||
|
template<>
|
||
|
ID_INLINE int idListSortCompare( const commandDef_t * const *a, const commandDef_t * const *b ) {
|
||
|
return idStr::Icmp( (*a)->name, (*b)->name );
|
||
|
}
|
||
|
|
||
|
void idCmdSystemLocal::ListByFlags( const idCmdArgs &args, cmdFlags_t flags ) {
|
||
|
int i;
|
||
|
idStr match;
|
||
|
const commandDef_t *cmd;
|
||
|
idList<const commandDef_t *> cmdList;
|
||
|
|
||
|
if ( args.Argc() > 1 ) {
|
||
|
match = args.Args( 1, -1 );
|
||
|
match.Replace( " ", "" );
|
||
|
} else {
|
||
|
match = "";
|
||
|
}
|
||
|
|
||
|
for ( cmd = cmdSystemLocal.GetCommands(); cmd; cmd = cmd->next ) {
|
||
|
if ( !( cmd->flags & flags ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
if ( match.Length() && idStr( cmd->name ).Filter( match, false ) == 0 ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
cmdList.Append( cmd );
|
||
|
}
|
||
|
|
||
|
cmdList.Sort();
|
||
|
|
||
|
for ( i = 0; i < cmdList.Num(); i++ ) {
|
||
|
cmd = cmdList[i];
|
||
|
|
||
|
common->Printf( " %-21s %s\n", cmd->name, cmd->description );
|
||
|
}
|
||
|
|
||
|
common->Printf( "%i commands\n", cmdList.Num() );
|
||
|
}
|
||
|
|
||
|
#ifdef STEAM
|
||
|
void idCmdSystemLocal::SteamCloudList(const idCmdArgs &args)
|
||
|
{
|
||
|
if (!game->GetSteamInitialized())
|
||
|
return;
|
||
|
|
||
|
int filecount = SteamRemoteStorage()->GetFileCount();
|
||
|
|
||
|
common->Printf("STEAM: cloud file count: %d\n", filecount);
|
||
|
|
||
|
if (filecount <= 0)
|
||
|
return;
|
||
|
|
||
|
int i;
|
||
|
for (i = 0; i < filecount; i++)
|
||
|
{
|
||
|
int32 *filesize = 0;
|
||
|
common->Printf("STEAM: cloud file #%d: %s\n", i, SteamRemoteStorage()->GetFileNameAndSize(i, filesize));
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void idCmdSystemLocal::Find_f( const idCmdArgs &args )
|
||
|
{
|
||
|
if ( args.Argc() != 2 )
|
||
|
{
|
||
|
common->Printf( "usage: find <substring>\n" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
idStr substring = args.Argv(1);
|
||
|
|
||
|
int i;
|
||
|
const commandDef_t *cmd;
|
||
|
idStrList candidates;
|
||
|
|
||
|
for ( cmd = cmdSystemLocal.GetCommands(); cmd; cmd = cmd->next )
|
||
|
{
|
||
|
if ( substring.Length() && idStr::FindText( cmd->name, substring, false ) <= -1 )
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
candidates.AddUnique(cmd->name);
|
||
|
}
|
||
|
|
||
|
for ( i = 0; i < cvarSystem->GetCvarTotal(); i++ )
|
||
|
{
|
||
|
if (idStr::FindText( cvarSystem->GetCvarByIndex(i), substring, false ) <= -1)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
candidates.AddUnique(cvarSystem->GetCvarByIndex(i));
|
||
|
}
|
||
|
|
||
|
candidates.Sort();
|
||
|
|
||
|
common->Printf( " \n" );
|
||
|
|
||
|
for ( i = 0; i < candidates.Num(); i++ )
|
||
|
{
|
||
|
common->Printf( " %s\n", candidates[i].c_str() );
|
||
|
}
|
||
|
|
||
|
common->Printf( "Found %i commands with substring: %s\n", candidates.Num(), substring.c_str() );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::List_f
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::List_f( const idCmdArgs &args ) {
|
||
|
idCmdSystemLocal::ListByFlags( args, CMD_FL_ALL );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::SystemList_f
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::SystemList_f( const idCmdArgs &args ) {
|
||
|
idCmdSystemLocal::ListByFlags( args, CMD_FL_SYSTEM );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::RendererList_f
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::RendererList_f( const idCmdArgs &args ) {
|
||
|
idCmdSystemLocal::ListByFlags( args, CMD_FL_RENDERER );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::SoundList_f
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::SoundList_f( const idCmdArgs &args ) {
|
||
|
idCmdSystemLocal::ListByFlags( args, CMD_FL_SOUND );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::GameList_f
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::GameList_f( const idCmdArgs &args ) {
|
||
|
idCmdSystemLocal::ListByFlags( args, CMD_FL_GAME );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ToolList_f
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ToolList_f( const idCmdArgs &args ) {
|
||
|
idCmdSystemLocal::ListByFlags( args, CMD_FL_TOOL );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============
|
||
|
idCmdSystemLocal::Exec_f
|
||
|
===============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Exec_f( const idCmdArgs &args ) {
|
||
|
char * f;
|
||
|
int len;
|
||
|
idStr filename;
|
||
|
|
||
|
if ( args.Argc () != 2 ) {
|
||
|
common->Printf( "exec <filename> : execute a script file\n" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
filename = args.Argv(1);
|
||
|
filename.DefaultFileExtension( ".cfg" );
|
||
|
len = fileSystem->ReadFile( filename, reinterpret_cast<void **>(&f), NULL );
|
||
|
if ( !f ) {
|
||
|
common->Printf( "couldn't exec %s\n", args.Argv(1) );
|
||
|
return;
|
||
|
}
|
||
|
common->Printf( "execing %s\n", args.Argv(1) );
|
||
|
|
||
|
cmdSystemLocal.BufferCommandText( CMD_EXEC_INSERT, f );
|
||
|
|
||
|
fileSystem->FreeFile( f );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============
|
||
|
idCmdSystemLocal::Vstr_f
|
||
|
|
||
|
Inserts the current value of a cvar as command text
|
||
|
===============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Vstr_f( const idCmdArgs &args ) {
|
||
|
const char *v;
|
||
|
|
||
|
if ( args.Argc () != 2 ) {
|
||
|
common->Printf( "vstr <variablename> : execute a variable command\n" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
v = cvarSystem->GetCVarString( args.Argv( 1 ) );
|
||
|
|
||
|
cmdSystemLocal.BufferCommandText( CMD_EXEC_APPEND, va( "%s\n", v ) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============
|
||
|
idCmdSystemLocal::Echo_f
|
||
|
|
||
|
Just prints the rest of the line to the console
|
||
|
===============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Echo_f( const idCmdArgs &args ) {
|
||
|
int i;
|
||
|
|
||
|
for ( i = 1; i < args.Argc(); i++ ) {
|
||
|
common->Printf( "%s ", args.Argv( i ) );
|
||
|
}
|
||
|
common->Printf( "\n" );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::Wait_f
|
||
|
|
||
|
Causes execution of the remainder of the command buffer to be delayed until next frame.
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Wait_f( const idCmdArgs &args ) {
|
||
|
if ( args.Argc() == 2 ) {
|
||
|
cmdSystemLocal.SetWait( atoi( args.Argv( 1 ) ) );
|
||
|
} else {
|
||
|
cmdSystemLocal.SetWait( 1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::Parse_f
|
||
|
|
||
|
This just prints out how the rest of the line was parsed, as a debugging tool.
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Parse_f( const idCmdArgs &args ) {
|
||
|
int i;
|
||
|
|
||
|
for ( i = 0; i < args.Argc(); i++ ) {
|
||
|
common->Printf( "%i: %s\n", i, args.Argv(i) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::Init
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Init( void ) {
|
||
|
|
||
|
#ifdef STEAM
|
||
|
AddCommand( "steam_cloudlist", SteamCloudList, CMD_FL_SYSTEM, "lists steam cloud files" );
|
||
|
#endif
|
||
|
AddCommand( "find", Find_f, CMD_FL_SYSTEM, "finds console commands via substring" );
|
||
|
AddCommand( "listCmds", List_f, CMD_FL_SYSTEM, "lists commands" );
|
||
|
AddCommand( "listSystemCmds", SystemList_f, CMD_FL_SYSTEM, "lists system commands" );
|
||
|
AddCommand( "listRendererCmds", RendererList_f, CMD_FL_SYSTEM, "lists renderer commands" );
|
||
|
AddCommand( "listSoundCmds", SoundList_f, CMD_FL_SYSTEM, "lists sound commands" );
|
||
|
AddCommand( "listGameCmds", GameList_f, CMD_FL_SYSTEM, "lists game commands" );
|
||
|
AddCommand( "listToolCmds", ToolList_f, CMD_FL_SYSTEM, "lists tool commands" );
|
||
|
AddCommand( "exec", Exec_f, CMD_FL_SYSTEM, "executes a config file", ArgCompletion_ConfigName );
|
||
|
AddCommand( "vstr", Vstr_f, CMD_FL_SYSTEM, "inserts the current value of a cvar as command text" );
|
||
|
AddCommand( "echo", Echo_f, CMD_FL_SYSTEM, "prints text" );
|
||
|
AddCommand( "parse", Parse_f, CMD_FL_SYSTEM, "prints tokenized string" );
|
||
|
AddCommand( "wait", Wait_f, CMD_FL_SYSTEM, "delays remaining buffered commands one or more frames" );
|
||
|
|
||
|
completionString = "*";
|
||
|
|
||
|
textLength = 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::Shutdown
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::Shutdown( void ) {
|
||
|
commandDef_t *cmd;
|
||
|
|
||
|
for ( cmd = commands; cmd; cmd = commands ) {
|
||
|
commands = commands->next;
|
||
|
Mem_Free( cmd->name );
|
||
|
Mem_Free( cmd->description );
|
||
|
delete cmd;
|
||
|
}
|
||
|
|
||
|
completionString.Clear();
|
||
|
completionParms.Clear();
|
||
|
tokenizedCmds.Clear();
|
||
|
postReload.Clear();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::AddCommand
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::AddCommand( const char *cmdName, cmdFunction_t function, int flags, const char *description, argCompletion_t argCompletion ) {
|
||
|
commandDef_t *cmd;
|
||
|
|
||
|
// fail if the command already exists
|
||
|
for ( cmd = commands; cmd; cmd = cmd->next ) {
|
||
|
if ( idStr::Cmp( cmdName, cmd->name ) == 0 ) {
|
||
|
if ( function != cmd->function ) {
|
||
|
common->Printf( "idCmdSystemLocal::AddCommand: %s already defined\n", cmdName );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cmd = new commandDef_t;
|
||
|
cmd->name = Mem_CopyString( cmdName );
|
||
|
cmd->function = function;
|
||
|
cmd->argCompletion = argCompletion;
|
||
|
cmd->flags = flags;
|
||
|
cmd->description = Mem_CopyString( description );
|
||
|
cmd->next = commands;
|
||
|
commands = cmd;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::RemoveCommand
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::RemoveCommand( const char *cmdName ) {
|
||
|
commandDef_t *cmd, **last;
|
||
|
|
||
|
for ( last = &commands, cmd = *last; cmd; cmd = *last ) {
|
||
|
if ( idStr::Cmp( cmdName, cmd->name ) == 0 ) {
|
||
|
*last = cmd->next;
|
||
|
Mem_Free( cmd->name );
|
||
|
Mem_Free( cmd->description );
|
||
|
delete cmd;
|
||
|
return;
|
||
|
}
|
||
|
last = &cmd->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::RemoveFlaggedCommands
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::RemoveFlaggedCommands( int flags ) {
|
||
|
commandDef_t *cmd, **last;
|
||
|
|
||
|
for ( last = &commands, cmd = *last; cmd; cmd = *last ) {
|
||
|
if ( cmd->flags & flags ) {
|
||
|
*last = cmd->next;
|
||
|
Mem_Free( cmd->name );
|
||
|
Mem_Free( cmd->description );
|
||
|
delete cmd;
|
||
|
continue;
|
||
|
}
|
||
|
last = &cmd->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::CommandCompletion
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::CommandCompletion( void(*callback)( const char *s ) ) {
|
||
|
commandDef_t *cmd;
|
||
|
|
||
|
for ( cmd = commands; cmd; cmd = cmd->next ) {
|
||
|
callback( cmd->name );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ArgCompletion
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) {
|
||
|
commandDef_t *cmd;
|
||
|
idCmdArgs args;
|
||
|
|
||
|
args.TokenizeString( cmdString, false );
|
||
|
|
||
|
for ( cmd = commands; cmd; cmd = cmd->next ) {
|
||
|
if ( !cmd->argCompletion ) {
|
||
|
continue;
|
||
|
}
|
||
|
if ( idStr::Icmp( args.Argv( 0 ), cmd->name ) == 0 ) {
|
||
|
cmd->argCompletion( args, callback );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ExecuteTokenizedString
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ExecuteTokenizedString( const idCmdArgs &args ) {
|
||
|
commandDef_t *cmd, **prev;
|
||
|
|
||
|
// execute the command line
|
||
|
if ( !args.Argc() ) {
|
||
|
return; // no tokens
|
||
|
}
|
||
|
|
||
|
// check registered command functions
|
||
|
for ( prev = &commands; *prev; prev = &cmd->next ) {
|
||
|
cmd = *prev;
|
||
|
if ( idStr::Icmp( args.Argv( 0 ), cmd->name ) == 0 ) {
|
||
|
// rearrange the links so that the command will be
|
||
|
// near the head of the list next time it is used
|
||
|
*prev = cmd->next;
|
||
|
cmd->next = commands;
|
||
|
commands = cmd;
|
||
|
|
||
|
if ( ( cmd->flags & (CMD_FL_CHEAT|CMD_FL_TOOL) ) && session && session->IsMultiplayer() && !cvarSystem->GetCVarBool( "net_allowCheats" ) ) {
|
||
|
common->Printf( "Command '%s' not valid in multiplayer mode.\n", cmd->name );
|
||
|
return;
|
||
|
}
|
||
|
// perform the action
|
||
|
if ( !cmd->function ) {
|
||
|
break;
|
||
|
} else {
|
||
|
cmd->function( args );
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// check cvars
|
||
|
if ( cvarSystem->Command( args ) ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
common->Printf( "Unknown command '%s'\n", args.Argv( 0 ) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ExecuteCommandText
|
||
|
|
||
|
Tokenizes, then executes.
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ExecuteCommandText( const char *text ) {
|
||
|
ExecuteTokenizedString( idCmdArgs( text, false ) );
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::InsertCommandText
|
||
|
|
||
|
Adds command text immediately after the current command
|
||
|
Adds a \n to the text
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::InsertCommandText( const char *text ) {
|
||
|
int len;
|
||
|
int i;
|
||
|
|
||
|
len = strlen( text ) + 1;
|
||
|
if ( len + textLength > (int)sizeof( textBuf ) ) {
|
||
|
common->Printf( "idCmdSystemLocal::InsertText: buffer overflow\n" );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// move the existing command text
|
||
|
for ( i = textLength - 1; i >= 0; i-- ) {
|
||
|
textBuf[ i + len ] = textBuf[ i ];
|
||
|
}
|
||
|
|
||
|
// copy the new text in
|
||
|
memcpy( textBuf, text, len - 1 );
|
||
|
|
||
|
// add a \n
|
||
|
textBuf[ len - 1 ] = '\n';
|
||
|
|
||
|
textLength += len;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::AppendCommandText
|
||
|
|
||
|
Adds command text at the end of the buffer, does NOT add a final \n
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::AppendCommandText( const char *text ) {
|
||
|
int l;
|
||
|
|
||
|
l = strlen( text );
|
||
|
|
||
|
if ( textLength + l >= (int)sizeof( textBuf ) ) {
|
||
|
common->Printf( "idCmdSystemLocal::AppendText: buffer overflow\n" );
|
||
|
return;
|
||
|
}
|
||
|
memcpy( textBuf + textLength, text, l );
|
||
|
textLength += l;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::BufferCommandText
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::BufferCommandText( cmdExecution_t exec, const char *text ) {
|
||
|
switch( exec ) {
|
||
|
case CMD_EXEC_NOW: {
|
||
|
ExecuteCommandText( text );
|
||
|
break;
|
||
|
}
|
||
|
case CMD_EXEC_INSERT: {
|
||
|
InsertCommandText( text );
|
||
|
break;
|
||
|
}
|
||
|
case CMD_EXEC_APPEND: {
|
||
|
AppendCommandText( text );
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
common->FatalError( "idCmdSystemLocal::BufferCommandText: bad exec type" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::BufferCommandArgs
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::BufferCommandArgs( cmdExecution_t exec, const idCmdArgs &args ) {
|
||
|
switch ( exec ) {
|
||
|
case CMD_EXEC_NOW: {
|
||
|
ExecuteTokenizedString( args );
|
||
|
break;
|
||
|
}
|
||
|
case CMD_EXEC_APPEND: {
|
||
|
AppendCommandText( "_execTokenized\n" );
|
||
|
tokenizedCmds.Append( args );
|
||
|
break;
|
||
|
}
|
||
|
default: {
|
||
|
common->FatalError( "idCmdSystemLocal::BufferCommandArgs: bad exec type" );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ExecuteCommandBuffer
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ExecuteCommandBuffer( void ) {
|
||
|
int i;
|
||
|
char * text;
|
||
|
int quotes;
|
||
|
idCmdArgs args;
|
||
|
|
||
|
while( textLength ) {
|
||
|
|
||
|
if ( wait ) {
|
||
|
// skip out while text still remains in buffer, leaving it for next frame
|
||
|
wait--;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// find a \n or ; line break
|
||
|
text = (char *)textBuf;
|
||
|
|
||
|
quotes = 0;
|
||
|
for ( i = 0; i < textLength; i++ ) {
|
||
|
if ( text[i] == '"' ) {
|
||
|
quotes++;
|
||
|
}
|
||
|
if ( !( quotes & 1 ) && text[i] == ';' ) {
|
||
|
break; // don't break if inside a quoted string
|
||
|
}
|
||
|
if ( text[i] == '\n' || text[i] == '\r' ) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
text[i] = 0;
|
||
|
|
||
|
if ( !idStr::Cmp( text, "_execTokenized" ) ) {
|
||
|
args = tokenizedCmds[ 0 ];
|
||
|
tokenizedCmds.RemoveIndex( 0 );
|
||
|
} else {
|
||
|
args.TokenizeString( text, false );
|
||
|
}
|
||
|
|
||
|
// delete the text from the command buffer and move remaining commands down
|
||
|
// this is necessary because commands (exec) can insert data at the
|
||
|
// beginning of the text buffer
|
||
|
|
||
|
if ( i == textLength ) {
|
||
|
textLength = 0;
|
||
|
} else {
|
||
|
i++;
|
||
|
textLength -= i;
|
||
|
memmove( text, text+i, textLength );
|
||
|
}
|
||
|
|
||
|
// execute the command line that we have already tokenized
|
||
|
ExecuteTokenizedString( args );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ArgCompletion_FolderExtension
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) {
|
||
|
int i;
|
||
|
idStr string;
|
||
|
const char *extension;
|
||
|
va_list argPtr;
|
||
|
|
||
|
string = args.Argv( 0 );
|
||
|
string += " ";
|
||
|
string += args.Argv( 1 );
|
||
|
|
||
|
if ( string.Icmp( completionString ) != 0 ) {
|
||
|
idStr parm, path;
|
||
|
idFileList *names;
|
||
|
|
||
|
completionString = string;
|
||
|
completionParms.Clear();
|
||
|
|
||
|
parm = args.Argv( 1 );
|
||
|
parm.ExtractFilePath( path );
|
||
|
if ( stripFolder || path.Length() == 0 ) {
|
||
|
path = folder + path;
|
||
|
}
|
||
|
path.StripTrailing( '/' );
|
||
|
|
||
|
// list folders
|
||
|
names = fileSystem->ListFiles( path, "/", true, true );
|
||
|
for ( i = 0; i < names->GetNumFiles(); i++ ) {
|
||
|
idStr name = names->GetFile( i );
|
||
|
if ( stripFolder ) {
|
||
|
name.Strip( folder );
|
||
|
} else {
|
||
|
name.Strip( "/" );
|
||
|
}
|
||
|
name = args.Argv( 0 ) + ( " " + name ) + "/";
|
||
|
completionParms.Append( name );
|
||
|
}
|
||
|
fileSystem->FreeFileList( names );
|
||
|
|
||
|
// list files
|
||
|
va_start( argPtr, stripFolder );
|
||
|
for ( extension = va_arg( argPtr, const char * ); extension; extension = va_arg( argPtr, const char * ) ) {
|
||
|
names = fileSystem->ListFiles( path, extension, true, true );
|
||
|
for ( i = 0; i < names->GetNumFiles(); i++ ) {
|
||
|
idStr name = names->GetFile( i );
|
||
|
if ( stripFolder ) {
|
||
|
name.Strip( folder );
|
||
|
} else {
|
||
|
name.Strip( "/" );
|
||
|
}
|
||
|
name = args.Argv( 0 ) + ( " " + name );
|
||
|
completionParms.Append( name );
|
||
|
}
|
||
|
fileSystem->FreeFileList( names );
|
||
|
}
|
||
|
va_end( argPtr );
|
||
|
}
|
||
|
for ( i = 0; i < completionParms.Num(); i++ ) {
|
||
|
callback( completionParms[i] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::ArgCompletion_DeclName
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::ArgCompletion_DeclName( const idCmdArgs &args, void(*callback)( const char *s ), int type ) {
|
||
|
int i, num;
|
||
|
|
||
|
if ( declManager == NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
num = declManager->GetNumDecls( (declType_t)type );
|
||
|
for ( i = 0; i < num; i++ ) {
|
||
|
callback( idStr( args.Argv( 0 ) ) + " " + declManager->DeclByIndex( (declType_t)type, i , false )->GetName() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::SetupReloadEngine
|
||
|
============
|
||
|
*/
|
||
|
void idCmdSystemLocal::SetupReloadEngine( const idCmdArgs &args ) {
|
||
|
BufferCommandText( CMD_EXEC_APPEND, "reloadEngine\n" );
|
||
|
postReload = args;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
idCmdSystemLocal::PostReloadEngine
|
||
|
============
|
||
|
*/
|
||
|
bool idCmdSystemLocal::PostReloadEngine( void ) {
|
||
|
if ( !postReload.Argc() ) {
|
||
|
return false;
|
||
|
}
|
||
|
BufferCommandArgs( CMD_EXEC_APPEND, postReload );
|
||
|
postReload.Clear();
|
||
|
return true;
|
||
|
}
|