Annotation of quake1/host_cmd.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.