20 #include "shared/shared.h"
21 #include "common/cmd.h"
22 #include "common/common.h"
23 #include "common/cvar.h"
24 #include "common/files.h"
25 #include "common/prompt.h"
26 #include "common/utils.h"
27 #include "common/zone.h"
34 #define Cvar_Malloc(size) Z_TagMalloc(size, TAG_CVAR)
36 #define CVARHASH_SIZE 256
52 for (var =
cvarHash[hash]; var; var = var->hashNext) {
53 if (!strcmp(var_name, var->name)) {
65 return var ? var->generator : NULL;
79 if (!weak && (var->flags & (CVAR_CUSTOM | CVAR_WEAK)))
146 cvar_t *
c = ctx->data;
149 if (strcmp(
c->string,
c->default_string)) {
159 char *s = var->string;
161 if (s[0] ==
'0' && s[1] ==
'x') {
162 long v = strtol(s, NULL, 16);
164 var->integer = clamp(v, INT_MIN, INT_MAX);
165 var->value = (float)var->integer;
167 var->integer = atoi(var->string);
168 var->value = atof(var->string);
181 if (var->flags & CVAR_USERINFO) {
185 var->modified = qtrue;
186 if (from != FROM_CODE) {
188 var->flags |= CVAR_MODIFIED;
189 if (from == FROM_MENU && !(var->flags & CVAR_NOARCHIVEMASK)) {
190 var->flags |= CVAR_ARCHIVE;
202 if (len == SIZE_MAX) {
203 Com_Printf(
"Info cvars should not contain '\\', ';' or '\"' characters.\n");
207 if (len >= MAX_QPATH) {
208 Com_Printf(
"Info cvars should be less than 64 characters long.\n");
221 if (var->flags & (CVAR_CUSTOM | CVAR_WEAK)) {
223 Z_Free(var->default_string);
227 if (strcmp(var_value, var->string)) {
228 if ((flags & CVAR_ROM) ||
232 (var->flags & CVAR_WEAK)) {
237 flags |= CVAR_MODIFIED;
245 var->flags &= ~(CVAR_GAME | CVAR_CUSTOM | CVAR_WEAK);
257 cvar_t *
Cvar_Get(
const char *var_name,
const char *var_value,
int flags)
259 cvar_t *var, *
c, **p;
264 Com_Error(ERR_FATAL,
"Cvar_Get: NULL var_name");
270 if (flags & CVAR_INFOMASK) {
281 if (!(flags & (CVAR_WEAK | CVAR_CUSTOM))) {
289 length = strlen(var_name) + 1;
291 var->name = (
char *)(var + 1);
292 memcpy(var->name, var_name, length);
294 var->latched_string = NULL;
300 var->modified = qtrue;
304 if (strcmp(var->name,
c->name) < 0) {
326 return Cvar_Get(var_name,
"", CVAR_WEAK);
331 if (var->flags & CVAR_LATCH) {
333 if (var->latched_string) {
334 Z_Free(var->latched_string);
335 var->latched_string = NULL;
350 if (!strcmp(value, var->string)) {
355 if (var->flags & CVAR_INFOMASK) {
362 if (from != FROM_CODE) {
363 if (var->flags & CVAR_ROM) {
364 Com_Printf(
"%s is read-only.\n", var->name);
368 if (var->flags & CVAR_CHEAT) {
370 Com_Printf(
"%s is cheat protected.\n", var->name);
378 if (var->flags & CVAR_NOSET) {
379 Com_Printf(
"%s may be set from command line only.\n", var->name);
383 if (var->flags & CVAR_LATCH) {
385 if (var->latched_string) {
386 if (!strcmp(var->latched_string, value)) {
389 Z_Free(var->latched_string);
390 var->latched_string = NULL;
394 Com_Printf(
"%s will be changed for next game.\n", var->name);
404 if (var->latched_string) {
405 Z_Free(var->latched_string);
406 var->latched_string = NULL;
417 cvar_t *
Cvar_SetEx(
const char *var_name,
const char *value, from_t from)
424 return Cvar_Get(var_name, value, CVAR_CUSTOM);
437 cvar_t *
Cvar_FullSet(
const char *var_name,
const char *value,
int flags, from_t from)
444 return Cvar_Get(var_name, value, flags | CVAR_CUSTOM);
451 if ((var->flags | flags) & CVAR_USERINFO) {
455 var->flags &= ~CVAR_INFOMASK;
466 cvar_t *
Cvar_Set(
const char *var_name,
const char *value)
468 return Cvar_SetEx(var_name, value, FROM_CODE);
478 return Cvar_SetEx(var_name, value, FROM_CONSOLE);
491 if (var->value == value) {
496 if (value == (
int)value)
497 Q_snprintf(val,
sizeof(val),
"%i", (
int)value);
513 if (var->integer == value) {
529 void Cvar_SetHex(cvar_t *var,
int value, from_t from)
533 if (var->integer == value) {
553 if (var->integer < min) {
558 if (var->integer > max) {
575 if (var->value < min) {
576 if (min == (
int)min) {
584 if (var->value > max) {
585 if (max == (
int)max) {
610 for (var =
cvar_vars; var; var = var->next) {
611 if (var->flags & CVAR_CHEAT) {
630 for (var =
cvar_vars; var; var = var->next) {
631 if (var->flags & CVAR_GAME)
632 var->flags &= ~CVAR_SERVERINFO;
633 if (!(var->flags & CVAR_LATCH))
635 if (!var->latched_string)
638 var->string = var->latched_string;
639 var->latched_string = NULL;
641 var->modified = qtrue;
654 for (var =
cvar_vars; var; var = var->next) {
655 if (!(var->flags & CVAR_LATCH))
657 if (!var->latched_string)
676 Com_Printf(
"\"%s\" is \"%s\"", v->name, v->string);
677 if (strcmp(v->string, v->default_string)) {
678 Com_Printf(
" default: \"%s\"", v->default_string);
680 if (v->latched_string && strcmp(v->latched_string, v->string)) {
681 Com_Printf(
" latched: \"%s\"", v->latched_string);
697 }
else if (argnum == 2) {
724 Com_Printf(
"Usage: set <variable> <value> [u / s]\n");
735 if (!strcmp(f,
"u")) {
736 flags = CVAR_USERINFO;
737 }
else if (!strcmp(f,
"s")) {
738 flags = CVAR_SERVERINFO;
763 Com_Printf(
"Usage: %s <variable> <value>\n", s);
767 if (!strcmp(s,
"seta")) {
769 if (var && !(var->flags & CVAR_NOARCHIVEMASK))
770 var->flags |= CVAR_ARCHIVE;
774 if (!strcmp(s,
"setu")) {
775 flags = CVAR_USERINFO;
776 }
else if (!strcmp(s,
"sets")) {
777 flags = CVAR_SERVERINFO;
795 void Cvar_WriteVariables(qhandle_t f,
int mask, qboolean modified)
800 for (var =
cvar_vars; var; var = var->next) {
801 if (var->flags & CVAR_NOARCHIVEMASK)
803 if (!(var->flags & mask))
806 s = var->latched_string ? var->latched_string : var->string;
807 if (modified && !strcmp(s, var->default_string))
810 a = !modified && (var->flags & CVAR_ARCHIVE) ?
"a" :
"";
811 FS_FPrintf(f,
"set%s %s \"%s\"\n", a, var->name, s);
825 {
"a",
"archive",
"list archived cvars" },
826 {
"c",
"cheat",
"list cheat protected cvars" },
827 {
"h",
"help",
"display this help message" },
828 {
"l",
"latched",
"list latched cvars" },
829 {
"m",
"modified",
"list modified cvars" },
830 {
"n",
"noset",
"list command line cvars" },
831 {
"r",
"rom",
"list read-only cvars" },
832 {
"s",
"serverinfo",
"list serverinfo cvars" },
833 {
"t",
"custom",
"list user-created cvars" },
834 {
"u",
"userinfo",
"list userinfo cvars" },
835 {
"v",
"verbose",
"display flags of each cvar" },
836 {
"w:string",
"wildcard",
"list cvars matching wildcard" },
849 qboolean verbose = qfalse, modified = qfalse, latched = qfalse;
851 char *wildcard = NULL;
858 mask |= CVAR_ARCHIVE;
865 Com_Printf(
"List registered console variables.\n");
869 "C: cheat protected\n"
870 "A: archived in config file\n"
871 "U: included in userinfo\n"
872 "S: included in serverinfo\n"
873 "N: set from command line only\n"
874 "R: read-only variable\n"
876 "?: created by user\n");
891 mask |= CVAR_SERVERINFO;
897 mask |= CVAR_USERINFO;
910 buffer[
sizeof(buffer) - 1] = 0;
912 for (var =
cvar_vars, total = 0; var; var = var->next, total++) {
913 if (latched && !var->latched_string) {
916 if (mask && !(var->flags & mask)) {
919 if (wildcard && !Com_WildCmp(wildcard, var->name)) {
922 if (modified && (!strcmp(var->latched_string ? var->latched_string :
923 var->string, var->default_string) || (var->flags & CVAR_ROM))) {
928 memset(buffer,
'-',
sizeof(buffer) - 1);
930 if (var->flags & CVAR_CHEAT)
932 else if (var->flags & CVAR_ARCHIVE)
935 if (var->flags & CVAR_USERINFO)
938 if (var->flags & CVAR_SERVERINFO)
941 if (var->flags & CVAR_ROM)
943 else if (var->flags & CVAR_NOSET)
945 else if (var->flags & CVAR_LATCH)
947 else if (var->flags & CVAR_CUSTOM)
950 Com_Printf(
"%s ", buffer);
953 Com_Printf(
"%s \"%s\"\n", var->name, var->string);
957 Com_Printf(
"%i of %i cvars\n", i, total);
971 Com_Printf(
"Usage: %s <variable> [values]\n",
Cmd_Argv(0));
977 Com_Printf(
"%s is not a variable\n",
Cmd_Argv(1));
982 if (!strcmp(var->string,
"0")) {
984 }
else if (!strcmp(var->string,
"1")) {
987 Com_Printf(
"\"%s\" is \"%s\", can't toggle\n",
988 var->name, var->string);
993 for (i = 0; i < argc - 2; i++) {
994 if (!Q_stricmp(var->string,
Cmd_Argv(2 + i))) {
995 i = (i + 1) % (argc - 2);
1001 Com_Printf(
"\"%s\" is \"%s\", can't cycle\n", var->name, var->string);
1012 s =
Cmd_Argv(ctx->argnum - argnum + 1);
1031 Com_Printf(
"Usage: %s <variable> [value]\n",
Cmd_Argv(0));
1037 Com_Printf(
"%s is not a variable\n",
Cmd_Argv(1));
1042 Com_Printf(
"\"%s\" is \"%s\", can't %s\n",
1043 var->name, var->string,
Cmd_Argv(0));
1054 value += var->value;
1056 if (value == (
int)value)
1057 Q_snprintf(val,
sizeof(val),
"%i", (
int)value);
1074 Com_Printf(
"Usage: %s <variable>\n",
Cmd_Argv(0));
1080 Com_Printf(
"%s is not a variable\n",
Cmd_Argv(1));
1098 for (var =
cvar_vars; var; var = var->next) {
1099 if (var->flags & CVAR_ROM)
1111 char newi[MAX_INFO_STRING], *v;
1113 size_t len, total = 0;
1116 for (var =
cvar_vars; var; var = var->next) {
1117 if (!(var->flags & bit)) {
1120 if (var->flags & CVAR_PRIVATE) {
1123 if (!var->string[0]) {
1127 "\\", var->name,
"\\", var->string, NULL);
1128 if (len >=
sizeof(newi)) {
1131 if (total + len >= MAX_INFO_STRING) {