|
|
1.1.1.3 ! root 1: /* ! 2: Copyright (C) 1997-2001 Id Software, Inc. ! 3: ! 4: This program is free software; you can redistribute it and/or ! 5: modify it under the terms of the GNU General Public License ! 6: as published by the Free Software Foundation; either version 2 ! 7: of the License, or (at your option) any later version. ! 8: ! 9: This program is distributed in the hope that it will be useful, ! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! 12: ! 13: See the GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with this program; if not, write to the Free Software ! 17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! 18: ! 19: */ 1.1 root 20: // cvar.c -- dynamic variable tracking 1.1.1.2 root 21: 1.1 root 22: #include "qcommon.h" 1.1.1.2 root 23: 1.1 root 24: cvar_t *cvar_vars; 1.1.1.2 root 25: 1.1 root 26: /* 27: ============ 28: Cvar_InfoValidate 29: ============ 30: */ 31: static qboolean Cvar_InfoValidate (char *s) 32: { 33: if (strstr (s, "\\")) 34: return false; 35: if (strstr (s, "\"")) 36: return false; 37: if (strstr (s, ";")) 38: return false; 39: return true; 40: } 41: 42: /* 43: ============ 44: Cvar_FindVar 45: ============ 46: */ 47: static cvar_t *Cvar_FindVar (char *var_name) 48: { 49: cvar_t *var; 50: 51: for (var=cvar_vars ; var ; var=var->next) 52: if (!strcmp (var_name, var->name)) 53: return var; 1.1.1.2 root 54: 1.1 root 55: return NULL; 56: } 1.1.1.2 root 57: 1.1 root 58: /* 59: ============ 60: Cvar_VariableValue 61: ============ 62: */ 63: float Cvar_VariableValue (char *var_name) 64: { 65: cvar_t *var; 66: 67: var = Cvar_FindVar (var_name); 68: if (!var) 69: return 0; 70: return atof (var->string); 71: } 1.1.1.2 root 72: 73: 1.1 root 74: /* 75: ============ 76: Cvar_VariableString 77: ============ 78: */ 79: char *Cvar_VariableString (char *var_name) 80: { 81: cvar_t *var; 82: 83: var = Cvar_FindVar (var_name); 84: if (!var) 85: return ""; 86: return var->string; 87: } 1.1.1.2 root 88: 89: 1.1 root 90: /* 91: ============ 92: Cvar_CompleteVariable 93: ============ 94: */ 95: char *Cvar_CompleteVariable (char *partial) 96: { 97: cvar_t *cvar; 98: int len; 99: 100: len = strlen(partial); 101: 102: if (!len) 103: return NULL; 104: 105: // check exact match 106: for (cvar=cvar_vars ; cvar ; cvar=cvar->next) 107: if (!strcmp (partial,cvar->name)) 108: return cvar->name; 1.1.1.2 root 109: 1.1 root 110: // check partial match 111: for (cvar=cvar_vars ; cvar ; cvar=cvar->next) 112: if (!strncmp (partial,cvar->name, len)) 113: return cvar->name; 1.1.1.2 root 114: 1.1 root 115: return NULL; 116: } 1.1.1.2 root 117: 118: 1.1 root 119: /* 120: ============ 121: Cvar_Get 1.1.1.2 root 122: 1.1 root 123: If the variable already exists, the value will not be set 124: The flags will be or'ed in if the variable exists. 125: ============ 126: */ 127: cvar_t *Cvar_Get (char *var_name, char *var_value, int flags) 128: { 129: cvar_t *var; 130: 131: if (flags & (CVAR_USERINFO | CVAR_SERVERINFO)) 132: { 133: if (!Cvar_InfoValidate (var_name)) 134: { 135: Com_Printf("invalid info cvar name\n"); 136: return NULL; 137: } 138: } 139: 140: var = Cvar_FindVar (var_name); 141: if (var) 142: { 143: var->flags |= flags; 144: return var; 145: } 1.1.1.2 root 146: 1.1 root 147: if (!var_value) 148: return NULL; 149: 150: if (flags & (CVAR_USERINFO | CVAR_SERVERINFO)) 151: { 152: if (!Cvar_InfoValidate (var_value)) 153: { 154: Com_Printf("invalid info cvar value\n"); 155: return NULL; 156: } 157: } 158: 159: var = Z_Malloc (sizeof(*var)); 160: var->name = CopyString (var_name); 161: var->string = CopyString (var_value); 162: var->modified = true; 163: var->value = atof (var->string); 1.1.1.2 root 164: 1.1 root 165: // link the variable in 166: var->next = cvar_vars; 167: cvar_vars = var; 1.1.1.2 root 168: 1.1 root 169: var->flags = flags; 1.1.1.2 root 170: 1.1 root 171: return var; 172: } 1.1.1.2 root 173: 1.1 root 174: /* 175: ============ 176: Cvar_Set2 177: ============ 178: */ 179: cvar_t *Cvar_Set2 (char *var_name, char *value, qboolean force) 180: { 181: cvar_t *var; 182: 183: var = Cvar_FindVar (var_name); 184: if (!var) 185: { // create it 186: return Cvar_Get (var_name, value, 0); 187: } 1.1.1.2 root 188: 1.1 root 189: if (var->flags & (CVAR_USERINFO | CVAR_SERVERINFO)) 190: { 191: if (!Cvar_InfoValidate (value)) 192: { 193: Com_Printf("invalid info cvar value\n"); 194: return var; 195: } 196: } 197: 198: if (!force) 199: { 200: if (var->flags & CVAR_NOSET) 201: { 202: Com_Printf ("%s is write protected.\n", var_name); 203: return var; 204: } 1.1.1.2 root 205: 1.1 root 206: if (var->flags & CVAR_LATCH) 207: { 208: if (var->latched_string) 209: { 210: if (strcmp(value, var->latched_string) == 0) 211: return var; 212: Z_Free (var->latched_string); 213: } 214: else 215: { 216: if (strcmp(value, var->string) == 0) 217: return var; 218: } 219: 220: if (Com_ServerState()) 221: { 222: Com_Printf ("%s will be changed for next game.\n", var_name); 223: var->latched_string = CopyString(value); 224: } 225: else 226: { 227: var->string = CopyString(value); 228: var->value = atof (var->string); 229: if (!strcmp(var->name, "game")) 230: { 231: FS_SetGamedir (var->string); 232: FS_ExecAutoexec (); 233: } 234: } 235: return var; 236: } 237: } 238: else 239: { 240: if (var->latched_string) 241: { 242: Z_Free (var->latched_string); 243: var->latched_string = NULL; 244: } 245: } 1.1.1.2 root 246: 1.1 root 247: if (!strcmp(value, var->string)) 248: return var; // not changed 1.1.1.2 root 249: 1.1 root 250: var->modified = true; 1.1.1.2 root 251: 1.1 root 252: if (var->flags & CVAR_USERINFO) 253: userinfo_modified = true; // transmit at next oportunity 254: 255: Z_Free (var->string); // free the old value string 256: 257: var->string = CopyString(value); 258: var->value = atof (var->string); 1.1.1.2 root 259: 1.1 root 260: return var; 261: } 1.1.1.2 root 262: 1.1 root 263: /* 264: ============ 265: Cvar_ForceSet 266: ============ 267: */ 268: cvar_t *Cvar_ForceSet (char *var_name, char *value) 269: { 270: return Cvar_Set2 (var_name, value, true); 271: } 1.1.1.2 root 272: 1.1 root 273: /* 274: ============ 275: Cvar_Set 276: ============ 277: */ 278: cvar_t *Cvar_Set (char *var_name, char *value) 279: { 280: return Cvar_Set2 (var_name, value, false); 281: } 1.1.1.2 root 282: 1.1 root 283: /* 284: ============ 285: Cvar_FullSet 286: ============ 287: */ 288: cvar_t *Cvar_FullSet (char *var_name, char *value, int flags) 289: { 290: cvar_t *var; 291: 292: var = Cvar_FindVar (var_name); 293: if (!var) 294: { // create it 295: return Cvar_Get (var_name, value, flags); 296: } 1.1.1.2 root 297: 1.1 root 298: var->modified = true; 1.1.1.2 root 299: 1.1 root 300: if (var->flags & CVAR_USERINFO) 301: userinfo_modified = true; // transmit at next oportunity 302: 303: Z_Free (var->string); // free the old value string 304: 305: var->string = CopyString(value); 306: var->value = atof (var->string); 307: var->flags = flags; 1.1.1.2 root 308: 1.1 root 309: return var; 310: } 1.1.1.2 root 311: 1.1 root 312: /* 313: ============ 314: Cvar_SetValue 315: ============ 316: */ 317: void Cvar_SetValue (char *var_name, float value) 318: { 319: char val[32]; 320: 321: if (value == (int)value) 322: Com_sprintf (val, sizeof(val), "%i",(int)value); 323: else 324: Com_sprintf (val, sizeof(val), "%f",value); 325: Cvar_Set (var_name, val); 326: } 1.1.1.2 root 327: 328: 1.1 root 329: /* 330: ============ 331: Cvar_GetLatchedVars 1.1.1.2 root 332: 1.1 root 333: Any variables with latched values will now be updated 334: ============ 335: */ 336: void Cvar_GetLatchedVars (void) 337: { 338: cvar_t *var; 1.1.1.2 root 339: 1.1 root 340: for (var = cvar_vars ; var ; var = var->next) 341: { 342: if (!var->latched_string) 343: continue; 344: Z_Free (var->string); 345: var->string = var->latched_string; 346: var->latched_string = NULL; 347: var->value = atof(var->string); 348: if (!strcmp(var->name, "game")) 349: { 350: FS_SetGamedir (var->string); 351: FS_ExecAutoexec (); 352: } 353: } 354: } 1.1.1.2 root 355: 1.1 root 356: /* 357: ============ 358: Cvar_Command 1.1.1.2 root 359: 1.1 root 360: Handles variable inspection and changing from the console 361: ============ 362: */ 363: qboolean Cvar_Command (void) 364: { 365: cvar_t *v; 1.1.1.2 root 366: 1.1 root 367: // check variables 368: v = Cvar_FindVar (Cmd_Argv(0)); 369: if (!v) 370: return false; 371: 372: // perform a variable print or set 373: if (Cmd_Argc() == 1) 374: { 375: Com_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); 376: return true; 377: } 1.1.1.2 root 378: 1.1 root 379: Cvar_Set (v->name, Cmd_Argv(1)); 380: return true; 381: } 1.1.1.2 root 382: 383: 1.1 root 384: /* 385: ============ 386: Cvar_Set_f 1.1.1.2 root 387: 1.1 root 388: Allows setting and defining of arbitrary cvars from console 389: ============ 390: */ 391: void Cvar_Set_f (void) 392: { 393: int c; 394: int flags; 1.1.1.2 root 395: 1.1 root 396: c = Cmd_Argc(); 397: if (c != 3 && c != 4) 398: { 399: Com_Printf ("usage: set <variable> <value> [u / s]\n"); 400: return; 401: } 1.1.1.2 root 402: 1.1 root 403: if (c == 4) 404: { 405: if (!strcmp(Cmd_Argv(3), "u")) 406: flags = CVAR_USERINFO; 407: else if (!strcmp(Cmd_Argv(3), "s")) 408: flags = CVAR_SERVERINFO; 409: else 410: { 411: Com_Printf ("flags can only be 'u' or 's'\n"); 412: return; 413: } 414: Cvar_FullSet (Cmd_Argv(1), Cmd_Argv(2), flags); 415: } 416: else 417: Cvar_Set (Cmd_Argv(1), Cmd_Argv(2)); 418: } 1.1.1.2 root 419: 420: 1.1 root 421: /* 422: ============ 423: Cvar_WriteVariables 1.1.1.2 root 424: 1.1 root 425: Appends lines containing "set variable value" for all variables 426: with the archive flag set to true. 427: ============ 428: */ 429: void Cvar_WriteVariables (char *path) 430: { 431: cvar_t *var; 432: char buffer[1024]; 433: FILE *f; 1.1.1.2 root 434: 1.1 root 435: f = fopen (path, "a"); 436: for (var = cvar_vars ; var ; var = var->next) 437: { 438: if (var->flags & CVAR_ARCHIVE) 439: { 440: Com_sprintf (buffer, sizeof(buffer), "set %s \"%s\"\n", var->name, var->string); 441: fprintf (f, "%s", buffer); 442: } 443: } 444: fclose (f); 445: } 1.1.1.2 root 446: 1.1 root 447: /* 448: ============ 449: Cvar_List_f 1.1.1.2 root 450: 1.1 root 451: ============ 452: */ 453: void Cvar_List_f (void) 454: { 455: cvar_t *var; 456: int i; 1.1.1.2 root 457: 1.1 root 458: i = 0; 459: for (var = cvar_vars ; var ; var = var->next, i++) 460: { 461: if (var->flags & CVAR_ARCHIVE) 462: Com_Printf ("*"); 463: else 464: Com_Printf (" "); 465: if (var->flags & CVAR_USERINFO) 466: Com_Printf ("U"); 467: else 468: Com_Printf (" "); 469: if (var->flags & CVAR_SERVERINFO) 470: Com_Printf ("S"); 471: else 472: Com_Printf (" "); 473: if (var->flags & CVAR_NOSET) 474: Com_Printf ("-"); 475: else if (var->flags & CVAR_LATCH) 476: Com_Printf ("L"); 477: else 478: Com_Printf (" "); 479: Com_Printf (" %s \"%s\"\n", var->name, var->string); 480: } 481: Com_Printf ("%i cvars\n", i); 482: } 1.1.1.2 root 483: 484: 1.1 root 485: qboolean userinfo_modified; 1.1.1.2 root 486: 487: 1.1 root 488: char *Cvar_BitInfo (int bit) 489: { 490: static char info[MAX_INFO_STRING]; 491: cvar_t *var; 1.1.1.2 root 492: 1.1 root 493: info[0] = 0; 1.1.1.2 root 494: 1.1 root 495: for (var = cvar_vars ; var ; var = var->next) 496: { 497: if (var->flags & bit) 498: Info_SetValueForKey (info, var->name, var->string); 499: } 500: return info; 501: } 1.1.1.2 root 502: 1.1 root 503: // returns an info string containing all the CVAR_USERINFO cvars 504: char *Cvar_Userinfo (void) 505: { 506: return Cvar_BitInfo (CVAR_USERINFO); 507: } 1.1.1.2 root 508: 1.1 root 509: // returns an info string containing all the CVAR_SERVERINFO cvars 510: char *Cvar_Serverinfo (void) 511: { 512: return Cvar_BitInfo (CVAR_SERVERINFO); 513: } 1.1.1.2 root 514: 1.1 root 515: /* 516: ============ 517: Cvar_Init 1.1.1.2 root 518: 1.1 root 519: Reads in all archived cvars 520: ============ 521: */ 522: void Cvar_Init (void) 523: { 524: Cmd_AddCommand ("set", Cvar_Set_f); 525: Cmd_AddCommand ("cvarlist", Cvar_List_f); 1.1.1.2 root 526: 1.1 root 527: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.