]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cvar.c
Split the global cmd interpreter into 4 separate ones for specific uses (client conso...
[xonotic/darkplaces.git] / cvar.c
diff --git a/cvar.c b/cvar.c
index b88aafd0374d761bb47dd97697fb40f44f729feb..e36b8f908ac5dbb7a8583da61155bb0ad22eec75 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -251,7 +251,7 @@ const char **Cvar_CompleteBuildList (const char *partial)
        return buf;
 }
 
-// written by LordHavoc
+// written by LadyHavoc
 void Cvar_CompleteCvarPrint (const char *partial)
 {
        cvar_t *cvar;
@@ -262,6 +262,20 @@ void Cvar_CompleteCvarPrint (const char *partial)
                        Con_Printf ("^3%s^7 is \"%s\" [\"%s\"] %s\n", cvar->name, cvar->string, cvar->defstring, cvar->description);
 }
 
+// check if a cvar is held by some progs
+static qboolean Cvar_IsAutoCvar(cvar_t *var)
+{
+       int i;
+       prvm_prog_t *prog;
+       for (i = 0;i < PRVM_PROG_MAX;i++)
+       {
+               prog = &prvm_prog_list[i];
+               if (prog->loaded && var->globaldefindex[i] >= 0)
+                       return true;
+       }
+       return false;
+}
+
 // we assume that prog is already set to the target progs
 static void Cvar_UpdateAutoCvar(cvar_t *var)
 {
@@ -273,7 +287,7 @@ static void Cvar_UpdateAutoCvar(cvar_t *var)
        for (i = 0;i < PRVM_PROG_MAX;i++)
        {
                prog = &prvm_prog_list[i];
-               if (prog->loaded && var->globaldefindex_progid[i] == prog->id)
+               if (prog->loaded && var->globaldefindex[i] >= 0)
                {
                        // MUST BE SYNCED WITH prvm_edict.c PRVM_LoadProgs
                        switch(prog->globaldefs[var->globaldefindex[i]].type & ~DEF_SAVEGLOBAL)
@@ -328,11 +342,11 @@ static void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
        char vabuf[1024];
 
        changed = strcmp(var->string, value) != 0;
-       // LordHavoc: don't reallocate when there is no change
+       // LadyHavoc: don't reallocate when there is no change
        if (!changed)
                return;
 
-       // LordHavoc: don't reallocate when the buffer is the same size
+       // LadyHavoc: don't reallocate when the buffer is the same size
        valuelen = strlen(value);
        if (!var->string || strlen(var->string) != valuelen)
        {
@@ -381,6 +395,8 @@ static void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
                }
                else if (!strcmp(var->name, "_cl_rate"))
                        CL_SetInfo("rate", va(vabuf, sizeof(vabuf), "%i", var->integer), true, false, false, false);
+               else if (!strcmp(var->name, "_cl_rate_burstsize"))
+                       CL_SetInfo("rate_burstsize", va(vabuf, sizeof(vabuf), "%i", var->integer), true, false, false, false);
                else if (!strcmp(var->name, "_cl_playerskin"))
                        CL_SetInfo("playerskin", var->string, true, false, false, false);
                else if (!strcmp(var->name, "_cl_playermodel"))
@@ -395,8 +411,10 @@ static void Cvar_SetQuick_Internal (cvar_t *var, const char *value)
                        if(var->integer <= 0)
                                Cvar_Set("rcon_password", "");
                }
+#ifdef CONFIG_MENU
                else if (!strcmp(var->name, "net_slist_favorites"))
                        NetConn_UpdateFavorites();
+#endif
        }
 
        Cvar_UpdateAutoCvar(var);
@@ -468,6 +486,7 @@ void Cvar_RegisterVariable (cvar_t *variable)
        cvar_t *current, *next, *cvar;
        char *oldstr;
        size_t alloclen;
+       int i;
 
        if (developer_extra.integer)
                Con_DPrintf("Cvar_RegisterVariable({\"%s\", \"%s\", %i});\n", variable->name, variable->string, variable->flags);
@@ -490,6 +509,9 @@ void Cvar_RegisterVariable (cvar_t *variable)
                        variable->defstring = cvar->defstring;
                        variable->value = atof (variable->string);
                        variable->integer = (int) variable->value;
+                       // Preserve autocvar status.
+                       memcpy(variable->globaldefindex, cvar->globaldefindex, sizeof(variable->globaldefindex));
+                       memcpy(variable->globaldefindex_stringno, cvar->globaldefindex_stringno, sizeof(variable->globaldefindex_stringno));
                        // replace cvar with this one...
                        variable->next = cvar->next;
                        if (cvar_vars == cvar)
@@ -516,7 +538,7 @@ void Cvar_RegisterVariable (cvar_t *variable)
        }
 
 // check for overlap with a command
