X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=host_cmd.c;h=da2705a40f58ec2071e3f4f5f893d80f4b587fb7;hp=44701986a659c7a5fd94e23d82dcf8e345c5ea07;hb=4962190c532b90f691cf944328f12bf70852c97d;hpb=2275e4d0cab079f4a0849ba55b8f92023d6f3eab diff --git a/host_cmd.c b/host_cmd.c index 44701986..da2705a4 100644 --- a/host_cmd.c +++ b/host_cmd.c @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -20,11 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -extern cvar_t pausable; - -int current_skill; - -void Mod_Print (void); +int current_skill; +char sv_spawnmap[MAX_QPATH]; +char sv_loadgame[MAX_OSPATH]; dfunction_t *ED_FindFunction (char *name); @@ -34,20 +32,12 @@ Host_Quit_f ================== */ -// LordHavoc: didn't like it asking me if I wanted to quit -//extern void M_Menu_Quit_f (void); - +extern qboolean host_shuttingdown; void Host_Quit_f (void) { - /* - if (key_dest != key_console && cls.state != ca_dedicated) - { - M_Menu_Quit_f (); - return; - } - */ + host_shuttingdown = true; CL_Disconnect (); - Host_ShutdownServer(false); + Host_ShutdownServer(false); Sys_Quit (); } @@ -60,13 +50,10 @@ Host_Status_f */ void Host_Status_f (void) { - client_t *client; - int seconds; - int minutes; - int hours = 0; - int j; - void (*print) (char *fmt, ...); - + client_t *client; + int seconds, minutes, hours = 0, j; + void (*print) (const char *fmt, ...); + if (cmd_source == src_command) { if (!sv.active) @@ -80,7 +67,7 @@ void Host_Status_f (void) print = SV_ClientPrintf; print ("host: %s\n", Cvar_VariableString ("hostname")); - print ("version: %4.2f\n", VERSION); + print ("version: %s build %s\n", gamename, buildstring); if (tcpipAvailable) print ("tcp/ip: %s\n", my_tcpip_address); if (ipxAvailable) @@ -248,58 +235,31 @@ SERVER TRANSITIONS =============================================================================== */ - /* ====================== Host_Map_f -handle a +handle a map command from the console. Active clients are kicked off. ====================== */ void Host_Map_f (void) { - int i; - char name[MAX_QPATH]; - if (cmd_source != src_command) return; cls.demonum = -1; // stop demo loop in case this fails + SCR_BeginLoadingPlaque (); + CL_Disconnect (); - Host_ShutdownServer(false); + Host_ShutdownServer(false); key_dest = key_game; // remove console or menu - SCR_BeginLoadingPlaque (); - - cls.mapstring[0] = 0; - for (i=0 ; i : continue game on a new level\n"); @@ -324,8 +282,7 @@ void Host_Changelevel_f (void) return; } SV_SaveSpawnparms (); - strcpy (level, Cmd_Argv(1)); - SV_SpawnServer (level); + strcpy (sv_spawnmap, Cmd_Argv(1)); } /* @@ -337,16 +294,12 @@ Restarts the current server for a dead player */ void Host_Restart_f (void) { - char mapname[MAX_QPATH]; - if (cls.demoplayback || !sv.active) return; if (cmd_source != src_command) return; - strcpy (mapname, sv.name); // must copy out, because it gets cleared - // in sv_spawnserver - SV_SpawnServer (mapname); + strcpy (sv_spawnmap, sv.name); } /* @@ -372,14 +325,11 @@ User command to connect to server */ void Host_Connect_f (void) { - char name[MAX_QPATH]; - + char name[MAX_QPATH]; + cls.demonum = -1; // stop demo loop in case this fails if (cls.demoplayback) - { - CL_StopPlayback (); CL_Disconnect (); - } strcpy (name, Cmd_Argv(1)); CL_EstablishConnection (name); Host_Reconnect_f (); @@ -400,7 +350,7 @@ LOAD / SAVE GAME =============== Host_SavegameComment -Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current +Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current =============== */ void Host_SavegameComment (char *text) @@ -429,7 +379,7 @@ Host_Savegame_f void Host_Savegame_f (void) { char name[256]; - FILE *f; + QFile *f; int i; char comment[SAVEGAME_COMMENT_LENGTH+1]; @@ -465,7 +415,7 @@ void Host_Savegame_f (void) Con_Printf ("Relative pathnames are not allowed.\n"); return; } - + for (i=0 ; iv.health <= 0) ) @@ -477,32 +427,32 @@ void Host_Savegame_f (void) sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); COM_DefaultExtension (name, ".sav"); - + Con_Printf ("Saving game to %s...\n", name); - f = fopen (name, "w"); + f = Qopen (name, "w"); if (!f) { Con_Printf ("ERROR: couldn't open.\n"); return; } - - fprintf (f, "%i\n", SAVEGAME_VERSION); + + Qprintf (f, "%i\n", SAVEGAME_VERSION); Host_SavegameComment (comment); - fprintf (f, "%s\n", comment); + Qprintf (f, "%s\n", comment); for (i=0 ; ispawn_parms[i]); - fprintf (f, "%d\n", current_skill); - fprintf (f, "%s\n", sv.name); - fprintf (f, "%f\n",sv.time); + Qprintf (f, "%f\n", svs.clients->spawn_parms[i]); + Qprintf (f, "%d\n", current_skill); + Qprintf (f, "%s\n", sv.name); + Qprintf (f, "%f\n",sv.time); // write the light styles for (i=0 ; iv, 0, progs->entityfields * 4); ent->free = false; ED_ParseEdict (start, ent); - - // link it into the bsp tree + + // link it into the bsp tree if (!ent->free) SV_LinkEdict (ent, false); } entnum++; } - + sv.num_edicts = entnum; sv.time = time; - fclose (f); + Qclose (f); - for (i=0 ; ispawn_parms[i] = spawn_parms[i]; if (cls.state != ca_dedicated) @@ -669,17 +636,18 @@ Host_Name_f */ void Host_Name_f (void) { - char *newName; + char newName[64]; if (Cmd_Argc () == 1) { Con_Printf ("\"name\" is \"%s\"\n", cl_name.string); return; } + if (Cmd_Argc () == 2) - newName = Cmd_Argv(1); + strncpy(newName, Cmd_Argv(1), 15); else - newName = Cmd_Args(); + strncpy(newName, Cmd_Args(), 15); newName[15] = 0; if (cmd_source == src_command) @@ -697,30 +665,29 @@ void Host_Name_f (void) Con_Printf ("%s renamed to %s\n", host_client->name, newName); strcpy (host_client->name, newName); host_client->edict->v.netname = host_client->name - pr_strings; - + // send notification to all clients - + MSG_WriteByte (&sv.reliable_datagram, svc_updatename); MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); MSG_WriteString (&sv.reliable_datagram, host_client->name); } - + void Host_Version_f (void) { - Con_Printf ("Version %4.2f\n", VERSION); - Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); + Con_Printf ("Version: %s build %s\n", gamename, buildstring); } void Host_Say(qboolean teamonly) { client_t *client; client_t *save; - int j; - char *p; + int j; + const char *p1, *p2; // LordHavoc: 256 char say messages - unsigned char text[256]; - qboolean fromServer = false; + unsigned char text[256]; + qboolean fromServer = false; if (cmd_source == src_command) { @@ -739,34 +706,40 @@ void Host_Say(qboolean teamonly) if (Cmd_Argc () < 2) return; - save = host_client; - - p = Cmd_Args(); -// remove quotes if present - if (*p == '"') - { - p++; - p[strlen(p)-1] = 0; - } - // turn on color set 1 if (!fromServer) - sprintf (text, "%c%s: ", 1, save->name); + sprintf (text, "%c%s: ", 1, host_client->name); else sprintf (text, "%c<%s> ", 1, hostname.string); - j = sizeof(text) - 2 - strlen(text); // -2 for /n and null terminator - if (strlen(p) > j) - p[j] = 0; + save = host_client; - strcat (text, p); - strcat (text, "\n"); + p1 = Cmd_Args(); + p2 = p1 + strlen(p1); + // remove trailing newlines + while (p2 > p1 && (p2[-1] == '\n' || p2[-1] == '\r')) + p2--; + // remove quotes if present + if (*p1 == '"') + { + p1++; + if (p2[-1] == '"') + p2--; + else + Con_Printf("Host_Say: missing end quote\n"); + } + while (p2 > p1 && (p2[-1] == '\n' || p2[-1] == '\r')) + p2--; + for (j = strlen(text);j < (sizeof(text) - 2) && p1 < p2;) + text[j++] = *p1++; + text[j++] = '\n'; + text[j++] = 0; for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) { if (!client || !client->active || !client->spawned) continue; - if (teamplay.value && teamonly && client->edict->v.team != save->edict->v.team) + if (teamplay.integer && teamonly && client->edict->v.team != save->edict->v.team) continue; host_client = client; SV_ClientPrintf("%s", text); @@ -793,38 +766,55 @@ void Host_Tell_f(void) { client_t *client; client_t *save; - int j; - char *p; - char text[1024]; // LordHavoc: FIXME: temporary buffer overflow fix (was 64) + int j; + const char *p1, *p2; + char text[1024]; // LordHavoc: FIXME: temporary buffer overflow fix (was 64) + qboolean fromServer = false; if (cmd_source == src_command) { - Cmd_ForwardToServer (); - return; + if (cls.state == ca_dedicated) + fromServer = true; + else + { + Cmd_ForwardToServer (); + return; + } } if (Cmd_Argc () < 3) return; - strcpy(text, host_client->name); - strcat(text, ": "); - - p = Cmd_Args(); - -// remove quotes if present - if (*p == '"') - { - p++; - p[strlen(p)-1] = 0; + if (!fromServer) + sprintf (text, "%s: ", host_client->name); + else + sprintf (text, "<%s> ", hostname.string); + + p1 = Cmd_Args(); + p2 = p1 + strlen(p1); + // remove the target name + while (p1 < p2 && *p1 != ' ') + p1++; + while (p1 < p2 && *p1 == ' ') + p1++; + // remove trailing newlines + while (p2 > p1 && (p2[-1] == '\n' || p2[-1] == '\r')) + p2--; + // remove quotes if present + if (*p1 == '"') + { + p1++; + if (p2[-1] == '"') + p2--; + else + Con_Printf("Host_Say: missing end quote\n"); } - -// check length & truncate if necessary - j = sizeof(text) - 2 - strlen(text); // -2 for /n and null terminator - if (strlen(p) > j) - p[j] = 0; - - strcat (text, p); - strcat (text, "\n"); + while (p2 > p1 && (p2[-1] == '\n' || p2[-1] == '\r')) + p2--; + for (j = strlen(text);j < (sizeof(text) - 2) && p1 < p2;) + text[j++] = *p1++; + text[j++] = '\n'; + text[j++] = 0; save = host_client; for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) @@ -852,11 +842,11 @@ void Host_Color_f(void) int playercolor; dfunction_t *f; func_t SV_ChangeTeam; - + if (Cmd_Argc() == 1) { - Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color.value) >> 4, ((int)cl_color.value) & 0x0f); - Con_Printf ("color <0-13> [0-13]\n"); + Con_Printf ("\"color\" is \"%i %i\"\n", cl_color.integer >> 4, cl_color.integer & 15); + Con_Printf ("color <0-15> [0-15]\n"); return; } @@ -867,7 +857,7 @@ void Host_Color_f(void) top = atoi(Cmd_Argv(1)); bottom = atoi(Cmd_Argv(2)); } - + top &= 15; // LordHavoc: allow skin colormaps 14 and 15 (was 13) if (top > 15) @@ -876,7 +866,7 @@ void Host_Color_f(void) // LordHavoc: allow skin colormaps 14 and 15 (was 13) if (bottom > 15) bottom = 15; - + playercolor = top*16 + bottom; if (cmd_source == src_command) @@ -887,14 +877,13 @@ void Host_Color_f(void) return; } - // void(float color) SV_ChangeTeam; if ((f = ED_FindFunction ("SV_ChangeTeam")) && (SV_ChangeTeam = (func_t)(f - pr_functions))) { Con_DPrintf("Calling SV_ChangeTeam\n"); pr_global_struct->time = sv.time; - pr_globals[0] = playercolor; + pr_globals[OFS_PARM0] = playercolor; pr_global_struct->self = EDICT_TO_PROG(host_client->edict); - PR_ExecuteProgram (SV_ChangeTeam); + PR_ExecuteProgram (SV_ChangeTeam, ""); } else { @@ -923,13 +912,13 @@ void Host_Kill_f (void) if (sv_player->v.health <= 0) { - SV_ClientPrintf ("Can't suicide -- allready dead!\n"); + SV_ClientPrintf ("Can't suicide -- already dead!\n"); return; } - + pr_global_struct->time = sv.time; pr_global_struct->self = EDICT_TO_PROG(sv_player); - PR_ExecuteProgram (pr_global_struct->ClientKill); + PR_ExecuteProgram (pr_global_struct->ClientKill, "QC function ClientKill is missing"); } @@ -946,7 +935,7 @@ void Host_Pause_f (void) Cmd_ForwardToServer (); return; } - if (!pausable.value) + if (!pausable.integer) SV_ClientPrintf ("Pause not allowed.\n"); else { @@ -985,7 +974,7 @@ void Host_PreSpawn_f (void) if (host_client->spawned) { - Con_Printf ("prespawn not valid -- allready spawned\n"); + Con_Printf ("prespawn not valid -- already spawned\n"); return; } @@ -1016,7 +1005,7 @@ void Host_Spawn_f (void) if (host_client->spawned) { - Con_Printf ("Spawn not valid -- allready spawned\n"); + Con_Printf ("Spawn not valid -- already spawned\n"); return; } @@ -1026,7 +1015,8 @@ void Host_Spawn_f (void) // run the entrance script if (sv.loadgame) - { // loaded games are fully inited allready + { + // loaded games are fully initialized already // if this is the last client to be connected, unpause sv.paused = false; @@ -1036,7 +1026,7 @@ void Host_Spawn_f (void) Con_DPrintf("Calling RestoreGame\n"); pr_global_struct->time = sv.time; pr_global_struct->self = EDICT_TO_PROG(sv_player); - PR_ExecuteProgram (RestoreGame); + PR_ExecuteProgram (RestoreGame, ""); } } else @@ -1061,12 +1051,12 @@ void Host_Spawn_f (void) pr_global_struct->time = sv.time; pr_global_struct->self = EDICT_TO_PROG(sv_player); - PR_ExecuteProgram (pr_global_struct->ClientConnect); + PR_ExecuteProgram (pr_global_struct->ClientConnect, "QC function ClientConnect is missing"); - if ((Sys_FloatTime() - host_client->netconnection->connecttime) <= sv.time) + if ((Sys_DoubleTime() - host_client->netconnection->connecttime) <= sv.time) Sys_Printf ("%s entered the game\n", host_client->name); - PR_ExecuteProgram (pr_global_struct->PutClientInServer); + PR_ExecuteProgram (pr_global_struct->PutClientInServer, "QC function PutClientInServer is missing"); } @@ -1086,7 +1076,7 @@ void Host_Spawn_f (void) MSG_WriteByte (&host_client->message, i); MSG_WriteByte (&host_client->message, client->colors); } - + // send all current light styles for (i=0 ; imessage, STAT_MONSTERS); MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters); -// // send a fixangle // Never send a roll angle, because savegames can catch the server // in a state where it is expecting the client to correct the angle @@ -1161,11 +1150,11 @@ Kicks a user off of the server */ void Host_Kick_f (void) { - char *who; - char *message = NULL; - client_t *save; - int i; - qboolean byNumber = false; + char *who; + const char *message = NULL; + client_t *save; + int i; + qboolean byNumber = false; if (cmd_source == src_command) { @@ -1204,10 +1193,12 @@ void Host_Kick_f (void) if (i < svs.maxclients) { if (cmd_source == src_command) + { if (cls.state == ca_dedicated) who = "Console"; else who = cl_name.string; + } else who = save->name; @@ -1217,7 +1208,8 @@ void Host_Kick_f (void) if (Cmd_Argc() > 2) { - message = COM_Parse(Cmd_Args()); + message = Cmd_Args(); + COM_ParseToken(&message); if (byNumber) { message++; // skip the # @@ -1253,9 +1245,9 @@ Host_Give_f */ void Host_Give_f (void) { - char *t; - int v; - eval_t *val; + const char *t; + int v; + eval_t *val; if (cmd_source == src_command) { @@ -1268,58 +1260,58 @@ void Host_Give_f (void) t = Cmd_Argv(1); v = atoi (Cmd_Argv(2)); - + switch (t[0]) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - // MED 01/04/97 added hipnotic give stuff - if (hipnotic) - { - if (t[0] == '6') - { - if (t[1] == 'a') - sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN; - else - sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER; - } - else if (t[0] == '9') - sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON; - else if (t[0] == '0') - sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR; - else if (t[0] >= '2') - sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); - } - else - { - if (t[0] >= '2') - sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); - } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // MED 01/04/97 added hipnotic give stuff + if (gamemode == GAME_HIPNOTIC) + { + if (t[0] == '6') + { + if (t[1] == 'a') + sv_player->v.items = (int)sv_player->v.items | HIT_PROXIMITY_GUN; + else + sv_player->v.items = (int)sv_player->v.items | IT_GRENADE_LAUNCHER; + } + else if (t[0] == '9') + sv_player->v.items = (int)sv_player->v.items | HIT_LASER_CANNON; + else if (t[0] == '0') + sv_player->v.items = (int)sv_player->v.items | HIT_MJOLNIR; + else if (t[0] >= '2') + sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + } + else + { + if (t[0] >= '2') + sv_player->v.items = (int)sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + } break; - - case 's': - if (rogue) + + case 's': + if (gamemode == GAME_ROGUE) { - if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_shells1))) - val->_float = v; + if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_shells1))) + val->_float = v; } - sv_player->v.ammo_shells = v; - break; - case 'n': - if (rogue) + sv_player->v.ammo_shells = v; + break; + case 'n': + if (gamemode == GAME_ROGUE) { - if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_nails1))) + if ((val = GETEDICTFIELDVALUE(sv_player, eval_ammo_nails1))) { - val->_float = v; + val->_float = v; if (sv_player->v.weapon <= IT_LIGHTNING) sv_player->v.ammo_nails = v; } @@ -1328,9 +1320,9 @@ void Host_Give_f (void) { sv_player->v.ammo_nails = v; } - break; - case 'l': - if (rogue) + break; + case 'l': + if (gamemode == GAME_ROGUE) { val = GETEDICTFIELDVALUE(sv_player, eval_ammo_lava_nails); if (val) @@ -1340,9 +1332,9 @@ void Host_Give_f (void) sv_player->v.ammo_nails = v; } } - break; - case 'r': - if (rogue) + break; + case 'r': + if (gamemode == GAME_ROGUE) { val = GETEDICTFIELDVALUE(sv_player, eval_ammo_rockets1); if (val) @@ -1356,9 +1348,9 @@ void Host_Give_f (void) { sv_player->v.ammo_rockets = v; } - break; - case 'm': - if (rogue) + break; + case 'm': + if (gamemode == GAME_ROGUE) { val = GETEDICTFIELDVALUE(sv_player, eval_ammo_multi_rockets); if (val) @@ -1368,12 +1360,12 @@ void Host_Give_f (void) sv_player->v.ammo_rockets = v; } } - break; - case 'h': - sv_player->v.health = v; - break; - case 'c': - if (rogue) + break; + case 'h': + sv_player->v.health = v; + break; + case 'c': + if (gamemode == GAME_ROGUE) { val = GETEDICTFIELDVALUE(sv_player, eval_ammo_cells1); if (val) @@ -1387,9 +1379,9 @@ void Host_Give_f (void) { sv_player->v.ammo_cells = v; } - break; - case 'p': - if (rogue) + break; + case 'p': + if (gamemode == GAME_ROGUE) { val = GETEDICTFIELDVALUE(sv_player, eval_ammo_plasma); if (val) @@ -1399,15 +1391,15 @@ void Host_Give_f (void) sv_player->v.ammo_cells = v; } } - break; - } + break; + } } edict_t *FindViewthing (void) { int i; edict_t *e; - + for (i=0 ; iframedata + (int) mheader))[frame]; - - Con_Printf ("frame %i: %s\n", frame, frameinfo->name); + if (m->animscenes) + Con_Printf("frame %i: %s\n", frame, m->animscenes[frame].name); + else + Con_Printf("frame %i\n", frame); } /* @@ -1545,8 +1532,13 @@ void Host_Startdemos_f (void) if (cls.state == ca_dedicated) { - if (!sv.active) - Cbuf_AddText ("map start\n"); + if (!sv.active && !sv_spawnmap[0]) + { + if (gamemode == GAME_TRANSFUSION) + Cbuf_AddText ("map bb1\n"); + else + Cbuf_AddText ("map start\n"); + } return; } @@ -1597,14 +1589,27 @@ Return to looping demos */ void Host_Stopdemo_f (void) { - if (cls.state == ca_dedicated) - return; if (!cls.demoplayback) return; - CL_StopPlayback (); CL_Disconnect (); } +// LordHavoc: because we don't want to load things before the video starts, +// we have to delay map and game loads until AFTER video is initialized +void Host_PerformSpawnServerAndLoadGame(void) +{ + if (vid_hidden && cls.state != ca_dedicated) + return; + if (sv_loadgame[0]) + Host_PerformLoadGame(sv_loadgame); + else if (sv_spawnmap[0]) + SV_SpawnServer(sv_spawnmap); + if (sv.active && cls.state == ca_disconnected) + Cmd_ExecuteString ("connect local", src_command); + sv_loadgame[0] = 0; + sv_spawnmap[0] = 0; +} + //============================================================================= /* @@ -1616,7 +1621,7 @@ void Host_InitCommands (void) { Cmd_AddCommand ("status", Host_Status_f); Cmd_AddCommand ("quit", Host_Quit_f); - if (nehahra) + if (gamemode == GAME_NEHAHRA) { Cmd_AddCommand ("max", Host_God_f); Cmd_AddCommand ("monster", Host_Notarget_f); @@ -1661,6 +1666,5 @@ void Host_InitCommands (void) Cmd_AddCommand ("viewframe", Host_Viewframe_f); Cmd_AddCommand ("viewnext", Host_Viewnext_f); Cmd_AddCommand ("viewprev", Host_Viewprev_f); - - Cmd_AddCommand ("mcache", Mod_Print); } +