cmd_wait = true;
}
+typedef struct cmddeferred_s
+{
+ struct cmddeferred_s *next;
+ char *value;
+ double time;
+} cmddeferred_t;
+
+static cmddeferred_t *cmd_deferred_list = NULL;
+
+/*
+============
+Cmd_Defer_f
+
+Cause a command to be executed after a delay.
+============
+*/
+static void Cmd_Defer_f (void)
+{
+ if(Cmd_Argc() == 1)
+ {
+ double time = Sys_DoubleTime();
+ cmddeferred_t *next = cmd_deferred_list;
+ if(!next)
+ Con_Printf("No commands are pending.\n");
+ while(next)
+ {
+ Con_Printf("-> In %9.2f: %s\n", next->time-time, next->value);
+ next = next->next;
+ }
+ } else if(Cmd_Argc() == 2 && !strcasecmp("clear", Cmd_Argv(1)))
+ {
+ while(cmd_deferred_list)
+ {
+ cmddeferred_t *cmd = cmd_deferred_list;
+ cmd_deferred_list = cmd->next;
+ Mem_Free(cmd->value);
+ Mem_Free(cmd);
+ }
+ } else if(Cmd_Argc() == 3)
+ {
+ const char *value = Cmd_Argv(2);
+ cmddeferred_t *defcmd = (cmddeferred_t*)Mem_Alloc(tempmempool, sizeof(*defcmd));
+ size_t len = strlen(value);
+
+ defcmd->time = Sys_DoubleTime() + atof(Cmd_Argv(1));
+ defcmd->value = (char*)Mem_Alloc(tempmempool, len+1);
+ memcpy(defcmd->value, value, len+1);
+ defcmd->next = NULL;
+
+ if(cmd_deferred_list)
+ {
+ cmddeferred_t *next = cmd_deferred_list;
+ while(next->next)
+ next = next->next;
+ next->next = defcmd;
+ } else
+ cmd_deferred_list = defcmd;
+ /* Stupid me... this changes the order... so commands with the same delay go blub :S
+ defcmd->next = cmd_deferred_list;
+ cmd_deferred_list = defcmd;*/
+ } else {
+ Con_Printf("usage: defer <seconds> <command>\n"
+ " defer clear\n");
+ return;
+ }
+}
+
+/*
+============
+Cmd_Centerprint_f
+
+Print something to the center of the screen using SCR_Centerprint
+============
+*/
+static void Cmd_Centerprint_f (void)
+{
+ char msg[MAX_INPUTLINE];
+ unsigned int i, c, p;
+ c = Cmd_Argc();
+ if(c >= 2)
+ {
+ strlcpy(msg, Cmd_Argv(1), sizeof(msg));
+ for(i = 2; i < c; ++i)
+ {
+ strlcat(msg, " ", sizeof(msg));
+ strlcat(msg, Cmd_Argv(i), sizeof(msg));
+ }
+ c = strlen(msg);
+ for(p = 0, i = 0; i < c; ++i)
+ {
+ if(msg[i] == '\\')
+ {
+ if(msg[i+1] == 'n')
+ msg[p++] = '\n';
+ else if(msg[i+1] == '\\')
+ msg[p++] = '\\';
+ else {
+ msg[p++] = '\\';
+ msg[p++] = msg[i+1];
+ }
+ ++i;
+ } else {
+ msg[p++] = msg[i];
+ }
+ }
+ msg[p] = '\0';
+ SCR_CenterPrint(msg);
+ }
+}
+
/*
=============================================================================
}
}
+/*
+============
+Cbuf_Execute_Deferred --blub
+============
+*/
+void Cbuf_Execute_Deferred (void)
+{
+ cmddeferred_t *cmd, *prev;
+ double time = Sys_DoubleTime();
+ prev = NULL;
+ cmd = cmd_deferred_list;
+ while(cmd)
+ {
+ if(cmd->time <= time)
+ {
+ Cbuf_AddText(cmd->value);
+ Cbuf_AddText(";\n");
+ Mem_Free(cmd->value);
+
+ if(prev) {
+ prev->next = cmd->next;
+ Mem_Free(cmd);
+ cmd = prev->next;
+ } else {
+ cmd_deferred_list = cmd->next;
+ Mem_Free(cmd);
+ cmd = cmd_deferred_list;
+ }
+ continue;
+ }
+ prev = cmd;
+ cmd = cmd->next;
+ }
+}
+
/*
============
Cbuf_Execute
// LordHavoc: making sure the tokenizebuffer doesn't get filled up by repeated crashes
cmd_tokenizebufferpos = 0;
+ Cbuf_Execute_Deferred();
while (cmd_text.cursize)
{
// find a \n or ; line break
{
if (text[i] == '"')
quotes ^= 1;
- if (text[i] == '\\' && (text[i+1] == '"' || text[i+1] == '\\'))
+ // make sure i doesn't get > cursize which causes a negative
+ // size in memmove, which is fatal --blub
+ if (i < (cmd_text.cursize-1) && (text[i] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
i++;
if ( !quotes && text[i] == ';')
break; // don't break if inside a quoted string
break;
}
- /* should never happen
+ // better than CRASHING on overlong input lines that may SOMEHOW enter the buffer
if(i >= MAX_INPUTLINE)
- i = MAX_INPUTLINE - 1;
- */
-
- memcpy (line, text, i);
- line[i] = 0;
+ {
+ Con_Printf("Warning: console input buffer had an overlong line. Ignored.\n");
+ line[0] = 0;
+ }
+ else
+ {
+ memcpy (line, text, i);
+ line[i] = 0;
+ }
// delete the text from the command buffer and move remaining commands down
// this is necessary because commands (exec, alias) can insert data at the
*is_multiple = true;
// kill pre-argument whitespace
- for (;*p && *p <= ' ';p++)
+ for (;*p && ISWHITESPACE(*p);p++)
;
return p;
// Exception: $* and $n- don't use the quoted form by default
varstr = Cmd_GetDirectCvarValue(varname, alias, &is_multiple);
if(is_multiple)
- varfunc = "asis";
+ if(!varfunc)
+ varfunc = "asis";
}
if(!varstr)
Cmd_AddCommand ("cvar_resettodefaults_nosaveonly", Cvar_ResetToDefaults_NoSaveOnly_f, "sets all non-saved cvars to their locked default values (variables that will not be saved to config.cfg)");
Cmd_AddCommand ("cvar_resettodefaults_saveonly", Cvar_ResetToDefaults_SaveOnly_f, "sets all saved cvars to their locked default values (variables that will be saved to config.cfg)");
+ Cmd_AddCommand ("cprint", Cmd_Centerprint_f, "print something at the screen center");
+ Cmd_AddCommand ("defer", Cmd_Defer_f, "execute a command in the future");
+
// DRESK - 5/14/06
// Support Doom3-style Toggle Command
Cmd_AddCommand( "toggle", Cmd_Toggle_f, "toggles a console variable's values (use for more info)");
while (1)
{
// skip whitespace up to a /n
- while (*text && *text <= ' ' && *text != '\r' && *text != '\n')
+ while (*text && ISWHITESPACE(*text) && *text != '\r' && *text != '\n')
text++;
// line endings:
void Cmd_ExecuteString (const char *text, cmd_source_t src)
{
int oldpos;
+ int found;
cmd_function_t *cmd;
cmdalias_t *a;
oldpos = cmd_tokenizebufferpos;
cmd_source = src;
+ found = false;
Cmd_TokenizeString (text);
}
else
Con_Printf("Command \"%s\" can not be executed\n", Cmd_Argv(0));
- cmd_tokenizebufferpos = oldpos;
- return;
+ found = true;
+ goto command_found;
+ break;
case src_client:
if (cmd->clientfunction)
{
break;
}
}
+command_found:
// if it's a client command and no command was found, say so.
if (cmd_source == src_client)
{
Con_Printf("player \"%s\" tried to %s\n", host_client->name, text);
+ cmd_tokenizebufferpos = oldpos;
return;
}
}
}
+ if(found) // if the command was hooked and found, all is good
+ {
+ cmd_tokenizebufferpos = oldpos;
+ return;
+ }
+
// check cvars
if (!Cvar_Command () && host_framecount > 0)
Con_Printf("Unknown command \"%s\"\n", Cmd_Argv(0));