Annotation of quake2/client/cl_parse.c, revision 1.1.1.1

1.1       root        1: // cl_parse.c  -- parse a message received from the server
                      2: 
                      3: #include "client.h"
                      4: 
                      5: char *svc_strings[256] =
                      6: {
                      7:        "svc_bad",
                      8: 
                      9:        "svc_muzzleflash",
                     10:        "svc_muzzlflash2",
                     11:        "svc_temp_entity",
                     12:        "svc_layout",
                     13:        "svc_inventory",
                     14: 
                     15:        "svc_nop",
                     16:        "svc_disconnect",
                     17:        "svc_reconnect",
                     18:        "svc_sound",
                     19:        "svc_print",
                     20:        "svc_stufftext",
                     21:        "svc_serverdata",
                     22:        "svc_configstring",
                     23:        "svc_spawnbaseline",    
                     24:        "svc_centerprint",
                     25:        "svc_download",
                     26:        "svc_playerinfo",
                     27:        "svc_packetentities",
                     28:        "svc_deltapacketentities",
                     29:        "svc_frame"
                     30: };
                     31: 
                     32: //=============================================================================
                     33: 
                     34: /*
                     35: ===============
                     36: CL_CheckOrDownloadFile
                     37: 
                     38: Returns true if the file exists, otherwise it attempts
                     39: to start a download from the server.
                     40: ===============
                     41: */
                     42: qboolean       CL_CheckOrDownloadFile (char *filename)
                     43: {
                     44:        if (strstr (filename, ".."))
                     45:        {
                     46:                Com_Printf ("Refusing to download a path with ..\n");
                     47:                return true;
                     48:        }
                     49: 
                     50:        if (FS_LoadFile (filename, NULL) != -1)
                     51:        {       // it exists, no need to download
                     52:                return true;
                     53:        }
                     54: 
                     55:        strcpy (cls.downloadname, filename);
                     56:        Com_Printf ("Downloading %s\n", cls.downloadname);
                     57: 
                     58:        // download to a temp name, and only rename
                     59:        // to the real name when done, so if interrupted
                     60:        // a runt file wont be left
                     61:        COM_StripExtension (cls.downloadname, cls.downloadtempname);
                     62:        strcat (cls.downloadtempname, ".tmp");
                     63: 
                     64:        MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
                     65:        MSG_WriteString (&cls.netchan.message,
                     66:                va("download %s", cls.downloadname));
                     67: 
                     68:        cls.downloadnumber++;
                     69: 
                     70:        return false;
                     71: }
                     72: 
                     73: 
                     74: /*
                     75: ======================
                     76: CL_RegisterSounds
                     77: ======================
                     78: */
                     79: void CL_RegisterSounds (void)
                     80: {
                     81:        int             i;
                     82: 
                     83:        S_BeginRegistration ();
                     84:        CL_RegisterTEntSounds ();
                     85:        for (i=1 ; i<MAX_SOUNDS ; i++)
                     86:        {
                     87:                if (!cl.configstrings[CS_SOUNDS+i][0])
                     88:                        break;
                     89:                cl.sound_precache[i] = S_RegisterSound (cl.configstrings[CS_SOUNDS+i]);
                     90:                Sys_SendKeyEvents ();   // pump message loop
                     91:        }
                     92:        S_EndRegistration ();
                     93: }
                     94: 
                     95: 
                     96: /*
                     97: ======================
                     98: CL_RequestNextDownload
                     99: ======================
                    100: */
                    101: void CL_RequestNextDownload (void)
                    102: {
                    103: }
                    104: 
                    105: /*
                    106: =====================
                    107: CL_ParseDownload
                    108: 
                    109: A download message has been received from the server
                    110: =====================
                    111: */
                    112: void CL_ParseDownload (void)
                    113: {
                    114:        int             size, percent;
                    115:        char    name[MAX_OSPATH];
                    116:        int             r;
                    117: 
                    118:        // read the data
                    119:        size = MSG_ReadShort (&net_message);
                    120:        percent = MSG_ReadByte (&net_message);
                    121:        if (size == -1)
                    122:        {
                    123:                Com_Printf ("File not found.\n");
                    124:                if (cls.download)
                    125:                {
                    126:                        Com_Printf ("cls.download shouldn't have been set\n");
                    127:                        fclose (cls.download);
                    128:                        cls.download = NULL;
                    129:                }
                    130:                CL_RequestNextDownload ();
                    131:                return;
                    132:        }
                    133: 
                    134:        // open the file if not opened yet
                    135:        if (!cls.download)
                    136:        {
                    137:                Com_sprintf (name, sizeof(name), "%s/%s", FS_Gamedir(), cls.downloadtempname);
                    138: 
                    139:                FS_CreatePath (name);
                    140: 
                    141:                cls.download = fopen (name, "wb");
                    142:                if (!cls.download)
                    143:                {
                    144:                        net_message.readcount += size;
                    145:                        Com_Printf ("Failed to open %s\n", cls.downloadtempname);
                    146:                        CL_RequestNextDownload ();
                    147:                        return;
                    148:                }
                    149:        }
                    150: 
                    151:        fwrite (net_message.data + net_message.readcount, 1, size, cls.download);
                    152:        net_message.readcount += size;
                    153: 
                    154:        if (percent != 100)
                    155:        {
                    156:                // request next block
                    157:                Com_Printf (".");
                    158:                if (10*(percent/10) != cls.downloadpercent)
                    159:                {
                    160:                        cls.downloadpercent = 10*(percent/10);
                    161:                        Com_Printf ("%i%%", cls.downloadpercent);
                    162:                }
                    163:                MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
                    164:                SZ_Print (&cls.netchan.message, "nextdl");
                    165:        }
                    166:        else
                    167:        {
                    168:                char    oldn[MAX_OSPATH];
                    169:                char    newn[MAX_OSPATH];
                    170: 
                    171:                Com_Printf ("100%%\n");
                    172: 
                    173:                fclose (cls.download);
                    174: 
                    175:                // rename the temp file to it's final name
                    176:                Com_sprintf (oldn, sizeof(oldn), "%s/%s", FS_Gamedir(), cls.downloadtempname);
                    177:                Com_sprintf (newn, sizeof(newn), "%s/%s", FS_Gamedir(), cls.downloadname);
                    178:                r = rename (oldn, newn);
                    179:                if (r)
                    180:                        Com_Printf ("failed to rename.\n");
                    181: 
                    182:                cls.download = NULL;
                    183:                cls.downloadpercent = 0;
                    184: 
                    185:                // get another file if needed
                    186: 
                    187:                CL_RequestNextDownload ();
                    188:        }
                    189: }
                    190: 
                    191: 
                    192: /*
                    193: =====================================================================
                    194: 
                    195:   SERVER CONNECTING MESSAGES
                    196: 
                    197: =====================================================================
                    198: */
                    199: 
                    200: /*
                    201: ==================
                    202: CL_ParseServerData
                    203: ==================
                    204: */
                    205: void CL_ParseServerData (void)
                    206: {
                    207:        extern cvar_t   *fs_gamedirvar;
                    208:        char    *str;
                    209:        int             i;
                    210:        
                    211:        Com_DPrintf ("Serverdata packet received.\n");
                    212: //
                    213: // wipe the client_state_t struct
                    214: //
                    215:        CL_ClearState ();
                    216:        cls.state = ca_connected;
                    217: 
                    218: // parse protocol version number
                    219:        i = MSG_ReadLong (&net_message);
                    220:        cls.serverProtocol = i;
                    221: 
                    222:        // BIG HACK to let demos from release work with the 3.0x patch!!!
                    223:        if (Com_ServerState() && PROTOCOL_VERSION == 31)
                    224:        {
                    225:        }
                    226:        else if (i != PROTOCOL_VERSION)
                    227:                Com_Error (ERR_DROP,"Server returned version %i, not %i", i, PROTOCOL_VERSION);
                    228: 
                    229:        cl.servercount = MSG_ReadLong (&net_message);
                    230:        cl.attractloop = MSG_ReadByte (&net_message);
                    231: 
                    232:        // game directory
                    233:        str = MSG_ReadString (&net_message);
                    234:        strncpy (cl.gamedir, str, sizeof(cl.gamedir)-1);
                    235: 
                    236:        // set gamedir
                    237:        if ((*str && (!fs_gamedirvar->string || !*fs_gamedirvar->string || strcmp(fs_gamedirvar->string, str))) || (!*str && (fs_gamedirvar->string || *fs_gamedirvar->string)))
                    238:                Cvar_Set("game", str);
                    239: 
                    240:        // parse player entity number
                    241:        cl.playernum = MSG_ReadShort (&net_message);
                    242: 
                    243:        // get the full level name
                    244:        str = MSG_ReadString (&net_message);
                    245: 
                    246:        if (cl.playernum == -1)
                    247:        {       // playing a cinematic or showing a pic, not a level
                    248:                SCR_PlayCinematic (str);
                    249:        }
                    250:        else
                    251:        {
                    252:                // seperate the printfs so the server message can have a color
                    253:                Com_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
                    254:                Com_Printf ("%c%s\n", 2, str);
                    255: 
                    256:                // need to prep refresh at next oportunity
                    257:                cl.refresh_prepped = false;
                    258:        }
                    259: }
                    260: 
                    261: /*
                    262: ==================
                    263: CL_ParseBaseline
                    264: ==================
                    265: */
                    266: void CL_ParseBaseline (void)
                    267: {
                    268:        entity_state_t  *es;
                    269:        int                             bits;
                    270:        int                             newnum;
                    271:        entity_state_t  nullstate;
                    272: 
                    273:        memset (&nullstate, 0, sizeof(nullstate));
                    274: 
                    275:        newnum = CL_ParseEntityBits (&bits);
                    276:        es = &cl_entities[newnum].baseline;
                    277:        CL_ParseDelta (&nullstate, es, newnum, bits);
                    278: }
                    279: 
                    280: 
                    281: /*
                    282: ================
                    283: CL_LoadClientinfo
                    284: 
                    285: ================
                    286: */
                    287: void CL_LoadClientinfo (clientinfo_t *ci, char *s)
                    288: {
                    289:        char            *t;
                    290:        char            model_name[MAX_QPATH];
                    291:        char            skin_name[MAX_QPATH];
                    292:        char            model_filename[MAX_QPATH];
                    293:        char            skin_filename[MAX_QPATH];
                    294:        char            weapon_filename[MAX_QPATH];
                    295: 
                    296:        // isolate the player's name
                    297:        strcpy (ci->name, s);
                    298:        t = strstr (s, "\\");
                    299:        if (t)
                    300:        {
                    301:                ci->name[t-s] = 0;
                    302:                s = t+1;
                    303:        }
                    304: 
                    305:        if (cl_noskins->value || *s == 0)
                    306:        {
                    307:                Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
                    308:                Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/weapon.md2");
                    309:                Com_sprintf (skin_filename, sizeof(skin_filename), "players/male/grunt.pcx");
                    310:                Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/male/grunt_i.pcx");
                    311:                ci->model = re.RegisterModel (model_filename);
                    312:                ci->weaponmodel = re.RegisterModel (weapon_filename);
                    313:                ci->skin = re.RegisterSkin (skin_filename);
                    314:                ci->icon = re.RegisterPic (ci->iconname);
                    315:        }
                    316:        else
                    317:        {
                    318:                // isolate the model name
                    319:                strcpy (model_name, s);
                    320:                t = strstr(model_name, "/");
                    321:                if (!t)
                    322:                        t = strstr(model_name, "\\");
                    323:                if (!t)
                    324:                        t = model_name;
                    325:                *t = 0;
                    326: 
                    327:                // isolate the skin name
                    328:                strcpy (skin_name, s + strlen(model_name) + 1);
                    329: 
                    330:                // model file
                    331:                Com_sprintf (model_filename, sizeof(model_filename), "players/%s/tris.md2", model_name);
                    332:                ci->model = re.RegisterModel (model_filename);
                    333:                if (!ci->model)
                    334:                {
                    335:                        strcpy(model_name, "male");
                    336:                        Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
                    337:                        ci->model = re.RegisterModel (model_filename);
                    338:                }
                    339: 
                    340:                // skin file
                    341:                Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
                    342:                ci->skin = re.RegisterSkin (skin_filename);
                    343: 
                    344:                // if we don't have the skin and the model wasn't male,
                    345:                // see if the male has it (this is for CTF's skins)
                    346:                if (!ci->skin && stricmp(model_name, "male"))
                    347:                {
                    348:                        // change model to male
                    349:                        strcpy(model_name, "male");
                    350:                        Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
                    351:                        ci->model = re.RegisterModel (model_filename);
                    352: 
                    353:                        // see if the skin exists for the male model
                    354:                        Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
                    355:                        ci->skin = re.RegisterSkin (skin_filename);
                    356:                }
                    357: 
                    358:                // weapon file
                    359:                Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/%s/weapon.md2", model_name);
                    360:                ci->weaponmodel = re.RegisterModel (weapon_filename);
                    361: 
                    362:                // icon file
                    363:                Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/%s/%s_i.pcx", model_name, skin_name);
                    364:                ci->icon = re.RegisterPic (ci->iconname);
                    365:        }
                    366: 
                    367:        // must have loaded all data types to be valud
                    368:        if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel)
                    369:        {
                    370:                ci->skin = NULL;
                    371:                ci->icon = NULL;
                    372:                ci->model = NULL;
                    373:                ci->weaponmodel = NULL;
                    374:                return;
                    375:        }
                    376: }
                    377: 
                    378: /*
                    379: ================
                    380: CL_ParseClientinfo
                    381: 
                    382: Load the skin, icon, and model for a client
                    383: ================
                    384: */
                    385: void CL_ParseClientinfo (int player)
                    386: {
                    387:        char                    *s;
                    388:        clientinfo_t    *ci;
                    389: 
                    390:        s = cl.configstrings[player+CS_PLAYERSKINS];
                    391: 
                    392:        ci = &cl.clientinfo[player];
                    393: 
                    394:        CL_LoadClientinfo (ci, s);
                    395: }
                    396: 
                    397: 
                    398: /*
                    399: ================
                    400: CL_ParseConfigString
                    401: ================
                    402: */
                    403: void CL_ParseConfigString (void)
                    404: {
                    405:        int             i;
                    406:        char    *s;
                    407: 
                    408:        i = MSG_ReadShort (&net_message);
                    409:        if (i < 0 || i >= MAX_CONFIGSTRINGS)
                    410:                Com_Error (ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
                    411:        s = MSG_ReadString(&net_message);
                    412:        strcpy (cl.configstrings[i], s);
                    413: 
                    414:        // do something apropriate 
                    415: 
                    416:        if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
                    417:                CL_SetLightstyle (i - CS_LIGHTS);
                    418:        else if (i == CS_CDTRACK)
                    419:        {
                    420:                if (cl.refresh_prepped)
                    421:                        CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true);
                    422:        }
                    423:        else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
                    424:        {
                    425:                if (cl.refresh_prepped)
                    426:                {
                    427:                        cl.model_draw[i-CS_MODELS] = re.RegisterModel (cl.configstrings[i]);
                    428:                        if (cl.configstrings[i][0] == '*')
                    429:                                cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]);
                    430:                        else
                    431:                                cl.model_clip[i-CS_MODELS] = NULL;
                    432:                }
                    433:        }
                    434:        else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_MODELS)
                    435:        {
                    436:                if (cl.refresh_prepped)
                    437:                        cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
                    438:        }
                    439:        else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_MODELS)
                    440:        {
                    441:                if (cl.refresh_prepped)
                    442:                        cl.image_precache[i-CS_IMAGES] = re.RegisterPic (cl.configstrings[i]);
                    443:        }
                    444:        else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
                    445:        {
                    446:                if (cl.refresh_prepped)
                    447:                        CL_ParseClientinfo (i-CS_PLAYERSKINS);
                    448:        }
                    449: }
                    450: 
                    451: 
                    452: /*
                    453: =====================================================================
                    454: 
                    455: ACTION MESSAGES
                    456: 
                    457: =====================================================================
                    458: */
                    459: 
                    460: /*
                    461: ==================
                    462: CL_ParseStartSoundPacket
                    463: ==================
                    464: */
                    465: void CL_ParseStartSoundPacket(void)
                    466: {
                    467:     vec3_t  pos_v;
                    468:        float   *pos;
                    469:     int        channel, ent;
                    470:     int        sound_num;
                    471:     float      volume;
                    472:     float      attenuation;  
                    473:        int             flags;
                    474:        float   ofs;
                    475: 
                    476:        flags = MSG_ReadByte (&net_message);
                    477:        sound_num = MSG_ReadByte (&net_message);
                    478: 
                    479:     if (flags & SND_VOLUME)
                    480:                volume = MSG_ReadByte (&net_message) / 255.0;
                    481:        else
                    482:                volume = DEFAULT_SOUND_PACKET_VOLUME;
                    483:        
                    484:     if (flags & SND_ATTENUATION)
                    485:                attenuation = MSG_ReadByte (&net_message) / 64.0;
                    486:        else
                    487:                attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; 
                    488: 
                    489:     if (flags & SND_OFFSET)
                    490:                ofs = MSG_ReadByte (&net_message) / 1000.0;
                    491:        else
                    492:                ofs = 0;
                    493: 
                    494:        if (flags & SND_ENT)
                    495:        {       // entity reletive
                    496:                channel = MSG_ReadShort(&net_message); 
                    497:                ent = channel>>3;
                    498:                if (ent > MAX_EDICTS)
                    499:                        Com_Error (ERR_DROP,"CL_ParseStartSoundPacket: ent = %i", ent);
                    500: 
                    501:                channel &= 7;
                    502:        }
                    503:        else
                    504:        {
                    505:                ent = 0;
                    506:                channel = 0;
                    507:        }
                    508: 
                    509:        if (flags & SND_POS)
                    510:        {       // positioned in space
                    511:                MSG_ReadPos (&net_message, pos_v);
                    512:  
                    513:                pos = pos_v;
                    514:        }
                    515:        else    // use entity number
                    516:                pos = NULL;
                    517: 
                    518:        if (!cl.sound_precache[sound_num])
                    519:                return;
                    520: 
                    521:        S_StartSound (pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation, ofs);
                    522: }       
                    523: 
                    524: 
                    525: void SHOWNET(char *s)
                    526: {
                    527:        if (cl_shownet->value>=2)
                    528:                Com_Printf ("%3i:%s\n", net_message.readcount-1, s);
                    529: }
                    530: 
                    531: /*
                    532: =====================
                    533: CL_ParseServerMessage
                    534: =====================
                    535: */
                    536: void CL_ParseServerMessage (void)
                    537: {
                    538:        int                     cmd;
                    539:        char            *s;
                    540:        int                     i;
                    541: 
                    542: //
                    543: // if recording demos, copy the message out
                    544: //
                    545:        if (cl_shownet->value == 1)
                    546:                Com_Printf ("%i ",net_message.cursize);
                    547:        else if (cl_shownet->value >= 2)
                    548:                Com_Printf ("------------------\n");
                    549: 
                    550: 
                    551: //
                    552: // parse the message
                    553: //
                    554:        while (1)
                    555:        {
                    556:                if (net_message.readcount > net_message.cursize)
                    557:                {
                    558:                        Com_Error (ERR_DROP,"CL_ParseServerMessage: Bad server message");
                    559:                        break;
                    560:                }
                    561: 
                    562:                cmd = MSG_ReadByte (&net_message);
                    563: 
                    564:                if (cmd == -1)
                    565:                {
                    566:                        SHOWNET("END OF MESSAGE");
                    567:                        break;
                    568:                }
                    569: 
                    570:                if (cl_shownet->value>=2)
                    571:                {
                    572:                        if (!svc_strings[cmd])
                    573:                                Com_Printf ("%3i:BAD CMD %i\n", net_message.readcount-1,cmd);
                    574:                        else
                    575:                                SHOWNET(svc_strings[cmd]);
                    576:                }
                    577:        
                    578:        // other commands
                    579:                switch (cmd)
                    580:                {
                    581:                default:
                    582:                        Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n");
                    583:                        break;
                    584:                        
                    585:                case svc_nop:
                    586: //                     Com_Printf ("svc_nop\n");
                    587:                        break;
                    588:                        
                    589:                case svc_disconnect:
                    590:                        Com_Error (ERR_DISCONNECT,"Server disconnected\n");
                    591:                        break;
                    592: 
                    593:                case svc_reconnect:
                    594:                        Com_Printf ("Server disconnected, reconnecting\n");
                    595:                        cls.state = ca_connecting;
                    596:                        cls.connect_time = -99999;      // CL_CheckForResend() will fire immediately
                    597:                        break;
                    598: 
                    599:                case svc_print:
                    600:                        i = MSG_ReadByte (&net_message);
                    601:                        if (i == PRINT_CHAT)
                    602:                        {
                    603:                                S_StartLocalSound ("misc/talk.wav");
                    604:                                con.ormask = 128;
                    605:                        }
                    606:                        Com_Printf ("%s", MSG_ReadString (&net_message));
                    607:                        con.ormask = 0;
                    608:                        break;
                    609:                        
                    610:                case svc_centerprint:
                    611:                        SCR_CenterPrint (MSG_ReadString (&net_message));
                    612:                        break;
                    613:                        
                    614:                case svc_stufftext:
                    615:                        s = MSG_ReadString (&net_message);
                    616:                        Com_DPrintf ("stufftext: %s\n", s);
                    617:                        Cbuf_AddText (s);
                    618:                        break;
                    619:                        
                    620:                case svc_serverdata:
                    621:                        Cbuf_Execute ();                // make sure any stuffed commands are done
                    622:                        CL_ParseServerData ();
                    623:                        break;
                    624:                        
                    625:                case svc_configstring:
                    626:                        CL_ParseConfigString ();
                    627:                        break;
                    628:                        
                    629:                case svc_sound:
                    630:                        CL_ParseStartSoundPacket();
                    631:                        break;
                    632:                        
                    633:                case svc_spawnbaseline:
                    634:                        CL_ParseBaseline ();
                    635:                        break;
                    636: 
                    637:                case svc_temp_entity:
                    638:                        CL_ParseTEnt ();
                    639:                        break;
                    640: 
                    641:                case svc_muzzleflash:
                    642:                        CL_ParseMuzzleFlash ();
                    643:                        break;
                    644: 
                    645:                case svc_muzzleflash2:
                    646:                        CL_ParseMuzzleFlash2 ();
                    647:                        break;
                    648: 
                    649:                case svc_download:
                    650:                        CL_ParseDownload ();
                    651:                        break;
                    652: 
                    653:                case svc_frame:
                    654:                        CL_ParseFrame ();
                    655:                        break;
                    656: 
                    657:                case svc_inventory:
                    658:                        CL_ParseInventory ();
                    659:                        break;
                    660: 
                    661:                case svc_layout:
                    662:                        s = MSG_ReadString (&net_message);
                    663:                        strncpy (cl.layout, s, sizeof(cl.layout)-1);
                    664:                        break;
                    665: 
                    666:                case svc_playerinfo:
                    667:                case svc_packetentities:
                    668:                case svc_deltapacketentities:
                    669:                        Com_Error (ERR_DROP, "Out of place frame data");
                    670:                        break;
                    671:                }
                    672:        }
                    673: 
                    674:        CL_AddNetgraph ();
                    675: 
                    676:        //
                    677:        // we don't know if it is ok to save a demo message until
                    678:        // after we have parsed the frame
                    679:        //
                    680:        if (cls.demorecording && !cls.demowaiting)
                    681:                CL_WriteDemoMessage ();
                    682: 
                    683: }
                    684: 
                    685: 

unix.superglobalmegacorp.com

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