387 lines · 7.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include "dat.h"#include "fns.h" /* Dynamic variable tracking * * cvar_t variables are used to hold scalar or string variables that can be * changed or displayed at the console or prog code as well as accessed * directly in C code. The user can access cvars from the console in three ways: * r_draworder		prints the current value * r_draworder 0	sets the current value to 0 * set r_draworder 0	as above, but creates the cvar if not present * Cvars are restricted from having the same names as commands to keep this * interface from being ambiguous. */ cvar_t *cvar_vars; /* if set, each time a CVAR_USERINFO var is changed, the client will send it * to the server */qboolean userinfo_modified;  static qbooleanCvar_InfoValidate(char *s){	if(strstr(s, "\\"))		return false;	if(strstr(s, "\""))		return false;	if(strstr(s, ";"))		return false;	return true;} static cvar_t *Cvar_FindVar(char *name){	cvar_t *p; 	for(p = cvar_vars; p != nil; p = p->next)		if(!strcmp(name, p->name))			return p;	return nil;} floatCvar_VariableValue(char *name){	cvar_t *p;		if((p = Cvar_FindVar(name)) == nil)		return 0;	return atof(p->string);} char *Cvar_VariableString(char *name){	cvar_t *p; 	if((p = Cvar_FindVar(name)) == nil)		return "";	return p->string;} char *Cvar_CompleteVariable(char *partial){	cvar_t *p;	int len; 	len = strlen(partial);	if(!len)		return nil; 	/* check exact match */	for(p = cvar_vars; p != nil; p = p->next)		if(!strcmp(partial, p->name))			return p->name;	/* check partial match */	for(p = cvar_vars; p != nil; p = p->next)		if(!strncmp(partial, p->name, len))			return p->name;	return nil;} /* If the variable already exists, the value will not be set. The flags will be * or'ed in if the variable exists. */cvar_t *Cvar_Get(char *var_name, char *var_value, int flags){	cvar_t *p;		if(flags & (CVAR_USERINFO|CVAR_SERVERINFO)){		if(!Cvar_InfoValidate(var_name)){			Com_Printf("invalid info cvar name\n");			return nil;		}	} 	if((p = Cvar_FindVar(var_name)) != nil){		p->flags |= flags;		return p;	} 	if(!var_value)		return nil; 	if(flags & (CVAR_USERINFO|CVAR_SERVERINFO)){		if(!Cvar_InfoValidate(var_value)){			Com_Printf("invalid info cvar value\n");			return nil;		}	} 	p = Z_Malloc(sizeof(*p));	p->name = CopyString(var_name);	p->string = CopyString(var_value);	p->modified = true;	p->value = atof(p->string);	p->next = cvar_vars;	cvar_vars = p;	p->flags = flags;	return p;} cvar_t *Cvar_Set2(char *var_name, char *value, qboolean force){	cvar_t *var; 	var = Cvar_FindVar(var_name);	if(!var)		return Cvar_Get(var_name, value, 0);	// create it 	if(var->flags & (CVAR_USERINFO|CVAR_SERVERINFO)){		if(!Cvar_InfoValidate(value)){			Com_Printf("invalid info cvar value\n");			return var;		}	}	if(!force){		if(var->flags & CVAR_NOSET){			Com_Printf("%s is write protected.\n", var_name);			return var;		}		if(var->flags & CVAR_LATCH){			if(var->latched_string){				if(!strcmp(value, var->latched_string))					return var;				Z_Free(var->latched_string);			}else if(!strcmp(value, var->string))					return var; 			if(Com_ServerState()){				Com_Printf("%s will be changed for next game.\n", var_name);				var->latched_string = CopyString(value);			}else{				var->string = CopyString(value);				var->value = atof(var->string);				if(!strcmp(var->name, "game")){					FS_SetGamedir(var->string);					FS_ExecAutoexec();				}			}			return var;		}	}else{		if(var->latched_string){			Z_Free(var->latched_string);			var->latched_string = nil;		}	} 	if(!strcmp(value, var->string))		return var;	// not changed 	var->modified = true; 	if(var->flags & CVAR_USERINFO)		userinfo_modified = true;	// transmit at next oportunity		Z_Free(var->string);	// free the old value string	var->string = CopyString(value);	var->value = atof(var->string);	return var;} /* set the variable even if NOSET or LATCH */cvar_t *Cvar_ForceSet(char *var_name, char *value){	return Cvar_Set2(var_name, value, true);} cvar_t *Cvar_Set(char *var_name, char *value){	return Cvar_Set2(var_name, value, false);} cvar_t *Cvar_FullSet(char *var_name, char *value, int flags){	cvar_t *var;		var = Cvar_FindVar(var_name);	if(!var)		return Cvar_Get(var_name, value, flags);	// create it 	var->modified = true; 	if(var->flags & CVAR_USERINFO)		userinfo_modified = true;	// transmit at next oportunity 	Z_Free(var->string);	// free the old value string	var->string = CopyString(value);	var->value = atof(var->string);	var->flags = flags;	return var;} voidCvar_SetValue(char *var_name, float value){	char val[32]; 	if(value == (int)value)		Com_sprintf(val, sizeof val, "%d", (int)value);	else		Com_sprintf(val, sizeof val, "%f", value);	Cvar_Set(var_name, val);} /* Any variables with latched values will now be updated */voidCvar_GetLatchedVars(void){	cvar_t *p; 	for(p = cvar_vars; p != nil; p = p->next){		if(!p->latched_string)			continue;		Z_Free(p->string);		p->string = p->latched_string;		p->latched_string = nil;		p->value = atof(p->string);		if(!strcmp(p->name, "game")){			FS_SetGamedir(p->string);			FS_ExecAutoexec();		}	}} /* called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known command. * Returns true if the command was a variable reference that was handled (print * or change). */qbooleanCvar_Command(void){	cvar_t *p; 	/* check variables */	if((p = Cvar_FindVar(Cmd_Argv(0))) == nil)		return false; 	/* perform a variable print or set */	if(Cmd_Argc() == 1){		Com_Printf("\"%s\" is \"%s\"\n", p->name, p->string);		return true;	} 	Cvar_Set(p->name, Cmd_Argv(1));	return true;} /* Allows setting and defining of arbitrary cvars from console */voidCvar_Set_f(void){	int c;	int flags; 	c = Cmd_Argc();	if(c != 3 && c != 4){		Com_Printf("usage: set <variable> <value> [u / s]\n");		return;	}	if(c == 4){		if(!strcmp(Cmd_Argv(3), "u"))			flags = CVAR_USERINFO;		else if(!strcmp(Cmd_Argv(3), "s"))			flags = CVAR_SERVERINFO;		else{			Com_Printf("flags can only be 'u' or 's'\n");			return;		}		Cvar_FullSet(Cmd_Argv(1), Cmd_Argv(2), flags);	}else		Cvar_Set(Cmd_Argv(1), Cmd_Argv(2));} /* Appends lines containing "set variable value" for all variables with the * archive flag set to true. */voidCvar_WriteVariables(char *path){	int fd;	cvar_t *p; 	if((fd = open(path, OWRITE)) < 0){		fprint(2, "Cvar_WriteVariables:open: %r\n");		return;	}	seek(fd, 0, 2);	for(p = cvar_vars; p != nil; p = p->next)		if(p->flags & CVAR_ARCHIVE)			if(fprint(fd, "set %s \"%s\"\n", p->name, p->string) < 0)				sysfatal("Cvar_WriteVariables:fprint: %r");	close(fd);} voidCvar_List_f(void){	cvar_t *p;	int i; 	for(p = cvar_vars, i = 0; p != nil; p = p->next, i++){		if(p->flags & CVAR_ARCHIVE)			Com_Printf("*");		else			Com_Printf(" ");		if(p->flags & CVAR_USERINFO)			Com_Printf("U");		else			Com_Printf(" ");		if(p->flags & CVAR_SERVERINFO)			Com_Printf("S");		else			Com_Printf(" ");		if(p->flags & CVAR_NOSET)			Com_Printf("-");		else if(p->flags & CVAR_LATCH)			Com_Printf("L");		else			Com_Printf(" ");		Com_Printf(" %s \"%s\"\n", p->name, p->string);	}	Com_Printf("%d cvars\n", i);} char *Cvar_BitInfo(int bit){	static char info[MAX_INFO_STRING];	cvar_t *p; 	info[0] = 0;	for(p = cvar_vars; p != nil; p = p->next)		if(p->flags & bit)			Info_SetValueForKey(info, p->name, p->string);	return info;} /* returns an info string containing all the CVAR_USERINFO cvars */char *Cvar_Userinfo(void){	return Cvar_BitInfo(CVAR_USERINFO);} /* returns an info string containing all the CVAR_SERVERINFO cvars */char *Cvar_Serverinfo(void){	return Cvar_BitInfo(CVAR_SERVERINFO);} voidCvar_Init(void){	Cmd_AddCommand("set", Cvar_Set_f);	Cmd_AddCommand("cvarlist", Cvar_List_f);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t