X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=host_cmd.c;h=ee974ac607e302c71c4ff19eb8208a44c98a40a8;hb=5090f6da276d673f6ee0b149ee2f83ef82f62902;hp=5e4b14764bf5bc32a94216063f3c39a9a4afb0a6;hpb=8d376b57de94bafd3bae224088b469649c853028;p=xonotic%2Fdarkplaces.git diff --git a/host_cmd.c b/host_cmd.c index 5e4b1476..ee974ac6 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int current_skill; cvar_t sv_cheats = {0, "sv_cheats", "0", "enables cheat commands in any game, and cheat impulses in dpmod"}; cvar_t sv_adminnick = {CVAR_SAVE, "sv_adminnick", "", "nick name to use for admin messages instead of host name"}; +cvar_t sv_status_privacy = {CVAR_SAVE, "sv_status_privacy", "0", "do not show IP addresses in 'status' replies to clients"}; cvar_t rcon_password = {CVAR_PRIVATE, "rcon_password", "", "password to authenticate rcon commands"}; cvar_t rcon_address = {0, "rcon_address", "", "server address to send rcon commands to (when not connected to a server)"}; cvar_t team = {CVAR_USERINFO | CVAR_SAVE, "team", "none", "QW team (4 character limit, example: blue)"}; @@ -101,7 +102,10 @@ void Host_Status_f (void) else hours = 0; print ("#%-3u %-16.16s %3i %2i:%02i:%02i\n", j+1, client->name, client->frags, hours, minutes, seconds); - print (" %s\n", client->netconnection ? client->netconnection->address : "botclient"); + if(sv_status_privacy.integer && cmd_source != src_command) + print (" %s\n", client->netconnection ? "hidden" : "botclient"); + else + print (" %s\n", client->netconnection ? client->netconnection->address : "botclient"); } } @@ -435,6 +439,102 @@ LOAD / SAVE GAME #define SAVEGAME_VERSION 5 +void Host_Savegame_to (const char *name) +{ + qfile_t *f; + int i, lightstyles = 64; + char comment[SAVEGAME_COMMENT_LENGTH+1]; + qboolean isserver; + + // first we have to figure out if this can be saved in 64 lightstyles + // (for Quake compatibility) + for (i=64 ; iedicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters); + else + dpsnprintf(comment, sizeof(comment), "(crash dump of %s progs)", PRVM_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)); + } + +#if 1 + FS_Printf(f,"/*\n"); + FS_Printf(f,"// DarkPlaces extended savegame\n"); + // darkplaces extension - extra lightstyles, support for color lightstyles + for (i=0 ; iedicts->fields.server->message), (int)prog->globals.server->killed_monsters, (int)prog->globals.server->total_monsters); - // convert space to _ to make stdio happy - // LordHavoc: convert control characters to _ as well - for (i=0 ; inum_edicts ; i++) - PRVM_ED_Write (f, PRVM_EDICT_NUM(i)); - + Host_Savegame_to(name); SV_VM_End(); - - FS_Close (f); - Con_Print("done.\n"); } @@ -545,8 +600,8 @@ void Host_Loadgame_f (void) char mapname[MAX_QPATH]; float time; const char *start; + const char *end; const char *t; - const char *oldt; char *text; prvm_edict_t *ent; int i; @@ -627,16 +682,20 @@ void Host_Loadgame_f (void) // load the light styles + SV_VM_Begin(); + // -1 is the globals + entnum = -1; + for (i = 0;i < MAX_LIGHTSTYLES;i++) { // light style - oldt = t; + start = t; COM_ParseToken_Simple(&t, false, false); // if this is a 64 lightstyle savegame produced by Quake, stop now - // we have to check this because darkplaces saves 256 lightstyle savegames + // we have to check this because darkplaces may save more than 64 if (com_token[0] == '{') { - t = oldt; + t = start; break; } strlcpy(sv.lightstyles[i], com_token, sizeof(sv.lightstyles[i])); @@ -646,21 +705,20 @@ void Host_Loadgame_f (void) // (this is for forward compatibility, so that older versions (at // least ones with this fix) can load savegames with extra data before the // first brace, as might be produced by a later engine version) - for(;;) + for (;;) { - oldt = t; - COM_ParseToken_Simple(&t, false, false); + start = t; + if (!COM_ParseToken_Simple(&t, false, false)) + break; if (com_token[0] == '{') { - t = oldt; + t = start; break; } } // load the edicts out of the savegame file - SV_VM_Begin(); - // -1 is the globals - entnum = -1; + end = t; for (;;) { start = t; @@ -703,6 +761,7 @@ void Host_Loadgame_f (void) SV_LinkEdict (ent, false); } + end = t; entnum++; } Mem_Free(text); @@ -713,6 +772,59 @@ void Host_Loadgame_f (void) for (i = 0;i < NUM_SPAWN_PARMS;i++) svs.clients[0].spawn_parms[i] = spawn_parms[i]; + // read extended data if present + // the extended data is stored inside a /* */ comment block, which the + // parser intentionally skips, so we have to check for it manually here + while (*end == '\r' || *end == '\n') + end++; + if (end[0] == '/' && end[1] == '*' && (end[2] == '\r' || end[2] == '\n')) + { + Con_Printf("Loading extended DarkPlaces savegame\n"); + t = end + 2; + 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)) + { + if (!strcmp(com_token, "sv.lightstyles")) + { + COM_ParseToken_Simple(&t, false, false); + i = atoi(com_token); + COM_ParseToken_Simple(&t, false, false); + if (i >= 0 && i < MAX_LIGHTSTYLES) + strlcpy(sv.lightstyles[i], com_token, sizeof(sv.lightstyles[i])); + else + Con_Printf("unsupported lightstyle %i \"%s\"\n", i, com_token); + } + else if (!strcmp(com_token, "sv.model_precache")) + { + COM_ParseToken_Simple(&t, false, false); + i = atoi(com_token); + COM_ParseToken_Simple(&t, false, false); + if (i >= 0 && i < MAX_MODELS) + { + strlcpy(sv.model_precache[i], com_token, sizeof(sv.model_precache[i])); + sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, false); + } + else + Con_Printf("unsupported model %i \"%s\"\n", i, com_token); + } + else if (!strcmp(com_token, "sv.sound_precache")) + { + COM_ParseToken_Simple(&t, false, false); + i = atoi(com_token); + COM_ParseToken_Simple(&t, false, false); + 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); + } + // skip any trailing text or unrecognized commands + while (COM_ParseToken_Simple(&t, true, false) && strcmp(com_token, "\n")) + ; + } + } + SV_VM_End(); // make sure we're connected to loopback @@ -767,6 +879,15 @@ void Host_Name_f (void) host_client->name[j++] = host_client->name[i]; host_client->name[j] = 0; + if(host_client->name[0] == 1 || host_client->name[0] == 2) + // may interfere with chat area, and will needlessly beep; so let's add a ^7 + { + memmove(host_client->name + 2, host_client->name, sizeof(host_client->name) - 2); + host_client->name[sizeof(host_client->name) - 1] = 0; + host_client->name[0] = STRING_COLOR_TAG; + host_client->name[1] = '0' + STRING_COLOR_DEFAULT; + } + COM_StringLengthNoColors(host_client->name, 0, &valid_colors); if(!valid_colors) // NOTE: this also proves the string is not empty, as "" is a valid colored string { @@ -1055,11 +1176,11 @@ void Host_Tell_f(void) // note this uses the chat prefix \001 if (!fromServer) - sprintf (text, "\001%s tells you: ", host_client->name); + dpsnprintf (text, sizeof(text), "\001%s tells you: ", host_client->name); else if(*(sv_adminnick.string)) - sprintf (text, "\001<%s tells you> ", sv_adminnick.string); + dpsnprintf (text, sizeof(text), "\001<%s tells you> ", sv_adminnick.string); else - sprintf (text, "\001<%s tells you> ", hostname.string); + dpsnprintf (text, sizeof(text), "\001<%s tells you> ", hostname.string); p1 = Cmd_Args(); p2 = p1 + strlen(p1); @@ -1812,7 +1933,7 @@ Host_Viewmodel_f void Host_Viewmodel_f (void) { prvm_edict_t *e; - model_t *m; + dp_model_t *m; if (!sv.active) return; @@ -1843,7 +1964,7 @@ void Host_Viewframe_f (void) { prvm_edict_t *e; int f; - model_t *m; + dp_model_t *m; if (!sv.active) return; @@ -1863,7 +1984,7 @@ void Host_Viewframe_f (void) } -void PrintFrameName (model_t *m, int frame) +void PrintFrameName (dp_model_t *m, int frame) { if (m->animscenes) Con_Printf("frame %i: %s\n", frame, m->animscenes[frame].name); @@ -1879,7 +2000,7 @@ Host_Viewnext_f void Host_Viewnext_f (void) { prvm_edict_t *e; - model_t *m; + dp_model_t *m; if (!sv.active) return; @@ -1906,7 +2027,7 @@ Host_Viewprev_f void Host_Viewprev_f (void) { prvm_edict_t *e; - model_t *m; + dp_model_t *m; if (!sv.active) return; @@ -2520,6 +2641,7 @@ void Host_InitCommands (void) Cvar_RegisterVariable(&sv_cheats); Cvar_RegisterVariable(&sv_adminnick); + Cvar_RegisterVariable(&sv_status_privacy); } void Host_NoOperation_f(void)