X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=host_cmd.c;h=10012cc9586d49fed0471cf9a8d404e16a8e1511;hb=ef1593610d977fe10d1f9225ab4f9111b02ef3fc;hp=b60af2164b63410b49f7641ca28c429cb13f98da;hpb=ce866fba439c8d4df9d4f0cc9f9fb8d1e5937351;p=xonotic%2Fdarkplaces.git diff --git a/host_cmd.c b/host_cmd.c index b60af216..10012cc9 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sv_demo.h" #include "image.h" +#include "prvm_cmds.h" #include "utf8lib.h" // for secure rcon authentication @@ -67,14 +68,16 @@ void Host_Quit_f (void) Host_Status_f ================== */ -void Host_Status_f (void) +static void Host_Status_f (void) { + prvm_prog_t *prog = SVVM_prog; char qcstatus[256]; client_t *client; int seconds = 0, minutes = 0, hours = 0, i, j, k, in, players, ping = 0, packetloss = 0; void (*print) (const char *fmt, ...); char ip[48]; // can contain a full length v6 address with [] and a port int frags; + char vabuf[1024]; if (cmd_source == src_command) { @@ -91,10 +94,7 @@ void Host_Status_f (void) if (!sv.active) return; - - if(cmd_source == src_command) - SV_VM_Begin(); - + in = 0; if (Cmd_Argc() == 2) { @@ -108,10 +108,10 @@ void Host_Status_f (void) if (svs.clients[i].active) players++; print ("host: %s\n", Cvar_VariableString ("hostname")); - print ("version: %s build %s\n", gamename, buildstring); + print ("version: %s build %s (gamename %s)\n", gamename, buildstring, gamenetworkfiltername); print ("protocol: %i (%s)\n", Protocol_NumberForEnum(sv.protocol), Protocol_NameForEnum(sv.protocol)); print ("map: %s\n", sv.name); - print ("timing: %s\n", Host_TimingReport()); + print ("timing: %s\n", Host_TimingReport(vabuf, sizeof(vabuf))); print ("players: %i active (%i max)\n\n", players, svs.maxclients); if (in == 1) @@ -159,7 +159,7 @@ void Host_Status_f (void) if(sv_status_show_qcstatus.integer) { prvm_edict_t *ed = PRVM_EDICT_NUM(i + 1); - const char *str = PRVM_GetString(PRVM_serveredictstring(ed, clientstatus)); + const char *str = PRVM_GetString(prog, PRVM_serveredictstring(ed, clientstatus)); if(str && *str) { char *p; @@ -198,9 +198,6 @@ void Host_Status_f (void) print ("%s%-47s #%-3u ^7%s\n", k%2 ? "^3" : "^7", ip, i+1, client->name); } } - - if(cmd_source == src_command) - SV_VM_End(); } @@ -211,8 +208,9 @@ Host_God_f Sets client to godmode ================== */ -void Host_God_f (void) +static void Host_God_f (void) { + prvm_prog_t *prog = SVVM_prog; if (!allowcheats) { SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n"); @@ -226,8 +224,9 @@ void Host_God_f (void) SV_ClientPrint("godmode ON\n"); } -void Host_Notarget_f (void) +static void Host_Notarget_f (void) { + prvm_prog_t *prog = SVVM_prog; if (!allowcheats) { SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n"); @@ -243,8 +242,9 @@ void Host_Notarget_f (void) qboolean noclip_anglehack; -void Host_Noclip_f (void) +static void Host_Noclip_f (void) { + prvm_prog_t *prog = SVVM_prog; if (!allowcheats) { SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n"); @@ -272,8 +272,9 @@ Host_Fly_f Sets client to flymode ================== */ -void Host_Fly_f (void) +static void Host_Fly_f (void) { + prvm_prog_t *prog = SVVM_prog; if (!allowcheats) { SV_ClientPrint("No cheats allowed, use sv_cheats 1 and restart level to enable.\n"); @@ -300,7 +301,7 @@ Host_Ping_f ================== */ void Host_Pings_f (void); // called by Host_Ping_f -void Host_Ping_f (void) +static void Host_Ping_f (void) { int i; client_t *client; @@ -352,7 +353,7 @@ map command from the console. Active clients are kicked off. ====================== */ -void Host_Map_f (void) +static void Host_Map_f (void) { char level[MAX_QPATH]; @@ -379,9 +380,11 @@ void Host_Map_f (void) svs.clients = (client_t *)Mem_Alloc(sv_mempool, sizeof(client_t) * svs.maxclients); } +#ifdef CONFIG_MENU // remove menu if (key_dest == key_menu || key_dest == key_menu_grabbed) MR_ToggleMenu(0); +#endif key_dest = key_game; svs.serverflags = 0; // haven't completed an episode yet @@ -399,7 +402,7 @@ Host_Changelevel_f Goes to a new map, taking all clients along ================== */ -void Host_Changelevel_f (void) +static void Host_Changelevel_f (void) { char level[MAX_QPATH]; @@ -414,14 +417,14 @@ void Host_Changelevel_f (void) return; } +#ifdef CONFIG_MENU // remove menu if (key_dest == key_menu || key_dest == key_menu_grabbed) MR_ToggleMenu(0); +#endif key_dest = key_game; - SV_VM_Begin(); SV_SaveSpawnparms (); - SV_VM_End(); allowcheats = sv_cheats.integer != 0; strlcpy(level, Cmd_Argv(1), sizeof(level)); SV_SpawnServer(level); @@ -436,7 +439,7 @@ Host_Restart_f Restarts the current server for a dead player ================== */ -void Host_Restart_f (void) +static void Host_Restart_f (void) { char mapname[MAX_QPATH]; @@ -451,9 +454,11 @@ void Host_Restart_f (void) return; } +#ifdef CONFIG_MENU // remove menu if (key_dest == key_menu || key_dest == key_menu_grabbed) MR_ToggleMenu(0); +#endif key_dest = key_game; allowcheats = sv_cheats.integer != 0; @@ -526,7 +531,7 @@ Host_Connect_f User command to connect to server ===================== */ -void Host_Connect_f (void) +static void Host_Connect_f (void) { if (Cmd_Argc() < 2) { @@ -550,10 +555,10 @@ LOAD / SAVE GAME #define SAVEGAME_VERSION 5 -void Host_Savegame_to (const char *name) +void Host_Savegame_to(prvm_prog_t *prog, const char *name) { qfile_t *f; - int i, k, l, lightstyles = 64; + int i, k, l, numbuffers, lightstyles = 64; char comment[SAVEGAME_COMMENT_LENGTH+1]; char line[MAX_INPUTLINE]; qboolean isserver; @@ -565,7 +570,7 @@ void Host_Savegame_to (const char *name) if (sv.lightstyles[i][0]) lightstyles = i+1; - isserver = !strcmp(PRVM_NAME, "server"); + isserver = prog == SVVM_prog; Con_Printf("Saving game to %s...\n", name); f = FS_OpenRealFile(name, "wb", false); @@ -579,9 +584,9 @@ void Host_Savegame_to (const char *name) memset(comment, 0, sizeof(comment)); if(isserver) - dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(PRVM_serveredictstring(prog->edicts, message)), (int)PRVM_serverglobalfloat(killed_monsters), (int)PRVM_serverglobalfloat(total_monsters)); + dpsnprintf(comment, sizeof(comment), "%-21.21s kills:%3i/%3i", PRVM_GetString(prog, PRVM_serveredictstring(prog->edicts, message)), (int)PRVM_serverglobalfloat(killed_monsters), (int)PRVM_serverglobalfloat(total_monsters)); else - dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", PRVM_NAME); + dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", prog->name); // convert space to _ to make stdio happy // LordHavoc: convert control characters to _ as well for (i=0 ; inum_edicts ; i++) { FS_Printf(f,"// edict %d\n", i); //Con_Printf("edict %d...\n", i); - PRVM_ED_Write (f, PRVM_EDICT_NUM(i)); + PRVM_ED_Write (prog, f, PRVM_EDICT_NUM(i)); } #if 1 @@ -643,11 +648,13 @@ void Host_Savegame_to (const char *name) FS_Printf(f,"sv.sound_precache %i %s\n", i, sv.sound_precache[i]); // darkplaces extension - save buffers - for (i = 0; i < (int)Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray); i++) + numbuffers = (int)Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray); + for (i = 0; i < numbuffers; i++) { prvm_stringbuffer_t *stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i); if(stringbuffer && (stringbuffer->flags & STRINGBUFFER_SAVED)) { + FS_Printf(f,"sv.buffer %i %i \"string\"\n", i, stringbuffer->flags & STRINGBUFFER_QCFLAGS); for(k = 0; k < stringbuffer->num_strings; k++) { if (!stringbuffer->strings[k]) @@ -698,8 +705,9 @@ void Host_Savegame_to (const char *name) Host_Savegame_f =============== */ -void Host_Savegame_f (void) +static void Host_Savegame_f (void) { + prvm_prog_t *prog = SVVM_prog; char name[MAX_QPATH]; qboolean deadflag = false; @@ -709,9 +717,7 @@ void Host_Savegame_f (void) return; } - SV_VM_Begin(); deadflag = cl.islocalgame && svs.clients[0].active && PRVM_serveredictfloat(svs.clients[0].edict, deadflag); - SV_VM_End(); if (cl.islocalgame) { @@ -746,9 +752,7 @@ void Host_Savegame_f (void) strlcpy (name, Cmd_Argv(1), sizeof (name)); FS_DefaultExtension (name, ".sav", sizeof (name)); - SV_VM_Begin(); - Host_Savegame_to(name); - SV_VM_End(); + Host_Savegame_to(prog, name); } @@ -758,8 +762,9 @@ Host_Loadgame_f =============== */ -void Host_Loadgame_f (void) +static void Host_Loadgame_f (void) { + prvm_prog_t *prog = SVVM_prog; char filename[MAX_QPATH]; char mapname[MAX_QPATH]; float time; @@ -768,12 +773,11 @@ void Host_Loadgame_f (void) const char *t; char *text; prvm_edict_t *ent; - int i, k; + int i, k, numbuffers; int entnum; int version; float spawn_parms[NUM_SPAWN_PARMS]; prvm_stringbuffer_t *stringbuffer; - size_t alloclen; if (Cmd_Argc() != 2) { @@ -790,9 +794,11 @@ void Host_Loadgame_f (void) if (cls.demoplayback) CL_Disconnect (); +#ifdef CONFIG_MENU // remove menu if (key_dest == key_menu || key_dest == key_menu_grabbed) MR_ToggleMenu(0); +#endif key_dest = key_game; cls.demonum = -1; // stop demo loop in case this fails @@ -808,7 +814,7 @@ void Host_Loadgame_f (void) Con_Printf("Host_Loadgame_f: loading version\n"); // version - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); version = atoi(com_token); if (version != SAVEGAME_VERSION) { @@ -821,15 +827,15 @@ void Host_Loadgame_f (void) Con_Printf("Host_Loadgame_f: loading description\n"); // description - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); for (i = 0;i < NUM_SPAWN_PARMS;i++) { - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); spawn_parms[i] = atof(com_token); } // skill - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); // this silliness is so we can load 1.06 save files, which have float skill values current_skill = (int)(atof(com_token) + 0.5); Cvar_SetValue ("skill", (float)current_skill); @@ -838,14 +844,14 @@ void Host_Loadgame_f (void) Con_Printf("Host_Loadgame_f: loading mapname\n"); // mapname - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); strlcpy (mapname, com_token, sizeof(mapname)); if(developer_entityparsing.integer) Con_Printf("Host_Loadgame_f: loading time\n"); // time - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); time = atof(com_token); allowcheats = sv_cheats.integer != 0; @@ -868,7 +874,6 @@ void Host_Loadgame_f (void) // load the light styles - SV_VM_Begin(); // -1 is the globals entnum = -1; @@ -876,7 +881,7 @@ void Host_Loadgame_f (void) { // light style start = t; - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); // if this is a 64 lightstyle savegame produced by Quake, stop now // we have to check this because darkplaces may save more than 64 if (com_token[0] == '{') @@ -897,7 +902,7 @@ void Host_Loadgame_f (void) for (;;) { start = t; - if (!COM_ParseToken_Simple(&t, false, false)) + if (!COM_ParseToken_Simple(&t, false, false, true)) break; if (com_token[0] == '{') { @@ -914,10 +919,10 @@ void Host_Loadgame_f (void) for (;;) { start = t; - while (COM_ParseToken_Simple(&t, false, false)) + while (COM_ParseToken_Simple(&t, false, false, true)) if (!strcmp(com_token, "}")) break; - if (!COM_ParseToken_Simple(&start, false, false)) + if (!COM_ParseToken_Simple(&start, false, false, true)) { // end of file break; @@ -934,7 +939,7 @@ void Host_Loadgame_f (void) Con_Printf("Host_Loadgame_f: loading globals\n"); // parse the global vars - PRVM_ED_ParseGlobals (start); + PRVM_ED_ParseGlobals (prog, start); // restore the autocvar globals Cvar_UpdateAllAutoCvars(); @@ -948,15 +953,15 @@ void Host_Loadgame_f (void) Host_Error("Host_PerformLoadGame: too many edicts in save file (reached MAX_EDICTS %i)", MAX_EDICTS); } while (entnum >= prog->max_edicts) - PRVM_MEM_IncreaseEdicts(); + PRVM_MEM_IncreaseEdicts(prog); ent = PRVM_EDICT_NUM(entnum); - memset(ent->fields.vp, 0, prog->entityfields * 4); + memset(ent->fields.fp, 0, prog->entityfields * sizeof(prvm_vec_t)); ent->priv.server->free = false; if(developer_entityparsing.integer) Con_Printf("Host_Loadgame_f: loading edict %d\n", entnum); - PRVM_ED_ParseEdict (start, ent); + PRVM_ED_ParseEdict (prog, start, ent); // link it into the bsp tree if (!ent->priv.server->free) @@ -993,13 +998,15 @@ void Host_Loadgame_f (void) memset(sv.lightstyles[0], 0, sizeof(sv.lightstyles)); memset(sv.model_precache[0], 0, sizeof(sv.model_precache)); memset(sv.sound_precache[0], 0, sizeof(sv.sound_precache)); - while (COM_ParseToken_Simple(&t, false, false)) + BufStr_Flush(prog); + + while (COM_ParseToken_Simple(&t, false, false, true)) { if (!strcmp(com_token, "sv.lightstyles")) { - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); i = atoi(com_token); - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); if (i >= 0 && i < MAX_LIGHTSTYLES) strlcpy(sv.lightstyles[i], com_token, sizeof(sv.lightstyles[i])); else @@ -1007,9 +1014,9 @@ void Host_Loadgame_f (void) } else if (!strcmp(com_token, "sv.model_precache")) { - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); i = atoi(com_token); - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); if (i >= 0 && i < MAX_MODELS) { strlcpy(sv.model_precache[i], com_token, sizeof(sv.model_precache[i])); @@ -1020,67 +1027,78 @@ void Host_Loadgame_f (void) } else if (!strcmp(com_token, "sv.sound_precache")) { - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); i = atoi(com_token); - COM_ParseToken_Simple(&t, false, false); + COM_ParseToken_Simple(&t, false, false, true); if (i >= 0 && i < MAX_SOUNDS) strlcpy(sv.sound_precache[i], com_token, sizeof(sv.sound_precache[i])); else Con_Printf("unsupported sound %i \"%s\"\n", i, com_token); } + else if (!strcmp(com_token, "sv.buffer")) + { + if (COM_ParseToken_Simple(&t, false, false, true)) + { + i = atoi(com_token); + if (i >= 0) + { + k = STRINGBUFFER_SAVED; + if (COM_ParseToken_Simple(&t, false, false, true)) + k |= atoi(com_token); + if (!BufStr_FindCreateReplace(prog, i, k, "string")) + Con_Printf("failed to create stringbuffer %i\n", i); + } + else + Con_Printf("unsupported stringbuffer index %i \"%s\"\n", i, com_token); + } + else + Con_Printf("unexpected end of line when parsing sv.buffer (expected buffer index)\n"); + } else if (!strcmp(com_token, "sv.bufstr")) { - COM_ParseToken_Simple(&t, false, false); - i = atoi(com_token); - COM_ParseToken_Simple(&t, false, false); - k = atoi(com_token); - COM_ParseToken_Simple(&t, false, false); - stringbuffer = (prvm_stringbuffer_t*) Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i); - // VorteX: nasty code, cleanup required - // create buffer at this index - if(!stringbuffer) - stringbuffer = (prvm_stringbuffer_t *) Mem_ExpandableArray_AllocRecordAtIndex(&prog->stringbuffersarray, i); - if (!stringbuffer) - Con_Printf("cant write string %i into buffer %i\n", k, i); + if (!COM_ParseToken_Simple(&t, false, false, true)) + Con_Printf("unexpected end of line when parsing sv.bufstr\n"); else { - // code copied from VM_bufstr_set - // expand buffer - if (stringbuffer->max_strings <= i) + i = atoi(com_token); + stringbuffer = BufStr_FindCreateReplace(prog, i, STRINGBUFFER_SAVED, "string"); + if (stringbuffer) { - char **oldstrings = stringbuffer->strings; - stringbuffer->max_strings = max(stringbuffer->max_strings * 2, 128); - while (stringbuffer->max_strings <= i) - stringbuffer->max_strings *= 2; - stringbuffer->strings = (char **) Mem_Alloc(prog->progs_mempool, stringbuffer->max_strings * sizeof(stringbuffer->strings[0])); - if (stringbuffer->num_strings > 0) - memcpy(stringbuffer->strings, oldstrings, stringbuffer->num_strings * sizeof(stringbuffer->strings[0])); - if (oldstrings) - Mem_Free(oldstrings); + if (COM_ParseToken_Simple(&t, false, false, true)) + { + k = atoi(com_token); + if (COM_ParseToken_Simple(&t, false, false, true)) + BufStr_Set(prog, stringbuffer, k, com_token); + else + Con_Printf("unexpected end of line when parsing sv.bufstr (expected string)\n"); + } + else + Con_Printf("unexpected end of line when parsing sv.bufstr (expected strindex)\n"); } - // allocate string - stringbuffer->num_strings = max(stringbuffer->num_strings, k + 1); - if(stringbuffer->strings[k]) - Mem_Free(stringbuffer->strings[k]); - stringbuffer->strings[k] = NULL; - alloclen = strlen(com_token) + 1; - stringbuffer->strings[k] = (char *)Mem_Alloc(prog->progs_mempool, alloclen); - memcpy(stringbuffer->strings[k], com_token, alloclen); + else + Con_Printf("failed to create stringbuffer %i \"%s\"\n", i, com_token); } } // skip any trailing text or unrecognized commands - while (COM_ParseToken_Simple(&t, true, false) && strcmp(com_token, "\n")) + while (COM_ParseToken_Simple(&t, true, false, true) && strcmp(com_token, "\n")) ; } } } Mem_Free(text); + // remove all temporary flagged string buffers (ones created with BufStr_FindCreateReplace) + numbuffers = (int)Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray); + for (i = 0; i < numbuffers; i++) + { + if ( (stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i)) ) + if (stringbuffer->flags & STRINGBUFFER_TEMP) + BufStr_Del(prog, stringbuffer); + } + if(developer_entityparsing.integer) Con_Printf("Host_Loadgame_f: finished\n"); - SV_VM_End(); - // make sure we're connected to loopback if (sv.active && cls.state == ca_disconnected) CL_EstablishConnection("local:1", -2); @@ -1094,8 +1112,9 @@ Host_Name_f ====================== */ cvar_t cl_name = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_name", "player", "internal storage cvar for current player name (changed by name command)"}; -void Host_Name_f (void) +static void Host_Name_f (void) { + prvm_prog_t *prog = SVVM_prog; int i, j; qboolean valid_colors; const char *newNameSource; @@ -1103,7 +1122,10 @@ void Host_Name_f (void) if (Cmd_Argc () == 1) { - Con_Printf("name: %s\n", cl_name.string); + if (cmd_source == src_command) + { + Con_Printf("name: %s\n", cl_name.string); + } return; } @@ -1201,10 +1223,10 @@ void Host_Name_f (void) if (j >= 0 && strlen(host_client->name) < sizeof(host_client->name) - 2) memcpy(host_client->name + strlen(host_client->name), STRING_COLOR_DEFAULT_STR, strlen(STRING_COLOR_DEFAULT_STR) + 1); - PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(host_client->name); + PRVM_serveredictstring(host_client->edict, netname) = PRVM_SetEngineString(prog, host_client->name); if (strcmp(host_client->old_name, host_client->name)) { - if (host_client->spawned) + if (host_client->begun) SV_BroadcastPrintf("%s ^7changed name to %s\n", host_client->old_name, host_client->name); strlcpy(host_client->old_name, host_client->name, sizeof(host_client->old_name)); // send notification to all clients @@ -1222,14 +1244,18 @@ Host_Playermodel_f */ cvar_t cl_playermodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playermodel", "", "internal storage cvar for current player model in Nexuiz/Xonotic (changed by playermodel command)"}; // the old cl_playermodel in cl_main has been renamed to __cl_playermodel -void Host_Playermodel_f (void) +static void Host_Playermodel_f (void) { + prvm_prog_t *prog = SVVM_prog; int i, j; char newPath[sizeof(host_client->playermodel)]; if (Cmd_Argc () == 1) { - Con_Printf("\"playermodel\" is \"%s\"\n", cl_playermodel.string); + if (cmd_source == src_command) + { + Con_Printf("\"playermodel\" is \"%s\"\n", cl_playermodel.string); + } return; } @@ -1261,7 +1287,7 @@ void Host_Playermodel_f (void) // point the string back at updateclient->name to keep it safe strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel)); - PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(host_client->playermodel); + PRVM_serveredictstring(host_client->edict, playermodel) = PRVM_SetEngineString(prog, host_client->playermodel); if (strcmp(host_client->old_model, host_client->playermodel)) { strlcpy(host_client->old_model, host_client->playermodel, sizeof(host_client->old_model)); @@ -1278,14 +1304,18 @@ Host_Playerskin_f ====================== */ cvar_t cl_playerskin = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_playerskin", "", "internal storage cvar for current player skin in Nexuiz/Xonotic (changed by playerskin command)"}; -void Host_Playerskin_f (void) +static void Host_Playerskin_f (void) { + prvm_prog_t *prog = SVVM_prog; int i, j; char newPath[sizeof(host_client->playerskin)]; if (Cmd_Argc () == 1) { - Con_Printf("\"playerskin\" is \"%s\"\n", cl_playerskin.string); + if (cmd_source == src_command) + { + Con_Printf("\"playerskin\" is \"%s\"\n", cl_playerskin.string); + } return; } @@ -1317,10 +1347,10 @@ void Host_Playerskin_f (void) // point the string back at updateclient->name to keep it safe strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin)); - PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(host_client->playerskin); + PRVM_serveredictstring(host_client->edict, playerskin) = PRVM_SetEngineString(prog, host_client->playerskin); if (strcmp(host_client->old_skin, host_client->playerskin)) { - //if (host_client->spawned) + //if (host_client->begun) // SV_BroadcastPrintf("%s changed skin to %s\n", host_client->name, host_client->playerskin); strlcpy(host_client->old_skin, host_client->playerskin, sizeof(host_client->old_skin)); /*// send notification to all clients @@ -1330,13 +1360,14 @@ void Host_Playerskin_f (void) } } -void Host_Version_f (void) +static void Host_Version_f (void) { Con_Printf("Version: %s build %s\n", gamename, buildstring); } -void Host_Say(qboolean teamonly) +static void Host_Say(qboolean teamonly) { + prvm_prog_t *prog = SVVM_prog; client_t *save; int j, quoted; const char *p1; @@ -1403,19 +1434,19 @@ void Host_Say(qboolean teamonly) } -void Host_Say_f(void) +static void Host_Say_f(void) { Host_Say(false); } -void Host_Say_Team_f(void) +static void Host_Say_Team_f(void) { Host_Say(true); } -void Host_Tell_f(void) +static void Host_Tell_f(void) { const char *playername_start = NULL; size_t playername_length = 0; @@ -1550,8 +1581,9 @@ Host_Color_f ================== */ cvar_t cl_color = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_color", "0", "internal storage cvar for current player colors (changed by color command)"}; -void Host_Color(int changetop, int changebottom) +static void Host_Color(int changetop, int changebottom) { + prvm_prog_t *prog = SVVM_prog; int top, bottom, playercolor; // get top and bottom either from the provided values or the current values @@ -1581,10 +1613,10 @@ void Host_Color(int changetop, int changebottom) if (host_client->edict && PRVM_serverfunction(SV_ChangeTeam)) { Con_DPrint("Calling SV_ChangeTeam\n"); + prog->globals.fp[OFS_PARM0] = playercolor; PRVM_serverglobalfloat(time) = sv.time; - prog->globals.generic[OFS_PARM0] = playercolor; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram(PRVM_serverfunction(SV_ChangeTeam), "QC function SV_ChangeTeam is missing"); + prog->ExecuteProgram(prog, PRVM_serverfunction(SV_ChangeTeam), "QC function SV_ChangeTeam is missing"); } else { @@ -1605,14 +1637,17 @@ void Host_Color(int changetop, int changebottom) } } -void Host_Color_f(void) +static void Host_Color_f(void) { int top, bottom; if (Cmd_Argc() == 1) { - Con_Printf("\"color\" is \"%i %i\"\n", cl_color.integer >> 4, cl_color.integer & 15); - Con_Print("color <0-15> [0-15]\n"); + if (cmd_source == src_command) + { + Con_Printf("\"color\" is \"%i %i\"\n", cl_color.integer >> 4, cl_color.integer & 15); + Con_Print("color <0-15> [0-15]\n"); + } return; } @@ -1626,24 +1661,30 @@ void Host_Color_f(void) Host_Color(top, bottom); } -void Host_TopColor_f(void) +static void Host_TopColor_f(void) { if (Cmd_Argc() == 1) { - Con_Printf("\"topcolor\" is \"%i\"\n", (cl_color.integer >> 4) & 15); - Con_Print("topcolor <0-15>\n"); + if (cmd_source == src_command) + { + Con_Printf("\"topcolor\" is \"%i\"\n", (cl_color.integer >> 4) & 15); + Con_Print("topcolor <0-15>\n"); + } return; } Host_Color(atoi(Cmd_Argv(1)), -1); } -void Host_BottomColor_f(void) +static void Host_BottomColor_f(void) { if (Cmd_Argc() == 1) { - Con_Printf("\"bottomcolor\" is \"%i\"\n", cl_color.integer & 15); - Con_Print("bottomcolor <0-15>\n"); + if (cmd_source == src_command) + { + Con_Printf("\"bottomcolor\" is \"%i\"\n", cl_color.integer & 15); + Con_Print("bottomcolor <0-15>\n"); + } return; } @@ -1651,14 +1692,18 @@ void Host_BottomColor_f(void) } cvar_t cl_rate = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_rate", "20000", "internal storage cvar for current rate (changed by rate command)"}; -void Host_Rate_f(void) +cvar_t cl_rate_burstsize = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_rate_burstsize", "1024", "internal storage cvar for current rate control burst size (changed by rate_burstsize command)"}; +static void Host_Rate_f(void) { int rate; if (Cmd_Argc() != 2) { - Con_Printf("\"rate\" is \"%i\"\n", cl_rate.integer); - Con_Print("rate \n"); + if (cmd_source == src_command) + { + Con_Printf("\"rate\" is \"%i\"\n", cl_rate.integer); + Con_Print("rate \n"); + } return; } @@ -1672,14 +1717,36 @@ void Host_Rate_f(void) host_client->rate = rate; } +static void Host_Rate_BurstSize_f(void) +{ + int rate_burstsize; + + if (Cmd_Argc() != 2) + { + Con_Printf("\"rate_burstsize\" is \"%i\"\n", cl_rate_burstsize.integer); + Con_Print("rate_burstsize \n"); + return; + } + + rate_burstsize = atoi(Cmd_Argv(1)); + + if (cmd_source == src_command) + { + Cvar_SetValue ("_cl_rate_burstsize", rate_burstsize); + return; + } + + host_client->rate_burstsize = rate_burstsize; +} /* ================== Host_Kill_f ================== */ -void Host_Kill_f (void) +static void Host_Kill_f (void) { + prvm_prog_t *prog = SVVM_prog; if (PRVM_serveredictfloat(host_client->edict, health) <= 0) { SV_ClientPrint("Can't suicide -- already dead!\n"); @@ -1688,7 +1755,7 @@ void Host_Kill_f (void) PRVM_serverglobalfloat(time) = sv.time; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram (PRVM_serverfunction(ClientKill), "QC function ClientKill is missing"); + prog->ExecuteProgram(prog, PRVM_serverfunction(ClientKill), "QC function ClientKill is missing"); } @@ -1697,18 +1764,44 @@ void Host_Kill_f (void) Host_Pause_f ================== */ -void Host_Pause_f (void) +static void Host_Pause_f (void) { - if (!pausable.integer) - SV_ClientPrint("Pause not allowed.\n"); + void (*print) (const char *fmt, ...); + if (cmd_source == src_command) + { + // if running a client, try to send over network so the pause is handled by the server + if (cls.state == ca_connected) + { + Cmd_ForwardToServer (); + return; + } + print = Con_Printf; + } else + print = SV_ClientPrintf; + + if (!pausable.integer) { - sv.paused ^= 1; - SV_BroadcastPrintf("%s %spaused the game\n", host_client->name, sv.paused ? "" : "un"); - // send notification to all clients - MSG_WriteByte(&sv.reliable_datagram, svc_setpause); - MSG_WriteByte(&sv.reliable_datagram, sv.paused); + if (cmd_source == src_client) + { + if(cls.state == ca_dedicated || host_client != &svs.clients[0]) // non-admin + { + print("Pause not allowed.\n"); + return; + } + } } + + sv.paused ^= 1; + if (cmd_source != src_command) + SV_BroadcastPrintf("%s %spaused the game\n", host_client->name, sv.paused ? "" : "un"); + else if(*(sv_adminnick.string)) + SV_BroadcastPrintf("%s %spaused the game\n", sv_adminnick.string, sv.paused ? "" : "un"); + else + SV_BroadcastPrintf("%s %spaused the game\n", hostname.string, sv.paused ? "" : "un"); + // send notification to all clients + MSG_WriteByte(&sv.reliable_datagram, svc_setpause); + MSG_WriteByte(&sv.reliable_datagram, sv.paused); } /* @@ -1721,11 +1814,15 @@ LordHavoc: correction, Mindcrime will be removing pmodel in the future, but it's cvar_t cl_pmodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_pmodel", "0", "internal storage cvar for current player model number in nehahra (changed by pmodel command)"}; static void Host_PModel_f (void) { + prvm_prog_t *prog = SVVM_prog; int i; if (Cmd_Argc () == 1) { - Con_Printf("\"pmodel\" is \"%s\"\n", cl_pmodel.string); + if (cmd_source == src_command) + { + Con_Printf("\"pmodel\" is \"%s\"\n", cl_pmodel.string); + } return; } i = atoi(Cmd_Argv(1)); @@ -1751,13 +1848,14 @@ static void Host_PModel_f (void) Host_PreSpawn_f ================== */ -void Host_PreSpawn_f (void) +static void Host_PreSpawn_f (void) { - if (host_client->spawned) + if (host_client->prespawned) { - Con_Print("prespawn not valid -- already spawned\n"); + Con_Print("prespawn not valid -- already prespawned\n"); return; } + host_client->prespawned = true; if (host_client->netconnection) { @@ -1776,17 +1874,24 @@ void Host_PreSpawn_f (void) Host_Spawn_f ================== */ -void Host_Spawn_f (void) +static void Host_Spawn_f (void) { + prvm_prog_t *prog = SVVM_prog; int i; client_t *client; int stats[MAX_CL_STATS]; + if (!host_client->prespawned) + { + Con_Print("Spawn not valid -- not yet prespawned\n"); + return; + } if (host_client->spawned) { Con_Print("Spawn not valid -- already spawned\n"); return; } + host_client->spawned = true; // reset name change timer again because they might want to change name // again in the first 5 seconds after connecting @@ -1806,7 +1911,7 @@ void Host_Spawn_f (void) Con_DPrint("Calling RestoreGame\n"); PRVM_serverglobalfloat(time) = sv.time; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram(PRVM_serverfunction(RestoreGame), "QC function RestoreGame is missing"); + prog->ExecuteProgram(prog, PRVM_serverfunction(RestoreGame), "QC function RestoreGame is missing"); } } else @@ -1821,12 +1926,13 @@ void Host_Spawn_f (void) host_client->clientconnectcalled = true; PRVM_serverglobalfloat(time) = sv.time; PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict); - PRVM_ExecuteProgram (PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing"); + prog->ExecuteProgram(prog, PRVM_serverfunction(ClientConnect), "QC function ClientConnect is missing"); if (cls.state == ca_dedicated) Con_Printf("%s connected\n", host_client->name); - PRVM_ExecuteProgram (PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing"); + PRVM_serverglobalfloat(time) = sv.time; + prog->ExecuteProgram(prog, PRVM_serverfunction(PutClientInServer), "QC function PutClientInServer is missing"); } if (!host_client->netconnection) @@ -1911,9 +2017,19 @@ void Host_Spawn_f (void) Host_Begin_f ================== */ -void Host_Begin_f (void) +static void Host_Begin_f (void) { - host_client->spawned = true; + if (!host_client->spawned) + { + Con_Print("Begin not valid -- not yet spawned\n"); + return; + } + if (host_client->begun) + { + Con_Print("Begin not valid -- already begun\n"); + return; + } + host_client->begun = true; // LordHavoc: note: this code also exists in SV_DropClient if (sv.loadgame) @@ -1940,7 +2056,7 @@ Host_Kick_f Kicks a user off of the server ================== */ -void Host_Kick_f (void) +static void Host_Kick_f (void) { const char *who; const char *message = NULL; @@ -1951,7 +2067,6 @@ void Host_Kick_f (void) if (!sv.active) return; - SV_VM_Begin(); save = host_client; if (Cmd_Argc() > 2 && strcmp(Cmd_Argv(1), "#") == 0) @@ -1991,7 +2106,7 @@ void Host_Kick_f (void) if (Cmd_Argc() > 2) { message = Cmd_Args(); - COM_ParseToken_Simple(&message, false, false); + COM_ParseToken_Simple(&message, false, false, true); if (byNumber) { message++; // skip the # @@ -2010,7 +2125,6 @@ void Host_Kick_f (void) } host_client = save; - SV_VM_End(); } /* @@ -2026,8 +2140,9 @@ DEBUGGING TOOLS Host_Give_f ================== */ -void Host_Give_f (void) +static void Host_Give_f (void) { + prvm_prog_t *prog = SVVM_prog; const char *t; int v; @@ -2053,7 +2168,7 @@ void Host_Give_f (void) case '8': case '9': // MED 01/04/97 added hipnotic give stuff - if (gamemode == GAME_HIPNOTIC) + if (gamemode == GAME_HIPNOTIC || gamemode == GAME_QUOTH) { if (t[0] == '6') { @@ -2148,7 +2263,7 @@ void Host_Give_f (void) } } -prvm_edict_t *FindViewthing (void) +static prvm_edict_t *FindViewthing(prvm_prog_t *prog) { int i; prvm_edict_t *e; @@ -2156,7 +2271,7 @@ prvm_edict_t *FindViewthing (void) for (i=0 ; inum_edicts ; i++) { e = PRVM_EDICT_NUM(i); - if (!strcmp (PRVM_GetString(PRVM_serveredictstring(e, classname)), "viewthing")) + if (!strcmp (PRVM_GetString(prog, PRVM_serveredictstring(e, classname)), "viewthing")) return e; } Con_Print("No viewthing on map\n"); @@ -2168,29 +2283,27 @@ prvm_edict_t *FindViewthing (void) Host_Viewmodel_f ================== */ -void Host_Viewmodel_f (void) +static void Host_Viewmodel_f (void) { + prvm_prog_t *prog = SVVM_prog; prvm_edict_t *e; dp_model_t *m; if (!sv.active) return; - SV_VM_Begin(); - e = FindViewthing (); - SV_VM_End(); - if (!e) - return; - - m = Mod_ForName (Cmd_Argv(1), false, true, NULL); - if (!m || !m->loaded || !m->Draw) + e = FindViewthing(prog); + if (e) { - Con_Printf("viewmodel: can't load %s\n", Cmd_Argv(1)); - return; + m = Mod_ForName (Cmd_Argv(1), false, true, NULL); + if (m && m->loaded && m->Draw) + { + PRVM_serveredictfloat(e, frame) = 0; + cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)] = m; + } + else + Con_Printf("viewmodel: can't load %s\n", Cmd_Argv(1)); } - - PRVM_serveredictfloat(e, frame) = 0; - cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)] = m; } /* @@ -2198,8 +2311,9 @@ void Host_Viewmodel_f (void) Host_Viewframe_f ================== */ -void Host_Viewframe_f (void) +static void Host_Viewframe_f (void) { + prvm_prog_t *prog = SVVM_prog; prvm_edict_t *e; int f; dp_model_t *m; @@ -2207,22 +2321,21 @@ void Host_Viewframe_f (void) if (!sv.active) return; - SV_VM_Begin(); - e = FindViewthing (); - SV_VM_End(); - if (!e) - return; - m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; + e = FindViewthing(prog); + if (e) + { + m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; - f = atoi(Cmd_Argv(1)); - if (f >= m->numframes) - f = m->numframes-1; + f = atoi(Cmd_Argv(1)); + if (f >= m->numframes) + f = m->numframes-1; - PRVM_serveredictfloat(e, frame) = f; + PRVM_serveredictfloat(e, frame) = f; + } } -void PrintFrameName (dp_model_t *m, int frame) +static void PrintFrameName (dp_model_t *m, int frame) { if (m->animscenes) Con_Printf("frame %i: %s\n", frame, m->animscenes[frame].name); @@ -2235,26 +2348,26 @@ void PrintFrameName (dp_model_t *m, int frame) Host_Viewnext_f ================== */ -void Host_Viewnext_f (void) +static void Host_Viewnext_f (void) { + prvm_prog_t *prog = SVVM_prog; prvm_edict_t *e; dp_model_t *m; if (!sv.active) return; - SV_VM_Begin(); - e = FindViewthing (); - SV_VM_End(); - if (!e) - return; - m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; + e = FindViewthing(prog); + if (e) + { + m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; - PRVM_serveredictfloat(e, frame) = PRVM_serveredictfloat(e, frame) + 1; - if (PRVM_serveredictfloat(e, frame) >= m->numframes) - PRVM_serveredictfloat(e, frame) = m->numframes - 1; + PRVM_serveredictfloat(e, frame) = PRVM_serveredictfloat(e, frame) + 1; + if (PRVM_serveredictfloat(e, frame) >= m->numframes) + PRVM_serveredictfloat(e, frame) = m->numframes - 1; - PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame)); + PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame)); + } } /* @@ -2262,27 +2375,26 @@ void Host_Viewnext_f (void) Host_Viewprev_f ================== */ -void Host_Viewprev_f (void) +static void Host_Viewprev_f (void) { + prvm_prog_t *prog = SVVM_prog; prvm_edict_t *e; dp_model_t *m; if (!sv.active) return; - SV_VM_Begin(); - e = FindViewthing (); - SV_VM_End(); - if (!e) - return; - - m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; + e = FindViewthing(prog); + if (e) + { + m = cl.model_precache[(int)PRVM_serveredictfloat(e, modelindex)]; - PRVM_serveredictfloat(e, frame) = PRVM_serveredictfloat(e, frame) - 1; - if (PRVM_serveredictfloat(e, frame) < 0) - PRVM_serveredictfloat(e, frame) = 0; + PRVM_serveredictfloat(e, frame) = PRVM_serveredictfloat(e, frame) - 1; + if (PRVM_serveredictfloat(e, frame) < 0) + PRVM_serveredictfloat(e, frame) = 0; - PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame)); + PrintFrameName (m, (int)PRVM_serveredictfloat(e, frame)); + } } /* @@ -2299,7 +2411,7 @@ DEMO LOOP CONTROL Host_Startdemos_f ================== */ -void Host_Startdemos_f (void) +static void Host_Startdemos_f (void) { int i, c; @@ -2338,7 +2450,7 @@ Host_Demos_f Return to looping demos ================== */ -void Host_Demos_f (void) +static void Host_Demos_f (void) { if (cls.state == ca_dedicated) return; @@ -2355,7 +2467,7 @@ Host_Stopdemo_f Return to looping demos ================== */ -void Host_Stopdemo_f (void) +static void Host_Stopdemo_f (void) { if (!cls.demoplayback) return; @@ -2363,12 +2475,13 @@ void Host_Stopdemo_f (void) Host_ShutdownServer (); } -void Host_SendCvar_f (void) +static void Host_SendCvar_f (void) { int i; cvar_t *c; const char *cvarname; client_t *old; + char vabuf[1024]; if(Cmd_Argc() != 2) return; @@ -2379,9 +2492,9 @@ void Host_SendCvar_f (void) // LordHavoc: if there is no such cvar or if it is private, send a // reply indicating that it has no value if(!c || (c->flags & CVAR_PRIVATE)) - Cmd_ForwardStringToServer(va("sentcvar %s", cvarname)); + Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s", cvarname)); else - Cmd_ForwardStringToServer(va("sentcvar %s \"%s\"", c->name, c->string)); + Cmd_ForwardStringToServer(va(vabuf, sizeof(vabuf), "sentcvar %s \"%s\"", c->name, c->string)); return; } if(!sv.active)// || !PRVM_serverfunction(SV_ParseClientCommand)) @@ -2435,7 +2548,7 @@ Host_PQRcon_f ProQuake rcon support ===================== */ -void Host_PQRcon_f (void) +static void Host_PQRcon_f (void) { int n; const char *e; @@ -2443,6 +2556,12 @@ void Host_PQRcon_f (void) lhnetsocket_t *mysocket; char peer_address[64]; + if (Cmd_Argc() == 1) + { + Con_Printf("%s: Usage: %s command\n", Cmd_Argv(0), Cmd_Argv(0)); + return; + } + if (!rcon_password.string || !rcon_password.string[0] || rcon_secure.integer > 0) { Con_Printf ("You must set rcon_password before issuing an pqrcon command, and rcon_secure must be 0.\n"); @@ -2469,15 +2588,18 @@ void Host_PQRcon_f (void) mysocket = NetConn_ChooseClientSocketForAddress(&to); if (mysocket) { - SZ_Clear(&net_message); - MSG_WriteLong (&net_message, 0); - MSG_WriteByte (&net_message, CCREQ_RCON); - SZ_Write(&net_message, (const unsigned char*)rcon_password.string, n); - MSG_WriteByte (&net_message, 0); // terminate the (possibly partial) string - MSG_WriteString (&net_message, Cmd_Args()); - StoreBigLong(net_message.data, NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - NetConn_Write(mysocket, net_message.data, net_message.cursize, &to); - SZ_Clear (&net_message); + sizebuf_t buf; + unsigned char bufdata[64]; + buf.data = bufdata; + SZ_Clear(&buf); + MSG_WriteLong(&buf, 0); + MSG_WriteByte(&buf, CCREQ_RCON); + SZ_Write(&buf, (const unsigned char*)rcon_password.string, n); + MSG_WriteByte(&buf, 0); // terminate the (possibly partial) string + MSG_WriteString(&buf, Cmd_Args()); + StoreBigLong(buf.data, NETFLAG_CTL | (buf.cursize & NETFLAG_LENGTH_MASK)); + NetConn_Write(mysocket, buf.data, buf.cursize, &to); + SZ_Clear(&buf); } } @@ -2493,12 +2615,19 @@ Host_Rcon_f an unconnected command. ===================== */ -void Host_Rcon_f (void) // credit: taken from QuakeWorld +static void Host_Rcon_f (void) // credit: taken from QuakeWorld { int i, n; const char *e; lhnetaddress_t to; lhnetsocket_t *mysocket; + char vabuf[1024]; + + if (Cmd_Argc() == 1) + { + Con_Printf("%s: Usage: %s command\n", Cmd_Argv(0), Cmd_Argv(0)); + return; + } if (!rcon_password.string || !rcon_password.string[0]) { @@ -2552,16 +2681,16 @@ void Host_Rcon_f (void) // credit: taken from QuakeWorld char argbuf[1500]; dpsnprintf(argbuf, sizeof(argbuf), "%ld.%06d %s", (long) time(NULL), (int) (rand() % 1000000), Cmd_Args()); memcpy(buf, "\377\377\377\377srcon HMAC-MD4 TIME ", 24); - if(HMAC_MDFOUR_16BYTES((unsigned char *) (buf + 24), (unsigned char *) argbuf, strlen(argbuf), (unsigned char *) rcon_password.string, n)) + if(HMAC_MDFOUR_16BYTES((unsigned char *) (buf + 24), (unsigned char *) argbuf, (int)strlen(argbuf), (unsigned char *) rcon_password.string, n)) { buf[40] = ' '; strlcpy(buf + 41, argbuf, sizeof(buf) - 41); - NetConn_Write(mysocket, buf, 41 + strlen(buf + 41), &to); + NetConn_Write(mysocket, buf, 41 + (int)strlen(buf + 41), &to); } } else { - NetConn_WriteString(mysocket, va("\377\377\377\377rcon %.*s %s", n, rcon_password.string, Cmd_Args()), &to); + NetConn_WriteString(mysocket, va(vabuf, sizeof(vabuf), "\377\377\377\377rcon %.*s %s", n, rcon_password.string, Cmd_Args()), &to); } } } @@ -2575,7 +2704,7 @@ user Dump userdata / masterdata for a user ==================== */ -void Host_User_f (void) // credit: taken from QuakeWorld +static void Host_User_f (void) // credit: taken from QuakeWorld { int uid; int i; @@ -2608,7 +2737,7 @@ Host_Users_f Dump userids for all current players ==================== */ -void Host_Users_f (void) // credit: taken from QuakeWorld +static void Host_Users_f (void) // credit: taken from QuakeWorld { int i; int c; @@ -2636,7 +2765,7 @@ Sent by server when serverinfo changes ================== */ // TODO: shouldn't this be a cvar instead? -void Host_FullServerinfo_f (void) // credit: taken from QuakeWorld +static void Host_FullServerinfo_f (void) // credit: taken from QuakeWorld { char temp[512]; if (Cmd_Argc() != 2) @@ -2658,11 +2787,10 @@ Allow clients to change userinfo ================== Casey was here :) */ -void Host_FullInfo_f (void) // credit: taken from QuakeWorld +static void Host_FullInfo_f (void) // credit: taken from QuakeWorld { char key[512]; char value[512]; - char *o; const char *s; if (Cmd_Argc() != 2) @@ -2676,27 +2804,33 @@ void Host_FullInfo_f (void) // credit: taken from QuakeWorld s++; while (*s) { - o = key; - while (*s && *s != '\\') - *o++ = *s++; - *o = 0; - + size_t len = strcspn(s, "\\"); + if (len >= sizeof(key)) { + len = sizeof(key) - 1; + } + strlcpy(key, s, len + 1); + s += len; if (!*s) { Con_Printf ("MISSING VALUE\n"); return; } + ++s; // Skip over backslash. - o = value; - s++; - while (*s && *s != '\\') - *o++ = *s++; - *o = 0; - - if (*s) - s++; + len = strcspn(s, "\\"); + if (len >= sizeof(value)) { + len = sizeof(value) - 1; + } + strlcpy(value, s, len + 1); CL_SetInfo(key, value, false, false, false, false); + + s += len; + if (!*s) + { + break; + } + ++s; // Skip over backslash. } } @@ -2707,7 +2841,7 @@ CL_SetInfo_f Allow clients to change userinfo ================== */ -void Host_SetInfo_f (void) // credit: taken from QuakeWorld +static void Host_SetInfo_f (void) // credit: taken from QuakeWorld { if (Cmd_Argc() == 1) { @@ -2731,7 +2865,7 @@ packet Contents allows \n escape character ==================== */ -void Host_Packet_f (void) // credit: taken from QuakeWorld +static void Host_Packet_f (void) // credit: taken from QuakeWorld { char send[2048]; int i, l; @@ -2856,7 +2990,7 @@ void Host_Pings_f (void) MSG_WriteString(&host_client->netconnection->message, "\n"); } -void Host_PingPLReport_f(void) +static void Host_PingPLReport_f(void) { char *errbyte; int i; @@ -2902,7 +3036,7 @@ void Host_InitCommands (void) Cmd_AddCommand_WithClientCommand ("say_team", Host_Say_Team_f, Host_Say_Team_f, "send a chat message to your team on the server"); Cmd_AddCommand_WithClientCommand ("tell", Host_Tell_f, Host_Tell_f, "send a chat message to only one person on the server"); Cmd_AddCommand_WithClientCommand ("kill", NULL, Host_Kill_f, "die instantly"); - Cmd_AddCommand_WithClientCommand ("pause", NULL, Host_Pause_f, "pause the game (if the server allows pausing)"); + Cmd_AddCommand_WithClientCommand ("pause", Host_Pause_f, Host_Pause_f, "pause the game (if the server allows pausing)"); Cmd_AddCommand ("kick", Host_Kick_f, "kick a player off the server by number or name"); Cmd_AddCommand_WithClientCommand ("ping", Host_Ping_f, Host_Ping_f, "print ping times of all players on the server"); Cmd_AddCommand ("load", Host_Loadgame_f, "load a saved game file"); @@ -2923,6 +3057,8 @@ void Host_InitCommands (void) Cmd_AddCommand_WithClientCommand ("color", Host_Color_f, Host_Color_f, "change your player shirt and pants colors"); Cvar_RegisterVariable (&cl_rate); Cmd_AddCommand_WithClientCommand ("rate", Host_Rate_f, Host_Rate_f, "change your network connection speed"); + Cvar_RegisterVariable (&cl_rate_burstsize); + Cmd_AddCommand_WithClientCommand ("rate_burstsize", Host_Rate_BurstSize_f, Host_Rate_BurstSize_f, "change your network connection speed"); Cvar_RegisterVariable (&cl_pmodel); Cmd_AddCommand_WithClientCommand ("pmodel", Host_PModel_f, Host_PModel_f, "(Nehahra-only) change your player model choice");