]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cmd.c
don't print "empty file" spam here
[xonotic/darkplaces.git] / cmd.c
diff --git a/cmd.c b/cmd.c
index e7fe4a81e3624aee3dbcdb97aa44b7c19ce82e75..73f55456e1cb393df9737e3c7084b0d2496dcad8 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -63,6 +63,73 @@ static void Cmd_Wait_f (void)
        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
@@ -176,6 +243,41 @@ void Cbuf_InsertText (const char *text)
        }
 }
 
+/*
+============
+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
@@ -194,6 +296,7 @@ void Cbuf_Execute (void)
        // 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
@@ -609,7 +712,7 @@ static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias
                                                *is_multiple = true;
 
                                        // kill pre-argument whitespace
-                                       for (;*p && *p <= ' ';p++)
+                                       for (;*p && ISWHITESPACE(*p);p++)
                                                ;
 
                                        return p;
@@ -723,7 +826,8 @@ static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t *
                // 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)
@@ -971,6 +1075,7 @@ void Cmd_Init_Commands (void)
        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
@@ -1038,7 +1143,7 @@ static void Cmd_TokenizeString (const char *text)
        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:
@@ -1364,11 +1469,13 @@ FIXME: lookupnoadd the token to speed search?
 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);
 
@@ -1403,8 +1510,9 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
                                }
                                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)
                                {
@@ -1417,11 +1525,13 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
                        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;
        }
 
@@ -1436,6 +1546,12 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
                }
        }
 
+       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));