-       if (Cmd_Exists (variable->name))
+       if (Cmd_Exists(&cmd_client, variable->name) || Cmd_Exists(&cmd_server, variable->name))
        {
                Con_Printf("Cvar_RegisterVariable: %s is a command\n", variable->name);
                return;
@@ -532,6 +554,10 @@ void Cvar_RegisterVariable (cvar_t *variable)
        variable->value = atof (variable->string);
        variable->integer = (int) variable->value;
 
+       // Mark it as not an autocvar.
+       for (i = 0;i < PRVM_PROG_MAX;i++)
+               variable->globaldefindex[i] = -1;
+
 // link the variable in
 // alphanumerical order
        for( current = NULL, next = cvar_vars ; next && strcmp( next->name, variable->name ) < 0 ; current = next, next = next->next )
@@ -560,6 +586,7 @@ cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *ne
 {
        int hashindex;
        cvar_t *current, *next, *cvar;
+       int i;
 
        if (developer_extra.integer)
                Con_DPrintf("Cvar_Get(\"%s\", \"%s\", %i);\n", name, value, flags);
@@ -591,7 +618,7 @@ cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *ne
        }
 
 // check for overlap with a command
-       if (Cmd_Exists (name))
+       if (Cmd_Exists(&cmd_client, name) || Cmd_Exists(&cmd_server, name))
        {
                Con_Printf("Cvar_Get: %s is a command\n", name);
                return NULL;
@@ -613,6 +640,10 @@ cvar_t *Cvar_Get (const char *name, const char *value, int flags, const char *ne
        else
                cvar->description = cvar_dummy_description; // actually checked by VM_cvar_type
 
+       // Mark it as not an autocvar.
+       for (i = 0;i < PRVM_PROG_MAX;i++)
+               cvar->globaldefindex[i] = -1;
+
 // link the variable in
 // alphanumerical order
        for( current = NULL, next = cvar_vars ; next && strcmp( next->name, cvar->name ) < 0 ; current = next, next = next->next )
@@ -639,17 +670,17 @@ Cvar_Command
 Handles variable inspection and changing from the console
 ============
 */
-qboolean       Cvar_Command (void)
+qboolean       Cvar_Command (cmd_state_t *cmd)
 {
        cvar_t                  *v;
 
 // check variables
-       v = Cvar_FindVar (Cmd_Argv(0));
+       v = Cvar_FindVar (Cmd_Argv(cmd, 0));
        if (!v)
                return false;
 
 // perform a variable print or set
-       if (Cmd_Argc() == 1)
+       if (Cmd_Argc(cmd) == 1)
        {
                Con_Printf("\"%s\" is \"%s\" [\"%s\"]\n", v->name, ((v->flags & CVAR_PRIVATE) ? "********"/*hunter2*/ : v->string), v->defstring);
                return true;
@@ -663,7 +694,7 @@ qboolean    Cvar_Command (void)
                Con_Printf("%s is read-only\n", v->name);
                return true;
        }
-       Cvar_Set (v->name, Cmd_Argv(1));
+       Cvar_Set (v->name, Cmd_Argv(cmd, 1));
        if (developer_extra.integer)
                Con_DPrint("\n");
        return true;
@@ -679,7 +710,7 @@ void Cvar_UnlockDefaults (void)
 }
 
 
-void Cvar_LockDefaults_f (void)
+void Cvar_LockDefaults_f(cmd_state_t *cmd)
 {
        cvar_t *var;
        // lock in the default values of all cvars
@@ -747,6 +778,18 @@ void Cvar_RestoreInitState(void)
                        if (!(c->flags & CVAR_ALLOCATED))
                        {
                                Con_DPrintf("Cvar_RestoreInitState: Unable to destroy cvar \"%s\", it was registered after init!\n", c->name);
+                               // In this case, at least reset it to the default.
+                               if((c->flags & CVAR_NORESETTODEFAULTS) == 0)
+                                       Cvar_SetQuick(c, c->defstring);
+                               cp = &c->next;
+                               continue;
+                       }
+                       if (Cvar_IsAutoCvar(c))
+                       {
+                               Con_DPrintf("Cvar_RestoreInitState: Unable to destroy cvar \"%s\", it is an autocvar used by running progs!\n", c->name);
+                               // In this case, at least reset it to the default.
+                               if((c->flags & CVAR_NORESETTODEFAULTS) == 0)
+                                       Cvar_SetQuick(c, c->defstring);
                                cp = &c->next;
                                continue;
                        }
@@ -779,7 +822,7 @@ void Cvar_RestoreInitState(void)
        }
 }
 
-void Cvar_ResetToDefaults_All_f (void)
+void Cvar_ResetToDefaults_All_f(cmd_state_t *cmd)
 {
        cvar_t *var;
        // restore the default values of all cvars
@@ -789,7 +832,7 @@ void Cvar_ResetToDefaults_All_f (void)
 }
 
 
-void Cvar_ResetToDefaults_NoSaveOnly_f (void)
+void Cvar_ResetToDefaults_NoSaveOnly_f(cmd_state_t *cmd)
 {
        cvar_t *var;
        // restore the default values of all cvars
@@ -799,7 +842,7 @@ void Cvar_ResetToDefaults_NoSaveOnly_f (void)
 }
 
 
-void Cvar_ResetToDefaults_SaveOnly_f (void)
+void Cvar_ResetToDefaults_SaveOnly_f(cmd_state_t *cmd)
 {
        cvar_t *var;
        // restore the default values of all cvars
@@ -840,7 +883,7 @@ void Cvar_WriteVariables (qfile_t *f)
 Cvar_List
 =========
 */
-void Cvar_List_f (void)
+void Cvar_List_f(cmd_state_t *cmd)
 {
        cvar_t *cvar;
        const char *partial;
@@ -848,9 +891,9 @@ void Cvar_List_f (void)
        int count;
        qboolean ispattern;
 
-       if (Cmd_Argc() > 1)
+       if (Cmd_Argc(cmd) > 1)
        {
-               partial = Cmd_Argv (1);
+               partial = Cmd_Argv(cmd, 1);
                len = strlen(partial);
                ispattern = (strchr(partial, '*') || strchr(partial, '?'));
        }
@@ -883,19 +926,19 @@ void Cvar_List_f (void)
 }
 // 2000-01-09 CvarList command by Maddes
 
-void Cvar_Set_f (void)
+void Cvar_Set_f(cmd_state_t *cmd)
 {
        cvar_t *cvar;
 
        // make sure it's the right number of parameters
-       if (Cmd_Argc() < 3)
+       if (Cmd_Argc(cmd) < 3)
        {
                Con_Printf("Set: wrong number of parameters, usage: set <variablename> <value> [<description>]\n");
                return;
        }
 
        // check if it's read-only
-       cvar = Cvar_FindVar(Cmd_Argv(1));
+       cvar = Cvar_FindVar(Cmd_Argv(cmd, 1));
        if (cvar && cvar->flags & CVAR_READONLY)
        {
                Con_Printf("Set: %s is read-only\n", cvar->name);
@@ -906,22 +949,22 @@ void Cvar_Set_f (void)
                Con_DPrint("Set: ");
 
        // all looks ok, create/modify the cvar
-       Cvar_Get(Cmd_Argv(1), Cmd_Argv(2), 0, Cmd_Argc() > 3 ? Cmd_Argv(3) : NULL);
+       Cvar_Get(Cmd_Argv(cmd, 1), Cmd_Argv(cmd, 2), 0, Cmd_Argc(cmd) > 3 ? Cmd_Argv(cmd, 3) : NULL);
 }
 
-void Cvar_SetA_f (void)
+void Cvar_SetA_f(cmd_state_t *cmd)
 {
        cvar_t *cvar;
 
        // make sure it's the right number of parameters
-       if (Cmd_Argc() < 3)
+       if (Cmd_Argc(cmd) < 3)
        {
                Con_Printf("SetA: wrong number of parameters, usage: seta <variablename> <value> [<description>]\n");
                return;
        }
 
        // check if it's read-only
-       cvar = Cvar_FindVar(Cmd_Argv(1));
+       cvar = Cvar_FindVar(Cmd_Argv(cmd, 1));
        if (cvar && cvar->flags & CVAR_READONLY)
        {
                Con_Printf("SetA: %s is read-only\n", cvar->name);
@@ -932,25 +975,25 @@ void Cvar_SetA_f (void)
                Con_DPrint("SetA: ");
 
        // all looks ok, create/modify the cvar
-       Cvar_Get(Cmd_Argv(1), Cmd_Argv(2), CVAR_SAVE, Cmd_Argc() > 3 ? Cmd_Argv(3) : NULL);
+       Cvar_Get(Cmd_Argv(cmd, 1), Cmd_Argv(cmd, 2), CVAR_SAVE, Cmd_Argc(cmd) > 3 ? Cmd_Argv(cmd, 3) : NULL);
 }
 
-void Cvar_Del_f (void)
+void Cvar_Del_f(cmd_state_t *cmd)
 {
        int i;
        cvar_t *cvar, *parent, **link, *prev;
 
-       if(Cmd_Argc() < 2)
+       if(Cmd_Argc(cmd) < 2)
        {
                Con_Printf("Del: wrong number of parameters, useage: unset <variablename1> [<variablename2> ...]\n");
                return;
        }
-       for(i = 1; i < Cmd_Argc(); ++i)
+       for(i = 1; i < Cmd_Argc(cmd); ++i)
        {
-               cvar = Cvar_FindVarLink(Cmd_Argv(i), &parent, &link, &prev);
+               cvar = Cvar_FindVarLink(Cmd_Argv(cmd, i), &parent, &link, &prev);
                if(!cvar)
                {
-                       Con_Printf("Del: %s is not defined\n", Cmd_Argv(i));
+                       Con_Printf("Del: %s is not defined\n", Cmd_Argv(cmd, i));
                        continue;
                }
                if(cvar->flags & CVAR_READONLY)
@@ -990,19 +1033,19 @@ void Cvar_Del_f (void)
 }
 
 #ifdef FILLALLCVARSWITHRUBBISH
-void Cvar_FillAll_f()
+void Cvar_FillAll_f(cmd_state_t *cmd)
 {
        char *buf, *p, *q;
        int n, i;
        cvar_t *var;
        qboolean verify;
-       if(Cmd_Argc() != 2)
+       if(Cmd_Argc(cmd) != 2)
        {
-               Con_Printf("Usage: %s length to plant rubbish\n", Cmd_Argv(0));
-               Con_Printf("Usage: %s -length to verify that the rubbish is still there\n", Cmd_Argv(0));
+               Con_Printf("Usage: %s length to plant rubbish\n", Cmd_Argv(cmd, 0));
+               Con_Printf("Usage: %s -length to verify that the rubbish is still there\n", Cmd_Argv(cmd, 0));
                return;
        }
-       n = atoi(Cmd_Argv(1));
+       n = atoi(Cmd_Argv(cmd, 1));
        verify = (n < 0);
        if(verify)
                n = -n;