void Cvar_Set_tp_f (void) { cvar_t *var; char *var_name; if (Cmd_Argc() != 3) { Com_Printf ("Usage: %s <cvar> <value>\n", Cmd_Argv(0)); return; } var_name = Cmd_Argv (1); var = Cvar_Find (var_name); if (var) { if (!var->teamplay) { Com_Printf("\"%s\" is not a teamplay variable\n", var->name); return; } else { Cvar_Set (var, Cmd_Argv(2)); } } else { if (Cmd_Exists(var_name)) { Com_Printf ("\"%s\" is a command\n", var_name); return; } var = Cvar_Create (var_name, Cmd_Argv(2), 0); var->teamplay = true; } }
void Cvar_Set_ex_f (void) { cvar_t *var; char *var_name; char *st = NULL; char text_exp[1024]; if (Cmd_Argc() != 3) { Com_Printf ("usage: set_ex <cvar> <value>\n"); return; } var_name = Cmd_Argv (1); var = Cvar_Find (var_name); if ( !var ) { if (Cmd_Exists(var_name)) { Com_Printf ("\"%s\" is a command\n", var_name); return; } var = Cvar_Create(var_name, "", 0); } Cmd_ExpandString( Cmd_Argv(2), text_exp); st = TP_ParseMacroString( text_exp ); st = TP_ParseFunChars(st, false); Cvar_Set (var, st ); }
// if an unknown command with parameters was encountered when loading // config.cfg, assume it's a cvar set and spawn a temp var qbool Cvar_CreateTempVar (void) { char *name = Cmd_Argv(0); // FIXME, make sure it's a valid cvar name, return false if not // Cvar_Get (name, Cmd_MakeArgs(1), CVAR_TEMP); Cvar_Create (name, Cmd_MakeArgs(1), CVAR_TEMP); return true; }
void Cvar_Set_Bind_Str_f (void) { cvar_t *var; int keynum; char *var_name; char *key_name; //char str[1024]; //char *v,*s; if (Cmd_Argc() != 3) { Com_Printf ("usage: set_bind_str <cvar> <key>\n"); return; } var_name = Cmd_Argv (1); key_name = Cmd_Argv (2); var = Cvar_Find (var_name); keynum = Key_StringToKeynum( key_name ); if ( !var) { if (Cmd_Exists(var_name)) { Com_Printf ("\"%s\" is a command\n", var_name); return; } var = Cvar_Create(var_name, "", 0); } if (!var) { Com_Printf ("Unknown variable \"%s\"\n", var_name); return; } else if (keynum == -1) { Com_Printf ("Unknown key \"%s\"\n", key_name); return; } else { if (keybindings[keynum]) { /* s = str; v = keybindings[keynum]; while (*v) { if (*v == '\"') // " should be escaped *s++ = '\\'; *s++ = *v++; } *s = '\0'; Cvar_Set (var, str);*/ Cvar_Set (var, keybindings[keynum]); } else Cvar_Set (var, ""); } }
void Cvar_Set_Eval_f(void) { if (Cmd_Argc() < 3) { Com_Printf("Usage:\n" "set_eval <variable> <expression>\n" "set_eval is similar to set_calc but supports richer expressions\n"); return; } else { const char *expression; char *var_name; cvar_t *var; int errn; expr_val result; var_name = Cmd_Argv (1); var = Cvar_Find (var_name); if (!var) var = Cvar_Create (var_name, Cmd_Argv (1), 0); expression = Cmd_MakeArgs(2); result = Expr_Eval(expression, NULL, &errn); if (errn == EXPR_EVAL_SUCCESS) { switch (result.type) { case ET_INT: Cvar_SetValue(var, result.i_val); break; case ET_DBL: Cvar_SetValue(var, result.d_val); break; case ET_BOOL: Cvar_SetValue(var, result.b_val ? 1 : 0); break; case ET_STR: Cvar_Set(var, result.s_val); free(result.s_val); break; } } else { Com_Printf("Error in expression: %s\n", Parser_Error_Description(errn)); } } }
void Cvar_Set_Alias_Str_f (void) { cvar_t *var; char *var_name; char *alias_name; //char str[1024]; char *v /*,*s*/; if (Cmd_Argc() != 3) { Com_Printf ("usage: set_alias_str <cvar> <alias>\n"); return; } var_name = Cmd_Argv (1); alias_name = Cmd_Argv (2); var = Cvar_Find (var_name); v = Cmd_AliasString( alias_name ); if ( !var) { if (Cmd_Exists(var_name)) { Com_Printf ("\"%s\" is a command\n", var_name); return; } var = Cvar_Create(var_name, "", 0); } if (!var) { Com_Printf ("Unknown variable \"%s\"\n", var_name); return; } else if (!v) { Com_Printf ("Unknown alias \"%s\"\n", alias_name); return; } else { /* s = str; while (*v) { if (*v == '\"') // " should be escaped *s++ = '\\'; *s++ = *v++; } *s = '\0'; Cvar_Set (var, str);*/ Cvar_Set (var, v); } }
// XXX: this could do with some refactoring void Cvar_Set_Calc_f(void) { cvar_t *var, *var2; char *var_name, *op, *a2, *a3; int pos, len, division_by_zero = 0; float num1, num2, result; char buf[1024]; var_name = Cmd_Argv (1); var = Cvar_Find (var_name); if (!var) var = Cvar_Create (var_name, Cmd_Argv (2), 0); a2 = Cmd_Argv (2); a3 = Cmd_Argv (3); if (!strcmp (a2, "strlen")) { Cvar_SetValue (var, strlen (a3)); return; } else if (!strcmp (a2, "int")) { Cvar_SetValue (var, (int) Q_atof (a3)); return; } else if (!strcmp (a2, "substr")) { int var2len; var2 = Cvar_Find (a3); if (!var2) { Com_Printf ("Unknown variable \"%s\"\n", a3); return; } pos = atoi (Cmd_Argv (4)); len = (Cmd_Argc () < 6)? 1 : atoi (Cmd_Argv (5)); if (len == 0) { Cvar_Set (var, ""); return; } if (len < 0 || pos < 0) { Com_Printf ("substr: invalid len or pos\n"); return; } var2len = strlen (var2->string); if (var2len < pos) { Com_Printf ("substr: string length exceeded\n"); return; } len = min (var2len - pos, len); strlcpy (buf, var2->string + pos, len); Cvar_Set (var, buf); return; } else if (!strcmp (a2, "set_substr")) { int var1len,var2len; var2 = Cvar_Find (a3); if (!var2) { Com_Printf ("Unknown variable \"%s\"\n", a3); return; } var1len = strlen (var->string); var2len = strlen (var2->string); pos = atoi (Cmd_Argv (4)); strlcpy (buf, var->string, sizeof (buf)); if (pos + var2len > var1len) { // need to expand int i; for (i = var1len; i < pos + var2len; i++) buf[i] = ' '; buf[pos+var2len] = 0; } strlcpy (buf + pos, var2->string, sizeof (buf) - pos); Cvar_Set (var, buf); return; } else if (!strcmp (a2, "pos")) { var2 = Cvar_Find (a3); if (!var2) { Com_Printf ("Unknown variable \"%s\"\n", a3); return; } op = strstr (var2->string, Cmd_Argv (4)); Cvar_SetValue (var, op ? op - var2->string : -1); return; } else if (!strcmp (a2, "tobrown")) { strlcpy (buf, var->string, sizeof (buf)); CharsToBrown (buf, buf + strlen (buf)); Cvar_Set (var, buf); return; } else if (!strcmp (a2, "towhite")) { strlcpy (buf, var->string, sizeof (buf)); CharsToWhite (buf, buf + strlen (buf)); Cvar_Set (var, buf); return; } num1 = Q_atof (a2); op = a3; num2 = Q_atof (Cmd_Argv (4)); if (!strcmp (op, "+")) result = num1 + num2; else if (!strcmp (op, "-")) result = num1 - num2; else if (!strcmp (op, "*")) result = num1 * num2; else if (!strcmp (op, "/")) { if (num2 != 0) result = num1 / num2; else division_by_zero = 1; } else if (!strcmp (op, "%")) { if ((int) num2 != 0) result = (int) num1 % (int) num2; else division_by_zero = 1; } else if (!strcmp (op, "div")) { if ((int) num2 != 0) result = (int) num1 / (int) num2; else division_by_zero = 1; } else if (!strcmp (op, "and")) { result = (int) num1 & (int) num2; } else if (!strcmp (op, "or")) { result = (int) num1 | (int) num2; } else if (!strcmp (op, "xor")) { result = (int) num1 ^ (int) num2; } else { Com_Printf ("set_calc: unknown operator: %s\nvalid operators are: + - * / div %% and or xor\n", op); // Com_Printf("set_calc: unknown command: %s\nvalid commands are: strlen int substr set_substr pos\n", a2); return; } if (division_by_zero) { Com_Printf ("set_calc: can't divide by zero\n"); result = 999; } Cvar_SetValue (var, result); }
/* ================ SV_SpawnServer Change the server to a new map, taking all connected clients along with it. This is only called from the SV_Map_f() function. ================ */ void SV_SpawnServer (char *mapname, qbool devmap, char* entityfile) { extern func_t ED_FindFunctionOffset (char *name); edict_t *ent; int i; extern cvar_t sv_loadentfiles, sv_loadentfiles_dir; char *entitystring; char oldmap[MAP_NAME_LEN]; extern qbool sv_allow_cheats; extern cvar_t sv_cheats, sv_paused, sv_bigcoords; #ifndef SERVERONLY extern void CL_ClearState (void); #endif // store old map name snprintf (oldmap, MAP_NAME_LEN, "%s", sv.mapname); Con_DPrintf ("SpawnServer: %s\n",mapname); #ifndef SERVERONLY // As client+server we do it here. // As serveronly we do it in NET_Init(). NET_InitServer(); #endif SV_SaveSpawnparms (); SV_LoadAccounts(); #ifdef USE_PR2 // remove bot clients for (i = 0; i < MAX_CLIENTS; i++) { if( sv_vm && svs.clients[i].isBot ) { svs.clients[i].old_frags = 0; svs.clients[i].edict->v.frags = 0.0; svs.clients[i].name[0] = 0; svs.clients[i].state = cs_free; Info_RemoveAll(&svs.clients[i]._userinfo_ctx_); Info_RemoveAll(&svs.clients[i]._userinfoshort_ctx_); SV_FullClientUpdate(&svs.clients[i], &sv.reliable_datagram); svs.clients[i].isBot = 0; } } #endif // Shutdown game. PR_GameShutDown(); PR_UnLoadProgs(); svs.spawncount++; // any partially connected client will be restarted #ifndef SERVERONLY com_serveractive = false; #endif sv.state = ss_dead; sv.paused = false; Cvar_SetROM(&sv_paused, "0"); Host_ClearMemory(); #ifdef FTE_PEXT_FLOATCOORDS if (sv_bigcoords.value) { msg_coordsize = 4; msg_anglesize = 2; } else { msg_coordsize = 2; msg_anglesize = 1; } #endif if ((int)coop.value) Cvar_Set (&deathmatch, "0"); current_skill = (int) (skill.value + 0.5); if (current_skill < 0) current_skill = 0; Cvar_Set (&skill, va("%d", current_skill)); if (current_skill > 3) current_skill = 3; if ((sv_cheats.value || devmap) && !sv_allow_cheats) { sv_allow_cheats = true; Info_SetValueForStarKey (svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING); } else if ((!sv_cheats.value && !devmap) && sv_allow_cheats) { sv_allow_cheats = false; Info_SetValueForStarKey (svs.info, "*cheats", "", MAX_SERVERINFO_STRING); } // wipe the entire per-level structure // NOTE: this also set sv.mvdrecording to false, so calling SV_MVD_Record() at end of function memset (&sv, 0, sizeof(sv)); sv.datagram.maxsize = sizeof(sv.datagram_buf); sv.datagram.data = sv.datagram_buf; sv.datagram.allowoverflow = true; sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf); sv.reliable_datagram.data = sv.reliable_datagram_buf; sv.multicast.maxsize = sizeof(sv.multicast_buf); sv.multicast.data = sv.multicast_buf; sv.signon.maxsize = sizeof(sv.signon_buffers[0]); sv.signon.data = sv.signon_buffers[0]; sv.num_signon_buffers = 1; sv.time = 1.0; // load progs to get entity field count // which determines how big each edict is // and allocate edicts PR_LoadProgs (); #ifdef WITH_NQPROGS PR_InitPatchTables(); #endif PR_InitProg(); for (i = 0; i < MAX_EDICTS; i++) { ent = EDICT_NUM(i); ent->e = &sv.sv_edicts[i]; // assigning ->e field in each edict_t ent->e->entnum = i; ent->e->area.ed = ent; // yeah, pretty funny, but this help to find which edict_t own this area (link_t) } fofs_items2 = ED_FindFieldOffset ("items2"); // ZQ_ITEMS2 extension fofs_maxspeed = ED_FindFieldOffset ("maxspeed"); fofs_gravity = ED_FindFieldOffset ("gravity"); fofs_movement = ED_FindFieldOffset ("movement"); fofs_vw_index = ED_FindFieldOffset ("vw_index"); fofs_hideentity = ED_FindFieldOffset ("hideentity"); fofs_trackent = ED_FindFieldOffset ("trackent"); // find optional QC-exported functions. // we have it here, so we set it to NULL in case of PR2 progs. mod_SpectatorConnect = ED_FindFunctionOffset ("SpectatorConnect"); mod_SpectatorThink = ED_FindFunctionOffset ("SpectatorThink"); mod_SpectatorDisconnect = ED_FindFunctionOffset ("SpectatorDisconnect"); mod_ChatMessage = ED_FindFunctionOffset ("ChatMessage"); mod_UserInfo_Changed = ED_FindFunctionOffset ("UserInfo_Changed"); mod_ConsoleCmd = ED_FindFunctionOffset ("ConsoleCmd"); mod_UserCmd = ED_FindFunctionOffset ("UserCmd"); mod_localinfoChanged = ED_FindFunctionOffset ("localinfoChanged"); GE_ClientCommand = ED_FindFunctionOffset ("GE_ClientCommand"); GE_PausedTic = ED_FindFunctionOffset ("GE_PausedTic"); GE_ShouldPause = ED_FindFunctionOffset ("GE_ShouldPause"); // leave slots at start for clients only sv.num_edicts = MAX_CLIENTS+1; for (i=0 ; i<MAX_CLIENTS ; i++) { ent = EDICT_NUM(i+1); // restore client name. ent->v.netname = PR_SetString(svs.clients[i].name); // reserve edict. svs.clients[i].edict = ent; //ZOID - make sure we update frags right svs.clients[i].old_frags = 0; } // fill sv.mapname and sv.modelname with new map name strlcpy (sv.mapname, mapname, sizeof(sv.mapname)); snprintf (sv.modelname, sizeof(sv.modelname), "maps/%s.bsp", sv.mapname); #ifndef SERVERONLY // set cvar Cvar_ForceSet (&host_mapname, mapname); #endif if (!(sv.worldmodel = CM_LoadMap (sv.modelname, false, &sv.map_checksum, &sv.map_checksum2))) // true if bad map { Con_Printf ("Cant load map %s, falling back to %s\n", mapname, oldmap); // fill mapname, sv.mapname and sv.modelname with old map name strlcpy (sv.mapname, oldmap, sizeof(sv.mapname)); snprintf (sv.modelname, sizeof(sv.modelname), "maps/%s.bsp", sv.mapname); mapname = oldmap; // and re-load old map sv.worldmodel = CM_LoadMap (sv.modelname, false, &sv.map_checksum, &sv.map_checksum2); // this should never happen if (!sv.worldmodel) SV_Error ("CM_LoadMap: bad map"); } sv.map_checksum2 = Com_TranslateMapChecksum (sv.mapname, sv.map_checksum2); SV_ClearWorld (); // clear physics interaction links #ifdef USE_PR2 if ( sv_vm ) { sv.sound_precache[0] = ""; sv.model_precache[0] = ""; } else #endif { sv.sound_precache[0] = pr_strings; sv.model_precache[0] = pr_strings; } sv.model_precache[1] = sv.modelname; sv.models[1] = sv.worldmodel; for (i=1 ; i< CM_NumInlineModels() ; i++) { sv.model_precache[1+i] = localmodels[i]; sv.models[i+1] = CM_InlineModel (localmodels[i]); } //check player/eyes models for hacks sv.model_player_checksum = SV_CheckModel("progs/player.mdl"); sv.model_newplayer_checksum = SV_CheckModel("progs/newplayer.mdl"); sv.eyes_player_checksum = SV_CheckModel("progs/eyes.mdl"); // // spawn the rest of the entities on the map // // precache and static commands can be issued during // map initialization sv.state = ss_loading; #ifndef SERVERONLY com_serveractive = true; #endif ent = EDICT_NUM(0); ent->e->free = false; ent->v.model = PR_SetString(sv.modelname); ent->v.modelindex = 1; // world model ent->v.solid = SOLID_BSP; ent->v.movetype = MOVETYPE_PUSH; // information about the server ent->v.netname = PR_SetString(VersionStringFull()); ent->v.targetname = PR_SetString(SERVER_NAME); ent->v.impulse = VERSION_NUM; ent->v.items = pr_numbuiltins - 1; PR_GLOBAL(mapname) = PR_SetString(sv.mapname); // serverflags are for cross level information (sigils) PR_GLOBAL(serverflags) = svs.serverflags; if (pr_nqprogs) { pr_globals[35] = deathmatch.value; pr_globals[36] = coop.value; pr_globals[37] = teamplay.value; NQP_Reset (); } if (pr_nqprogs) { // register the cvars that NetQuake provides for mod use const char **var, *nqcvars[] = {"gamecfg", "scratch1", "scratch2", "scratch3", "scratch4", "saved1", "saved2", "saved3", "saved4", "savedgamecfg", "temp1", NULL}; for (var = nqcvars; *var; var++) Cvar_Create((char *)/*stupid const warning*/ *var, "0", 0); } // run the frame start qc function to let progs check cvars if (!pr_nqprogs) SV_ProgStartFrame (); // ********* External Entity support (.ent file(s) in gamedir/maps) pinched from ZQuake ********* // load and spawn all other entities entitystring = NULL; if ((int)sv_loadentfiles.value) { char ent_path[1024] = {0}; if (!entityfile || !entityfile[0]) entityfile = sv.mapname; // first try maps/sv_loadentfiles_dir/ if (sv_loadentfiles_dir.string[0]) { snprintf(ent_path, sizeof(ent_path), "maps/%s/%s.ent", sv_loadentfiles_dir.string, entityfile); entitystring = (char *) FS_LoadHunkFile(ent_path, NULL); } // try maps/ if not loaded yet. if (!entitystring) { snprintf(ent_path, sizeof(ent_path), "maps/%s.ent", entityfile); entitystring = (char *) FS_LoadHunkFile(ent_path, NULL); } if (entitystring) { Con_DPrintf ("Using entfile %s\n", ent_path); } } if (!entitystring) { entitystring = CM_EntityString(); } PR_LoadEnts(entitystring); // ********* End of External Entity support code ********* // look up some model indexes for specialized message compression SV_FindModelNumbers (); // all spawning is completed, any further precache statements // or prog writes to the signon message are errors sv.state = ss_active; // run two frames to allow everything to settle SV_Physics (); sv.time += 0.1; SV_Physics (); sv.time += 0.1; sv.old_time = sv.time; // save movement vars SV_SetMoveVars(); // create a baseline for more efficient communications SV_CreateBaseline (); sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize; Info_SetValueForKey (svs.info, "map", sv.mapname, MAX_SERVERINFO_STRING); // calltimeofday. { extern void PF_calltimeofday (void); pr_global_struct->time = sv.time; pr_global_struct->self = 0; PF_calltimeofday(); } Con_DPrintf ("Server spawned.\n"); // we change map - clear whole demo struct and sent initial state to all dest if any (for QTV only I thought) SV_MVD_Record(NULL, true); #ifndef SERVERONLY CL_ClearState (); #endif }