|
|
1.1 root 1:
2: #include "quakedef.h"
3:
4:
5: /*
6: ==================
7: Host_Quit_f
8: ==================
9: */
10:
11: extern void M_Menu_Quit_f (void);
12:
13: void Host_Quit_f (void)
14: {
15: if (key_dest != key_console && cls.state != ca_dedicated)
16: {
17: M_Menu_Quit_f ();
18: return;
19: }
20: CL_Disconnect ();
21: Host_ShutdownServer(false);
22:
23: Sys_Quit ();
24: }
25:
26:
27: /*
28: ==================
29: Host_Status_f
30: ==================
31: */
32: void Host_Status_f (void)
33: {
34: client_t *client;
35: int seconds;
36: int minutes;
37: int hours = 0;
38: int j;
39: void (*print) (char *fmt, ...);
40:
41: if (cmd_source == src_command)
42: {
43: if (!sv.active)
44: {
45: Cmd_ForwardToServer ();
46: return;
47: }
48: print = Con_Printf;
49: }
50: else
51: print = SV_ClientPrintf;
52:
53: print ("host: %s\n", Cvar_VariableString ("hostname"));
54: print ("version: %4.2f\n", VERSION);
55: if (tcpipAvailable)
56: print ("tcp/ip: %s\n", my_tcpip_address);
57: if (ipxAvailable)
58: print ("ipx: %s\n", my_ipx_address);
59: print ("map: %s\n", sv.name);
60: print ("players: %i active (%i max)\n\n", net_activeconnections, svs.maxclients);
61: for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
62: {
63: if (!client->active)
64: continue;
65: seconds = (int)(net_time - client->netconnection->connecttime);
66: minutes = seconds / 60;
67: if (minutes)
68: {
69: seconds -= (minutes * 60);
70: hours = minutes / 60;
71: if (hours)
72: minutes -= (hours * 60);
73: }
74: else
75: hours = 0;
1.1.1.2 ! root 76: print ("%-16.16s %3i %2i:%02i:%02i\n", client->name, (int)client->edict->v.frags, hours, minutes, seconds);
1.1 root 77: print (" %s\n", client->netconnection->address);
78: }
79: }
80:
81:
82: /*
83: ==================
84: Host_God_f
85:
86: Sets client to godmode
87: ==================
88: */
89: void Host_God_f (void)
90: {
91: if (cmd_source == src_command)
92: {
93: Cmd_ForwardToServer ();
94: return;
95: }
96:
97: if (pr_global_struct->deathmatch && !host_client->privileged)
98: return;
99:
100: sv_player->v.flags = (int)sv_player->v.flags ^ FL_GODMODE;
101: if (!((int)sv_player->v.flags & FL_GODMODE) )
102: SV_ClientPrintf ("godmode OFF\n");
103: else
104: SV_ClientPrintf ("godmode ON\n");
105: }
106:
107: void Host_Notarget_f (void)
108: {
109: if (cmd_source == src_command)
110: {
111: Cmd_ForwardToServer ();
112: return;
113: }
114:
115: if (pr_global_struct->deathmatch && !host_client->privileged)
116: return;
117:
118: sv_player->v.flags = (int)sv_player->v.flags ^ FL_NOTARGET;
119: if (!((int)sv_player->v.flags & FL_NOTARGET) )
120: SV_ClientPrintf ("notarget OFF\n");
121: else
122: SV_ClientPrintf ("notarget ON\n");
123: }
124:
125: qboolean noclip_anglehack;
126:
127: void Host_Noclip_f (void)
128: {
129: if (cmd_source == src_command)
130: {
131: Cmd_ForwardToServer ();
132: return;
133: }
134:
135: if (pr_global_struct->deathmatch && !host_client->privileged)
136: return;
137:
138: if (sv_player->v.movetype != MOVETYPE_NOCLIP)
139: {
140: noclip_anglehack = true;
141: sv_player->v.movetype = MOVETYPE_NOCLIP;
142: SV_ClientPrintf ("noclip ON\n");
143: }
144: else
145: {
146: noclip_anglehack = false;
147: sv_player->v.movetype = MOVETYPE_WALK;
148: SV_ClientPrintf ("noclip OFF\n");
149: }
150: }
151:
152: /*
153: ==================
154: Host_Fly_f
155:
156: Sets client to flymode
157: ==================
158: */
159: void Host_Fly_f (void)
160: {
161: if (cmd_source == src_command)
162: {
163: Cmd_ForwardToServer ();
164: return;
165: }
166:
167: if (pr_global_struct->deathmatch && !host_client->privileged)
168: return;
169:
170: if (sv_player->v.movetype != MOVETYPE_FLY)
171: {
172: sv_player->v.movetype = MOVETYPE_FLY;
173: SV_ClientPrintf ("flymode ON\n");
174: }
175: else
176: {
177: sv_player->v.movetype = MOVETYPE_WALK;
178: SV_ClientPrintf ("flymode OFF\n");
179: }
180: }
181:
182:
183: /*
184: ==================
185: Host_Ping_f
186:
187: ==================
188: */
189: void Host_Ping_f (void)
190: {
191: int i, j;
192: float total;
193: client_t *client;
194:
195: if (cmd_source == src_command)
196: {
197: Cmd_ForwardToServer ();
198: return;
199: }
200:
201: SV_ClientPrintf ("Client ping times:\n");
202: for (i=0, client = svs.clients ; i<svs.maxclients ; i++, client++)
203: {
204: if (!client->active)
205: continue;
206: total = 0;
207: for (j=0 ; j<NUM_PING_TIMES ; j++)
208: total+=client->ping_times[j];
209: total /= NUM_PING_TIMES;
210: SV_ClientPrintf ("%4i %s\n", (int)(total*1000), client->name);
211: }
212: }
213:
214: /*
215: ===============================================================================
216:
217: SERVER TRANSITIONS
218:
219: ===============================================================================
220: */
221:
222:
223: /*
224: ======================
225: Host_Map_f
226:
227: handle a
228: map <servername>
229: command from the console. Active clients are kicked off.
230: ======================
231: */
232: void Host_Map_f (void)
233: {
234: int i;
235: char name[MAX_QPATH];
236:
237: if (cmd_source != src_command)
238: return;
239:
240: cls.demonum = -1; // stop demo loop in case this fails
241:
242: CL_Disconnect ();
243: Host_ShutdownServer(false);
244:
245: key_dest = key_game; // remove console or menu
246: SCR_BeginLoadingPlaque ();
247:
248: cls.mapstring[0] = 0;
249: for (i=0 ; i<Cmd_Argc() ; i++)
250: {
251: strcat (cls.mapstring, Cmd_Argv(i));
252: strcat (cls.mapstring, " ");
253: }
254: strcat (cls.mapstring, "\n");
255:
256: svs.serverflags = 0; // haven't completed an episode yet
257: strcpy (name, Cmd_Argv(1));
258: SV_SpawnServer (name);
259: if (!sv.active)
260: return;
261:
262: if (cls.state != ca_dedicated)
263: {
264: strcpy (cls.spawnparms, "");
265:
266: for (i=2 ; i<Cmd_Argc() ; i++)
267: {
268: strcat (cls.spawnparms, Cmd_Argv(i));
269: strcat (cls.spawnparms, " ");
270: }
271:
272: Cmd_ExecuteString ("connect local", src_command);
273: }
274: }
275:
276: /*
277: ==================
278: Host_Changelevel_f
279:
280: Goes to a new map, taking all clients along
281: ==================
282: */
283: void Host_Changelevel_f (void)
284: {
285: char level[MAX_QPATH];
286:
287: if (Cmd_Argc() != 2)
288: {
289: Con_Printf ("changelevel <levelname> : continue game on a new level\n");
290: return;
291: }
292: if (!sv.active || cls.demoplayback)
293: {
294: Con_Printf ("Only the server may changelevel\n");
295: return;
296: }
297: SV_SaveSpawnparms ();
298: strcpy (level, Cmd_Argv(1));
299: SV_SpawnServer (level);
300: }
301:
302: /*
303: ==================
304: Host_Restart_f
305:
306: Restarts the current server for a dead player
307: ==================
308: */
309: void Host_Restart_f (void)
310: {
311: char mapname[MAX_QPATH];
312:
1.1.1.2 ! root 313: if (!sv.active)
! 314: Con_Printf ("Only the server may restart\n");
1.1 root 315: if (cmd_source != src_command)
316: return;
317: strcpy (mapname, sv.name); // must copy out, because it gets cleared
318: // in sv_spawnserver
319: SV_SpawnServer (mapname);
320: }
321:
322: /*
323: ==================
324: Host_Reconnect_f
325:
326: This command causes the client to wait for the signon messages again.
327: This is sent just before a server changes levels
328: ==================
329: */
330: void Host_Reconnect_f (void)
331: {
332: SCR_BeginLoadingPlaque ();
333: cls.signon = 0; // need new connection messages
334: }
335:
336: /*
337: =====================
338: Host_Connect_f
339:
340: User command to connect to server
341: =====================
342: */
343: void Host_Connect_f (void)
344: {
345: char name[MAX_QPATH];
346:
347: cls.demonum = -1; // stop demo loop in case this fails
348: if (cls.demoplayback)
349: {
350: CL_StopPlayback ();
351: CL_Disconnect ();
352: }
353: strcpy (name, Cmd_Argv(1));
354: CL_EstablishConnection (name);
355: Host_Reconnect_f ();
356: }
357:
358:
359: /*
360: ===============================================================================
361:
362: LOAD / SAVE GAME
363:
364: ===============================================================================
365: */
366:
367: #define SAVEGAME_VERSION 5
368:
369: /*
370: ===============
371: Host_SavegameComment
372:
373: Writes a 30 character comment describing the current
374: ===============
375: */
376: void Host_SavegameComment (char *text)
377: {
378: int i;
379: char kills[20];
380:
381: for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
382: text[i] = ' ';
383: memcpy (text, cl.levelname, strlen(cl.levelname));
384: sprintf (kills,"kills:%3i/%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
385: memcpy (text+22, kills, strlen(kills));
386: // convert space to _ to make stdio happy
387: for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
388: if (text[i] == ' ')
389: text[i] = '_';
390: }
391:
392: /*
393: ===============
394: Host_Savegame_f
395: ===============
396: */
397: void Host_Savegame_f (void)
398: {
399: char name[256];
400: FILE *f;
401: int i;
402: char comment[SAVEGAME_COMMENT_LENGTH+1];
403:
404: if (cmd_source != src_command)
405: return;
406:
407: if (!sv.active)
408: {
409: Con_Printf ("Not playing a local game.\n");
410: return;
411: }
412:
413: if (cl.intermission)
414: {
415: Con_Printf ("Can't save in intermission.\n");
416: return;
417: }
418:
419: if (svs.maxclients != 1)
420: {
421: Con_Printf ("Can't save multiplayer games.\n");
422: return;
423: }
424:
425: if (Cmd_Argc() != 2)
426: {
427: Con_Printf ("save <savename> : save a game\n");
428: return;
429: }
430:
431: for (i=0 ; i<svs.maxclients ; i++)
432: {
433: if (svs.clients[i].active && (svs.clients[i].edict->v.health <= 0) )
434: {
435: Con_Printf ("Can't savegame with a dead player\n");
436: return;
437: }
438: }
1.1.1.2 ! root 439:
1.1 root 440: sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
441: COM_DefaultExtension (name, ".sav");
442:
443: Con_Printf ("Saving game to %s...\n", name);
444: f = fopen (name, "w");
445: if (!f)
446: {
447: Con_Printf ("ERROR: couldn't open.\n");
448: return;
449: }
450:
451: fprintf (f, "%i\n", SAVEGAME_VERSION);
452: Host_SavegameComment (comment);
453: fprintf (f, "%s\n", comment);
454: for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
455: fprintf (f, "%f\n", svs.clients->spawn_parms[i]);
456: fprintf (f, "%f\n", skill.value);
457: fprintf (f, "%s\n", sv.name);
458: fprintf (f, "%f\n",sv.time);
459:
460: // write the light styles
461:
462: for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
463: {
464: if (sv.lightstyles[i])
465: fprintf (f, "%s\n", sv.lightstyles[i]);
466: else
467: fprintf (f,"m\n");
468: }
469:
470:
471: ED_WriteGlobals (f);
472: for (i=0 ; i<sv.num_edicts ; i++)
473: {
474: ED_Write (f, EDICT_NUM(i));
475: fflush (f);
476: }
477: fclose (f);
478: Con_Printf ("done.\n");
479: }
480:
481:
482: /*
483: ===============
484: Host_Loadgame_f
485: ===============
486: */
487: void Host_Loadgame_f (void)
488: {
489: char name[MAX_OSPATH];
490: FILE *f;
491: char mapname[MAX_QPATH];
492: float time, sk;
493: char str[32768], *start;
494: int i, r;
495: edict_t *ent;
496: int entnum;
497: int version;
498: float spawn_parms[NUM_SPAWN_PARMS];
499:
500: if (cmd_source != src_command)
501: return;
502:
503: if (Cmd_Argc() != 2)
504: {
505: Con_Printf ("load <savename> : load a game\n");
506: return;
507: }
508:
509: cls.demonum = -1; // stop demo loop in case this fails
510:
511: sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
512: COM_DefaultExtension (name, ".sav");
513:
514: // we can't call SCR_BeginLoadingPlaque, because too much stack space has
515: // been used. The menu calls it before stuffing loadgame command
516: // SCR_BeginLoadingPlaque ();
517:
518: Con_Printf ("Loading game from %s...\n", name);
519: f = fopen (name, "r");
520: if (!f)
521: {
522: Con_Printf ("ERROR: couldn't open.\n");
523: return;
524: }
525:
526: fscanf (f, "%i\n", &version);
527: if (version != SAVEGAME_VERSION)
528: {
529: fclose (f);
530: Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
531: return;
532: }
533: fscanf (f, "%s\n", str);
534: for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
535: fscanf (f, "%f\n", &spawn_parms[i]);
536: fscanf (f, "%f\n", &sk);
537: Cvar_SetValue ("skill", sk);
538:
539: fscanf (f, "%s\n",mapname);
540: fscanf (f, "%f\n",&time);
541:
542: CL_Disconnect_f ();
543:
544: SV_SpawnServer (mapname);
545: if (!sv.active)
546: {
547: Con_Printf ("Couldn't load map\n");
548: return;
549: }
550: sv.paused = true; // pause until all clients connect
551: sv.loadgame = true;
552:
553: // load the light styles
554:
555: for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
556: {
557: fscanf (f, "%s\n", str);
558: sv.lightstyles[i] = Hunk_Alloc (strlen(str)+1);
559: strcpy (sv.lightstyles[i], str);
560: }
561:
562: // load the edicts out of the savegame file
563: entnum = -1; // -1 is the globals
564: while (!feof(f))
565: {
566: for (i=0 ; i<sizeof(str)-1 ; i++)
567: {
568: r = fgetc (f);
569: if (r == EOF || !r)
570: break;
571: str[i] = r;
572: if (r == '}')
573: {
574: i++;
575: break;
576: }
577: }
578: if (i == sizeof(str)-1)
579: Sys_Error ("Loadgame buffer overflow");
580: str[i] = 0;
581: start = str;
582: start = COM_Parse(str);
583: if (!com_token[0])
584: break; // end of file
585: if (strcmp(com_token,"{"))
586: Sys_Error ("First token isn't a brace");
587:
588: if (entnum == -1)
589: { // parse the global vars
590: ED_ParseGlobals (start);
591: }
592: else
593: { // parse an edict
594:
595: ent = EDICT_NUM(entnum);
596: memset (&ent->v, 0, progs->entityfields * 4);
597: ent->free = false;
598: ED_ParseEdict (start, ent);
599:
600: // link it into the bsp tree
601: if (!ent->free)
602: SV_LinkEdict (ent, false);
603: }
604:
605: entnum++;
606: }
607:
608: sv.num_edicts = entnum;
609: sv.time = time;
610:
611: fclose (f);
612:
613: for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
614: svs.clients->spawn_parms[i] = spawn_parms[i];
615:
616: if (cls.state != ca_dedicated)
617: {
618: CL_EstablishConnection ("local");
619: Host_Reconnect_f ();
620: }
621: }
622:
623: //============================================================================
624:
625: /*
626: ======================
627: Host_Name_f
628: ======================
629: */
630: void Host_Name_f (void)
631: {
632: char *newName;
633:
1.1.1.2 ! root 634: if (Cmd_Argc () != 2)
1.1 root 635: {
636: Con_Printf ("\"name\" is \"%s\"\n", cl_name.string);
637: return;
638: }
639:
1.1.1.2 ! root 640: newName = Cmd_Argv(1);
! 641: newName[15] = 0;
1.1 root 642: if (cmd_source == src_command)
643: {
644: if (Q_strcmp(cl_name.string, newName) == 0)
645: return;
646: Cvar_Set ("_cl_name", newName);
647: if (cls.state == ca_connected)
648: Cmd_ForwardToServer ();
649: return;
650: }
651:
652: if (host_client->name[0] && strcmp(host_client->name, "unconnected") )
653: if (Q_strcmp(host_client->name, newName) != 0)
654: Con_Printf ("%s renamed to %s\n", host_client->name, newName);
655: Q_strcpy (host_client->name, newName);
656: host_client->edict->v.netname = host_client->name - pr_strings;
657:
658: // send notification to all clients
659:
660: MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
661: MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
662: MSG_WriteString (&sv.reliable_datagram, host_client->name);
663: }
664:
665:
666: void Host_Version_f (void)
667: {
668: Con_Printf ("Version %4.2f\n", VERSION);
669: Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
670: }
671:
1.1.1.2 ! root 672: #ifdef DEBUG
1.1 root 673: void Host_Please_f (void)
674: {
675: client_t *cl;
676: int j;
677:
678: if (cmd_source != src_command)
679: return;
680:
681: if (Cmd_Argc () != 2)
682: return;
1.1.1.2 ! root 683:
1.1 root 684: for (j=0, cl = svs.clients ; j<svs.maxclients ; j++, cl++)
685: {
686: if (!cl->active)
687: continue;
688: if (Q_strcasecmp(cl->name, Cmd_Argv(1)) == 0)
689: {
690: if (cl->privileged)
691: {
692: cl->privileged = false;
693: cl->edict->v.flags = (int)cl->edict->v.flags & ~(FL_GODMODE|FL_NOTARGET);
694: cl->edict->v.movetype = MOVETYPE_WALK;
695: noclip_anglehack = false;
696: }
697: else
698: cl->privileged = true;
699: break;
700: }
701: }
702: }
703: #endif
704:
705:
706: void Host_Say(qboolean teamonly)
707: {
708: client_t *client;
709: client_t *save;
710: int j;
711: char *p;
712: unsigned char text[64];
713: qboolean fromServer = false;
714:
715: if (cmd_source == src_command)
716: {
717: if (cls.state == ca_dedicated)
718: {
719: fromServer = true;
720: teamonly = false;
721: }
722: else
723: {
724: Cmd_ForwardToServer ();
725: return;
726: }
727: }
728:
729: if (Cmd_Argc () < 2)
730: return;
731:
732: save = host_client;
733:
734: p = Cmd_Args();
735: // remove quotes if present
736: if (*p == '"')
737: {
738: p++;
739: p[Q_strlen(p)-1] = 0;
740: }
741:
742: // turn on color set 1
743: if (!fromServer)
744: sprintf (text, "%c%s: ", 1, save->name);
745: else
746: sprintf (text, "%c<%s> ", 1, hostname.string);
747:
748: j = sizeof(text) - 2 - Q_strlen(text); // -2 for /n and null terminator
749: if (Q_strlen(p) > j)
750: p[j] = 0;
751:
752: strcat (text, p);
753: strcat (text, "\n");
754:
755: for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++)
756: {
757: if (!client || !client->active || !client->spawned)
758: continue;
759: if (teamplay.value && teamonly && client->edict->v.team != save->edict->v.team)
760: continue;
761: host_client = client;
1.1.1.2 ! root 762: SV_ClientPrintf(text);
1.1 root 763: }
764: host_client = save;
765: }
766:
767:
768: void Host_Say_f(void)
769: {
770: Host_Say(false);
771: }
772:
773:
774: void Host_Say_Team_f(void)
775: {
776: Host_Say(true);
777: }
778:
779:
780: void Host_Tell_f(void)
781: {
782: client_t *client;
783: client_t *save;
784: int j;
785: char *p;
786: char text[80];
787:
788: if (cmd_source == src_command)
789: {
790: Cmd_ForwardToServer ();
791: return;
792: }
793:
794: if (Cmd_Argc () < 3)
795: return;
796:
797: save = host_client;
798: Q_strcpy(text, save->name);
799: Q_strcat(text, ": ");
800: p = Cmd_Args();
801:
802: p += Q_strlen(Cmd_Argv(1));
803: while (*p == ' ')
804: p++;
805:
806: if (*p != '"')
807: {
808: Q_strcat(text, p);
809: }
810: else
811: {
812: Q_strcat(text, p+1);
813: text[Q_strlen(text)-1] = 0;
814: }
815: Q_strcat(text, "\n");
816:
817: for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++)
818: {
819: if (!client->active || !client->spawned)
820: continue;
821: if (Q_strcasecmp(client->name, Cmd_Argv(1)))
822: continue;
823: host_client = client;
1.1.1.2 ! root 824: SV_ClientPrintf(text);
1.1 root 825: break;
826: }
827: host_client = save;
828: }
829:
830:
831: /*
832: ==================
833: Host_Color_f
834: ==================
835: */
836: void Host_Color_f(void)
837: {
838: int top, bottom;
839: int playercolor;
840:
841: if (Cmd_Argc() == 1)
842: {
843: Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color.value) >> 4, ((int)cl_color.value) & 0x0f);
844: Con_Printf ("color <0-13> [0-13]\n");
845: return;
846: }
847:
848: if (Cmd_Argc() == 2)
849: top = bottom = atoi(Cmd_Argv(1));
850: else
851: {
852: top = atoi(Cmd_Argv(1));
853: bottom = atoi(Cmd_Argv(2));
854: }
855:
856: top &= 15;
857: if (top > 13)
858: top = 13;
859: bottom &= 15;
860: if (bottom > 13)
861: bottom = 13;
862:
863: playercolor = top*16 + bottom;
864:
865: if (cmd_source == src_command)
866: {
867: Cvar_SetValue ("_cl_color", playercolor);
868: if (cls.state == ca_connected)
869: Cmd_ForwardToServer ();
870: return;
871: }
872:
873: host_client->colors = playercolor;
874: host_client->edict->v.team = bottom + 1;
875:
876: // send notification to all clients
877: MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
878: MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
879: MSG_WriteByte (&sv.reliable_datagram, host_client->colors);
880: }
881:
882: /*
883: ==================
884: Host_Kill_f
885: ==================
886: */
887: void Host_Kill_f (void)
888: {
889: if (cmd_source == src_command)
890: {
891: Cmd_ForwardToServer ();
892: return;
893: }
894:
895: if (sv_player->v.health <= 0)
896: {
897: SV_ClientPrintf ("Can't suicide -- allready dead!\n");
898: return;
899: }
900:
901: pr_global_struct->time = sv.time;
902: pr_global_struct->self = EDICT_TO_PROG(sv_player);
903: PR_ExecuteProgram (pr_global_struct->ClientKill);
904: }
905:
906: /*
907: ==================
908: Host_Pause_f
909: ==================
910: */
911: void Host_Pause_f (void)
912: {
913: extern cvar_t pausable;
914:
915: if (cmd_source == src_command)
916: {
917: Cmd_ForwardToServer ();
918: return;
919: }
920: if (!pausable.value)
921: SV_ClientPrintf ("Pause not allowed.\n");
922: else
923: {
924: sv.paused ^= 1;
925: if (sv.paused)
926: SV_BroadcastPrintf ("%s paused the game\n", pr_strings + sv_player->v.netname);
927: else
928: SV_BroadcastPrintf ("%s unpaused the game\n",pr_strings + sv_player->v.netname);
929: // send notification to all clients
930: MSG_WriteByte (&sv.reliable_datagram, svc_setpause);
931: MSG_WriteByte (&sv.reliable_datagram, sv.paused);
932: }
933: }
934:
935: //===========================================================================
936:
937:
938: /*
939: ==================
940: Host_PreSpawn_f
941: ==================
942: */
943: void Host_PreSpawn_f (void)
944: {
945: if (cmd_source == src_command)
946: {
947: Con_Printf ("prespawn is not valid from the console\n");
948: return;
949: }
950:
951: if (host_client->spawned)
952: {
953: Con_Printf ("prespawn not valid -- allready spawned\n");
954: return;
955: }
956:
957: SZ_Write (&host_client->message, sv.signon.data, sv.signon.cursize);
958: MSG_WriteByte (&host_client->message, svc_signonnum);
959: MSG_WriteByte (&host_client->message, 2);
960: host_client->sendsignon = true;
961: }
962:
963: /*
964: ==================
965: Host_Spawn_f
966: ==================
967: */
968: void Host_Spawn_f (void)
969: {
970: int i;
971: client_t *client;
972: edict_t *ent;
973:
974: if (cmd_source == src_command)
975: {
976: Con_Printf ("spawn is not valid from the console\n");
977: return;
978: }
979:
980: if (host_client->spawned)
981: {
982: Con_Printf ("Spawn not valid -- allready spawned\n");
983: return;
984: }
985:
986: // run the entrance script
987: if (sv.loadgame)
988: { // loaded games are fully inited allready
989: // if this is the last client to be connected, unpause
990: sv.paused = false;
991: }
992: else
993: {
994: // set up the edict
995: ent = host_client->edict;
996:
997: memset (&ent->v, 0, progs->entityfields * 4);
998: ent->v.colormap = NUM_FOR_EDICT(ent);
999: ent->v.team = (host_client->colors & 15) + 1;
1000: ent->v.netname = host_client->name - pr_strings;
1001:
1002: // copy spawn parms out of the client_t
1003:
1004: for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
1005: (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
1006:
1007: // call the spawn function
1008:
1009: pr_global_struct->time = sv.time;
1010: pr_global_struct->self = EDICT_TO_PROG(sv_player);
1011: PR_ExecuteProgram (pr_global_struct->ClientConnect);
1012:
1013: PR_ExecuteProgram (pr_global_struct->PutClientInServer);
1014: }
1015:
1016:
1017: // send all current names, colors, and frag counts
1018: SZ_Clear (&host_client->message);
1019:
1020: // send time of update
1021: MSG_WriteByte (&host_client->message, svc_time);
1022: MSG_WriteFloat (&host_client->message, sv.time);
1023:
1024: for (i=0, client = svs.clients ; i<svs.maxclients ; i++, client++)
1025: {
1026: MSG_WriteByte (&host_client->message, svc_updatename);
1027: MSG_WriteByte (&host_client->message, i);
1028: MSG_WriteString (&host_client->message, client->name);
1029: MSG_WriteByte (&host_client->message, svc_updatefrags);
1030: MSG_WriteByte (&host_client->message, i);
1031: MSG_WriteShort (&host_client->message, client->old_frags);
1032: MSG_WriteByte (&host_client->message, svc_updatecolors);
1033: MSG_WriteByte (&host_client->message, i);
1034: MSG_WriteByte (&host_client->message, client->colors);
1035: }
1036:
1037: // send all current light styles
1038: for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
1039: {
1040: MSG_WriteByte (&host_client->message, svc_lightstyle);
1041: MSG_WriteByte (&host_client->message, (char)i);
1042: MSG_WriteString (&host_client->message, sv.lightstyles[i]);
1043: }
1044:
1045: //
1046: // send some stats
1047: //
1048: MSG_WriteByte (&host_client->message, svc_updatestat);
1049: MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS);
1050: MSG_WriteLong (&host_client->message, pr_global_struct->total_secrets);
1051:
1052: MSG_WriteByte (&host_client->message, svc_updatestat);
1053: MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS);
1054: MSG_WriteLong (&host_client->message, pr_global_struct->total_monsters);
1055:
1056: MSG_WriteByte (&host_client->message, svc_updatestat);
1057: MSG_WriteByte (&host_client->message, STAT_SECRETS);
1058: MSG_WriteLong (&host_client->message, pr_global_struct->found_secrets);
1059:
1060: MSG_WriteByte (&host_client->message, svc_updatestat);
1061: MSG_WriteByte (&host_client->message, STAT_MONSTERS);
1062: MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters);
1063:
1064:
1065: //
1066: // send a fixangle
1067: // Never send a roll angle, because savegames can catch the server
1068: // in a state where it is expecting the client to correct the angle
1069: // and it won't happen if the game was just loaded, so you wind up
1070: // with a permanent head tilt
1071: ent = EDICT_NUM( 1 + (host_client - svs.clients) );
1072: MSG_WriteByte (&host_client->message, svc_setangle);
1073: for (i=0 ; i < 2 ; i++)
1074: MSG_WriteAngle (&host_client->message, ent->v.angles[i] );
1075: MSG_WriteAngle (&host_client->message, 0 );
1076:
1077: SV_WriteClientdataToMessage (sv_player, &host_client->message);
1078:
1079: MSG_WriteByte (&host_client->message, svc_signonnum);
1080: MSG_WriteByte (&host_client->message, 3);
1081: host_client->sendsignon = true;
1082: }
1083:
1084: /*
1085: ==================
1086: Host_Begin_f
1087: ==================
1088: */
1089: void Host_Begin_f (void)
1090: {
1091: if (cmd_source == src_command)
1092: {
1093: Con_Printf ("begin is not valid from the console\n");
1094: return;
1095: }
1096:
1097: host_client->spawned = true;
1098: }
1099:
1100: //===========================================================================
1101:
1102:
1103: /*
1104: ==================
1105: Host_Kick_f
1106:
1107: Kicks a user off of the server
1108: ==================
1109: */
1110: void Host_Kick_f (void)
1111: {
1112: char *who;
1113: char *message = NULL;
1114: client_t *save;
1115: int i;
1116:
1117: if (cmd_source == src_command)
1118: {
1119: if (!sv.active)
1120: {
1121: Cmd_ForwardToServer ();
1122: return;
1123: }
1124: }
1125: else if (pr_global_struct->deathmatch && !host_client->privileged)
1126: return;
1127:
1128: save = host_client;
1129:
1.1.1.2 ! root 1130: for (i = 0, host_client = svs.clients; i < svs.maxclients; i++, host_client++)
1.1 root 1131: {
1.1.1.2 ! root 1132: if (!host_client->active)
! 1133: continue;
! 1134: if (Q_strcasecmp(host_client->name, Cmd_Argv(1)) == 0)
! 1135: break;
1.1 root 1136: }
1137:
1138: if (i < svs.maxclients)
1139: {
1140: if (cmd_source == src_command)
1141: if (cls.state == ca_dedicated)
1142: who = "Console";
1143: else
1144: who = cl_name.string;
1145: else
1146: who = save->name;
1147:
1148: if (Cmd_Argc() > 2)
1149: {
1150: message = COM_Parse(Cmd_Args());
1151: while (*message && *message == ' ')
1152: message++;
1153: }
1154: if (message)
1155: SV_ClientPrintf ("Kicked by %s: %s\n", who, message);
1156: else
1157: SV_ClientPrintf ("Kicked by %s\n", who);
1158: SV_DropClient (false);
1159: }
1160:
1161: host_client = save;
1162: }
1163:
1164: /*
1165: ===============================================================================
1166:
1167: DEBUGGING TOOLS
1168:
1169: ===============================================================================
1170: */
1171:
1172: /*
1173: ==================
1174: Host_Give_f
1175: ==================
1176: */
1177: void Host_Give_f (void)
1178: {
1179: char *t;
1180: int v;
1181:
1182: if (cmd_source == src_command)
1183: {
1184: Cmd_ForwardToServer ();
1185: return;
1186: }
1187:
1188: if (pr_global_struct->deathmatch && !host_client->privileged)
1189: return;
1190:
1191: t = Cmd_Argv(1);
1192: v = atoi (Cmd_Argv(2));
1193:
1194: switch (t[0])
1195: {
1196: case '2':
1197: case '3':
1198: case '4':
1199: case '5':
1200: case '6':
1201: case '7':
1202: case '8':
1203: case '9':
1204: sv_player->v.items = (int)sv_player->v.items | IT_SHOTGUN<< (t[0] - '2');
1205: break;
1206:
1207: case 's':
1208: sv_player->v.ammo_shells = v;
1209: break;
1210: case 'n':
1211: sv_player->v.ammo_nails = v;
1212: break;
1213: case 'r':
1214: sv_player->v.ammo_rockets = v;
1215: break;
1216: case 'h':
1217: sv_player->v.health = v;
1218: break;
1219: case 'c':
1220: sv_player->v.ammo_cells = v;
1221: break;
1222: }
1223: }
1224:
1225: edict_t *FindViewthing (void)
1226: {
1227: int i;
1228: edict_t *e;
1229:
1230: for (i=0 ; i<sv.num_edicts ; i++)
1231: {
1232: e = EDICT_NUM(i);
1233: if ( !strcmp (pr_strings + e->v.classname, "viewthing") )
1234: return e;
1235: }
1236: Con_Printf ("No viewthing on map\n");
1237: return NULL;
1238: }
1239:
1240: /*
1241: ==================
1242: Host_Viewmodel_f
1243: ==================
1244: */
1245: void Host_Viewmodel_f (void)
1246: {
1247: edict_t *e;
1248: model_t *m;
1249:
1250: e = FindViewthing ();
1251: if (!e)
1252: return;
1253:
1254: m = Mod_ForName (Cmd_Argv(1), false);
1255: if (!m)
1256: {
1257: Con_Printf ("Can't load %s\n", Cmd_Argv(1));
1258: return;
1259: }
1260:
1261: e->v.frame = 0;
1262: cl.model_precache[(int)e->v.modelindex] = m;
1263: }
1264:
1265: /*
1266: ==================
1267: Host_Viewframe_f
1268: ==================
1269: */
1270: void Host_Viewframe_f (void)
1271: {
1272: edict_t *e;
1273: int f;
1274: model_t *m;
1275:
1276: e = FindViewthing ();
1277: if (!e)
1278: return;
1279: m = cl.model_precache[(int)e->v.modelindex];
1280:
1281: f = atoi(Cmd_Argv(1));
1282: if (f >= m->numframes)
1283: f = m->numframes-1;
1284:
1285: e->v.frame = f;
1286: }
1287:
1288:
1289: void PrintFrameName (model_t *m, int frame)
1290: {
1291: aliashdr_t *hdr;
1292: maliasframedesc_t *pframedesc;
1293:
1294: hdr = (aliashdr_t *)Mod_Extradata (m);
1295: if (!hdr)
1296: return;
1297: pframedesc = &hdr->frames[frame];
1298:
1299: Con_Printf ("frame %i: %s\n", frame, pframedesc->name);
1300: }
1301:
1302: /*
1303: ==================
1304: Host_Viewnext_f
1305: ==================
1306: */
1307: void Host_Viewnext_f (void)
1308: {
1309: edict_t *e;
1310: model_t *m;
1311:
1312: e = FindViewthing ();
1313: if (!e)
1314: return;
1315: m = cl.model_precache[(int)e->v.modelindex];
1316:
1317: e->v.frame = e->v.frame + 1;
1318: if (e->v.frame >= m->numframes)
1319: e->v.frame = m->numframes - 1;
1320:
1321: PrintFrameName (m, e->v.frame);
1322: }
1323:
1324: /*
1325: ==================
1326: Host_Viewprev_f
1327: ==================
1328: */
1329: void Host_Viewprev_f (void)
1330: {
1331: edict_t *e;
1332: model_t *m;
1333:
1334: e = FindViewthing ();
1335: if (!e)
1336: return;
1337:
1338: m = cl.model_precache[(int)e->v.modelindex];
1339:
1340: e->v.frame = e->v.frame - 1;
1341: if (e->v.frame < 0)
1342: e->v.frame = 0;
1343:
1344: PrintFrameName (m, e->v.frame);
1345: }
1346:
1347: /*
1348: ===============================================================================
1349:
1350: DEMO LOOP CONTROL
1351:
1352: ===============================================================================
1353: */
1354:
1355:
1356: /*
1357: ==================
1358: Host_Startdemos_f
1359: ==================
1360: */
1361: void Host_Startdemos_f (void)
1362: {
1363: int i, c;
1364:
1365: if (cls.state == ca_dedicated)
1366: {
1367: if (!sv.active)
1368: Cbuf_AddText ("map start\n");
1369: return;
1370: }
1371:
1372: c = Cmd_Argc() - 1;
1373: if (c > MAX_DEMOS)
1374: {
1375: Con_Printf ("Max %i demos in demoloop\n", MAX_DEMOS);
1376: c = MAX_DEMOS;
1377: }
1378: Con_Printf ("%i demo(s) in loop\n", c);
1379:
1380: for (i=1 ; i<c+1 ; i++)
1381: strncpy (cls.demos[i-1], Cmd_Argv(i), sizeof(cls.demos[0])-1);
1382:
1383: if (!sv.active && cls.demonum != -1 && !cls.demoplayback)
1384: {
1385: cls.demonum = 0;
1386: CL_NextDemo ();
1387: }
1388: else
1389: cls.demonum = -1;
1390: }
1391:
1392:
1393: /*
1394: ==================
1395: Host_Demos_f
1396:
1397: Return to looping demos
1398: ==================
1399: */
1400: void Host_Demos_f (void)
1401: {
1402: if (cls.state == ca_dedicated)
1403: return;
1404: if (cls.demonum == -1)
1405: cls.demonum = 1;
1406: CL_Disconnect_f ();
1407: CL_NextDemo ();
1408: }
1409:
1410: /*
1411: ==================
1412: Host_Stopdemo_f
1413:
1414: Return to looping demos
1415: ==================
1416: */
1417: void Host_Stopdemo_f (void)
1418: {
1419: if (cls.state == ca_dedicated)
1420: return;
1421: if (!cls.demoplayback)
1422: return;
1423: CL_StopPlayback ();
1424: CL_Disconnect ();
1425: }
1426:
1427: //=============================================================================
1428:
1429: /*
1430: ==================
1431: Host_InitCommands
1432: ==================
1433: */
1434: void Host_InitCommands (void)
1435: {
1436: Cmd_AddCommand ("status", Host_Status_f);
1437: Cmd_AddCommand ("quit", Host_Quit_f);
1438: Cmd_AddCommand ("god", Host_God_f);
1439: Cmd_AddCommand ("notarget", Host_Notarget_f);
1440: Cmd_AddCommand ("fly", Host_Fly_f);
1441: Cmd_AddCommand ("map", Host_Map_f);
1442: Cmd_AddCommand ("restart", Host_Restart_f);
1443: Cmd_AddCommand ("changelevel", Host_Changelevel_f);
1444: Cmd_AddCommand ("connect", Host_Connect_f);
1445: Cmd_AddCommand ("reconnect", Host_Reconnect_f);
1446: Cmd_AddCommand ("name", Host_Name_f);
1447: Cmd_AddCommand ("noclip", Host_Noclip_f);
1448: Cmd_AddCommand ("version", Host_Version_f);
1.1.1.2 ! root 1449: #ifdef DEBUG
1.1 root 1450: Cmd_AddCommand ("please", Host_Please_f);
1451: #endif
1452: Cmd_AddCommand ("say", Host_Say_f);
1453: Cmd_AddCommand ("say_team", Host_Say_Team_f);
1454: Cmd_AddCommand ("tell", Host_Tell_f);
1455: Cmd_AddCommand ("color", Host_Color_f);
1456: Cmd_AddCommand ("kill", Host_Kill_f);
1457: Cmd_AddCommand ("pause", Host_Pause_f);
1458: Cmd_AddCommand ("spawn", Host_Spawn_f);
1459: Cmd_AddCommand ("begin", Host_Begin_f);
1460: Cmd_AddCommand ("prespawn", Host_PreSpawn_f);
1461: Cmd_AddCommand ("kick", Host_Kick_f);
1462: Cmd_AddCommand ("ping", Host_Ping_f);
1463: Cmd_AddCommand ("load", Host_Loadgame_f);
1464: Cmd_AddCommand ("save", Host_Savegame_f);
1465: Cmd_AddCommand ("give", Host_Give_f);
1466:
1467: Cmd_AddCommand ("startdemos", Host_Startdemos_f);
1468: Cmd_AddCommand ("demos", Host_Demos_f);
1469: Cmd_AddCommand ("stopdemo", Host_Stopdemo_f);
1470:
1471: Cmd_AddCommand ("viewmodel", Host_Viewmodel_f);
1472: Cmd_AddCommand ("viewframe", Host_Viewframe_f);
1473: Cmd_AddCommand ("viewnext", Host_Viewnext_f);
1474: Cmd_AddCommand ("viewprev", Host_Viewprev_f);
1475: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.