Annotation of quake1/cl_parse.c, revision 1.1.1.2

1.1       root        1: // cl_parse.c  -- parse a message received from the server
                      2: 
                      3: #include "quakedef.h"
                      4: 
                      5: char *svc_strings[] =
                      6: {
                      7:        "svc_bad",
                      8:        "svc_nop",
                      9:        "svc_disconnect",
                     10:        "svc_updatestat",
                     11:        "svc_version",          // [long] server version
                     12:        "svc_setview",          // [short] entity number
                     13:        "svc_sound",                    // <see code>
                     14:        "svc_time",                     // [float] server time
                     15:        "svc_print",                    // [string] null terminated string
                     16:        "svc_stufftext",                // [string] stuffed into client's console buffer
                     17:                                                // the string should be \n terminated
                     18:        "svc_setangle",         // [vec3] set the view angle to this absolute value
                     19:        
                     20:        "svc_serverinfo",               // [long] version
                     21:                                                // [string] signon string
                     22:                                                // [string]..[0]model cache [string]...[0]sounds cache
                     23:                                                // [string]..[0]item cache
                     24:        "svc_lightstyle",               // [byte] [string]
                     25:        "svc_updatename",               // [byte] [string]
                     26:        "svc_updatefrags",      // [byte] [short]
                     27:        "svc_clientdata",               // <shortbits + data>
                     28:        "svc_stopsound",                // <see code>
                     29:        "svc_updatecolors",     // [byte] [byte]
                     30:        "svc_particle",         // [vec3] <variable>
                     31:        "svc_damage",                   // [byte] impact [byte] blood [vec3] from
                     32:        
                     33:        "svc_spawnstatic",
                     34:        "OBSOLETE svc_spawnbinary",
                     35:        "svc_spawnbaseline",
                     36:        
                     37:        "svc_temp_entity",              // <variable>
                     38:        "svc_setpause",
                     39:        "svc_signonnum",
                     40:        "svc_centerprint",
                     41:        "svc_killedmonster",
                     42:        "svc_foundsecret",
                     43:        "svc_spawnstaticsound",
                     44:        "svc_intermission"
                     45: };
                     46: 
                     47: //=============================================================================
                     48: 
                     49: /*
                     50: ===============
                     51: CL_EntityNum
                     52: 
                     53: This error checks and tracks the total number of entities
                     54: ===============
                     55: */
                     56: entity_t       *CL_EntityNum (int num)
                     57: {
                     58:        if (num >= cl.num_entities)
                     59:        {
                     60:                if (num >= MAX_EDICTS)
                     61:                        Host_Error ("CL_EntityNum: %i is an invalid number",num);
                     62:                while (cl.num_entities<=num)
                     63:                {
                     64:                        cl_entities[cl.num_entities].colormap = vid.colormap;
                     65:                        cl.num_entities++;
                     66:                }
                     67:        }
                     68:                
                     69:        return &cl_entities[num];
                     70: }
                     71: 
                     72: 
                     73: /*
                     74: ==================
                     75: CL_ParseStartSoundPacket
                     76: ==================
                     77: */
                     78: void CL_ParseStartSoundPacket(void)
                     79: {
                     80:     vec3_t  pos;
                     81:     int        channel, ent;
                     82:     int        sound_num;
                     83:     int        volume;
                     84:     int        field_mask;
                     85:     float      attenuation;  
                     86:        int             i;
                     87:                   
                     88:     field_mask = MSG_ReadByte(); 
                     89: 
                     90:     if (field_mask & SND_VOLUME)
                     91:                volume = MSG_ReadByte ();
                     92:        else
                     93:                volume = DEFAULT_SOUND_PACKET_VOLUME;
                     94:        
                     95:     if (field_mask & SND_ATTENUATION)
                     96:                attenuation = MSG_ReadByte () / 64.0;
                     97:        else
                     98:                attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
                     99:        
                    100:        channel = MSG_ReadShort ();
                    101:        sound_num = MSG_ReadByte ();
                    102: 
                    103:        ent = channel >> 3;
                    104:        channel &= 7;
                    105: 
                    106:        if (ent > MAX_EDICTS)
                    107:                Host_Error ("CL_ParseStartSoundPacket: ent = %i", ent);
                    108:        
                    109:        for (i=0 ; i<3 ; i++)
                    110:                pos[i] = MSG_ReadCoord ();
                    111:  
                    112:     S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
                    113: }       
                    114: 
                    115: /*
                    116: ==================
                    117: CL_KeepaliveMessage
                    118: 
                    119: When the client is taking a long time to load stuff, send keepalive messages
                    120: so the server doesn't disconnect.
                    121: ==================
                    122: */
                    123: void CL_KeepaliveMessage (void)
                    124: {
                    125:        float   time;
                    126:        static float lastmsg;
                    127:        int             ret;
                    128:        sizebuf_t       old;
                    129:        byte            olddata[8192];
                    130:        
                    131:        if (sv.active)
                    132:                return;         // no need if server is local
                    133:        if (cls.demoplayback)
                    134:                return;
                    135: 
                    136: // read messages from server, should just be nops
                    137:        old = net_message;
                    138:        memcpy (olddata, net_message.data, net_message.cursize);
                    139:        
                    140:        do
                    141:        {
                    142:                ret = CL_GetMessage ();
                    143:                switch (ret)
                    144:                {
                    145:                default:
                    146:                        Host_Error ("CL_KeepaliveMessage: CL_GetMessage failed");               
                    147:                case 0:
                    148:                        break;  // nothing waiting
                    149:                case 1:
                    150:                        Host_Error ("CL_KeepaliveMessage: received a message");
                    151:                        break;
                    152:                case 2:
                    153:                        if (MSG_ReadByte() != svc_nop)
                    154:                                Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop");
                    155:                        break;
                    156:                }
                    157:        } while (ret);
                    158: 
                    159:        net_message = old;
                    160:        memcpy (net_message.data, olddata, net_message.cursize);
                    161: 
                    162: // check time
                    163:        time = Sys_FloatTime ();
                    164:        if (time - lastmsg < 5)
                    165:                return;
                    166:        lastmsg = time;
                    167: 
                    168: // write out a nop
                    169:        Con_Printf ("--> client to server keepalive\n");
                    170: 
                    171:        MSG_WriteByte (&cls.message, clc_nop);
                    172:        NET_SendMessage (cls.netcon, &cls.message);
                    173:        SZ_Clear (&cls.message);
                    174: }
                    175: 
                    176: /*
                    177: ==================
                    178: CL_ParseServerInfo
                    179: ==================
                    180: */
                    181: void CL_ParseServerInfo (void)
                    182: {
                    183:        char    *str;
                    184:        int             i;
                    185:        int             nummodels, numsounds;
                    186:        char    model_precache[MAX_MODELS][MAX_QPATH];
                    187:        char    sound_precache[MAX_SOUNDS][MAX_QPATH];
                    188:        
                    189:        Con_DPrintf ("Serverinfo packet received.\n");
                    190: //
                    191: // wipe the client_state_t struct
                    192: //
                    193:        CL_ClearState ();
                    194: 
                    195: // parse protocol version number
                    196:        i = MSG_ReadLong ();
                    197:        if (i != PROTOCOL_VERSION)
1.1.1.2 ! root      198:                Host_Error ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
1.1       root      199: 
                    200: // parse maxclients
                    201:        cl.maxclients = MSG_ReadByte ();
1.1.1.2 ! root      202:        if (cl.maxclients == 0)
        !           203:                Sys_Error ("Bad maxclients from server"); 
1.1       root      204:        cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");
                    205: 
                    206: // parse gametype
                    207:        cl.gametype = MSG_ReadByte ();
                    208: 
                    209: // parse signon message
                    210:        str = MSG_ReadString ();
                    211:        strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
                    212: 
                    213: // seperate the printfs so the server message can have a color
                    214:        Con_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");
                    215:        Con_Printf ("%c%s\n", 2, str);
                    216: 
                    217: //
                    218: // first we go through and touch all of the precache data that still
                    219: // happens to be in the cache, so precaching something else doesn't
                    220: // needlessly purge it
                    221: //
                    222: 
                    223: // precache models
                    224:        memset (cl.model_precache, 0, sizeof(cl.model_precache));
                    225:        for (nummodels=1 ; ; nummodels++)
                    226:        {
                    227:                str = MSG_ReadString ();
                    228:                if (!str[0])
                    229:                        break;
                    230:                if (nummodels==MAX_MODELS)
1.1.1.2 ! root      231:                        Host_Error ("Server sent too many model_precache");
1.1       root      232:                strcpy (model_precache[nummodels], str);
                    233:                Mod_TouchModel (str);
                    234:        }
                    235: 
                    236: // precache sounds
                    237:        memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
                    238:        for (numsounds=1 ; ; numsounds++)
                    239:        {
                    240:                str = MSG_ReadString ();
                    241:                if (!str[0])
                    242:                        break;
                    243:                if (numsounds==MAX_SOUNDS)
1.1.1.2 ! root      244:                        Host_Error ("Server sent too many sound_precache");
1.1       root      245:                strcpy (sound_precache[numsounds], str);
                    246:                S_TouchSound (str);
                    247:        }
                    248: 
                    249: //
                    250: // now we try to load everything else until a cache allocation fails
                    251: //
                    252:        for (i=1 ; i<nummodels ; i++)
                    253:        {
1.1.1.2 ! root      254:                cl.model_precache[i] = Mod_ForName (model_precache[i], true);
1.1       root      255:                CL_KeepaliveMessage ();
                    256:        }
                    257: 
                    258:        for (i=1 ; i<numsounds ; i++)
                    259:        {
                    260:                cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
                    261:                CL_KeepaliveMessage ();
                    262:        }
                    263: 
                    264: 
                    265: // local state
                    266:        cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
                    267:        
                    268:        R_NewMap ();
                    269: 
                    270:        Hunk_Check ();          // make sure nothing is hurt
                    271:        
                    272:        noclip_anglehack = false;               // noclip is turned off at start        
                    273: }
                    274: 
                    275: 
                    276: /*
                    277: ==================
                    278: CL_ParseUpdate
                    279: 
                    280: Parse an entity update message from the server
                    281: If an entities model or origin changes from frame to frame, it must be
                    282: relinked.  Other attributes can change without relinking.
                    283: ==================
                    284: */
                    285: int    bitcounts[16];
                    286: 
                    287: void CL_ParseUpdate (int bits)
                    288: {
                    289:        int                     i;
                    290:        model_t         *model;
                    291:        int                     modnum;
                    292:        qboolean        forcelink;
                    293:        entity_t        *ent;
                    294:        int                     num;
                    295: 
                    296:        if (cls.signon == SIGNONS - 1)
                    297:        {       // first update is the final signon stage
                    298:                cls.signon = SIGNONS;
                    299:                CL_SignonReply ();
                    300:        }
                    301: 
                    302:        if (bits & U_MOREBITS)
                    303:        {
                    304:                i = MSG_ReadByte ();
                    305:                bits |= (i<<8);
                    306:        }
                    307: 
                    308:        if (bits & U_LONGENTITY)        
                    309:                num = MSG_ReadShort ();
                    310:        else
                    311:                num = MSG_ReadByte ();
                    312: 
                    313:        ent = CL_EntityNum (num);
                    314: 
                    315: for (i=0 ; i<16 ; i++)
                    316: if (bits&(1<<i))
                    317:        bitcounts[i]++;
                    318: 
                    319:        if (ent->msgtime != cl.mtime[1])
                    320:                forcelink = true;       // no previous frame to lerp from
                    321:        else
                    322:                forcelink = false;
                    323: 
                    324:        ent->msgtime = cl.mtime[0];
                    325:        
                    326:        if (bits & U_MODEL)
                    327:        {
                    328:                modnum = MSG_ReadByte ();
                    329:                if (modnum >= MAX_MODELS)
                    330:                        Host_Error ("CL_ParseModel: bad modnum");
                    331:        }
                    332:        else
                    333:                modnum = ent->baseline.modelindex;
                    334:                
                    335:        model = cl.model_precache[modnum];
                    336:        if (model != ent->model)
                    337:        {
                    338:                ent->model = model;
                    339:        // automatic animation (torches, etc) can be either all together
                    340:        // or randomized
                    341:                if (model)
                    342:                {
                    343:                        if (model->synctype == ST_RAND)
                    344:                                ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
                    345:                        else
                    346:                                ent->syncbase = 0.0;
                    347:                }
                    348:                else
                    349:                        forcelink = true;       // hack to make null model players work
                    350:        }
                    351:        
                    352:        if (bits & U_FRAME)
                    353:                ent->frame = MSG_ReadByte ();
                    354:        else
                    355:                ent->frame = ent->baseline.frame;
                    356: 
                    357:        if (bits & U_COLORMAP)
                    358:                i = MSG_ReadByte();
                    359:        else
                    360:                i = ent->baseline.colormap;
                    361:        if (!i)
                    362:                ent->colormap = vid.colormap;
                    363:        else
                    364:        {
                    365:                if (i > cl.maxclients)
                    366:                        Sys_Error ("i >= cl.maxclients");
                    367:                ent->colormap = cl.scores[i-1].translations;
                    368:        }
                    369: 
                    370:        if (bits & U_SKIN)
                    371:                ent->skinnum = MSG_ReadByte();
                    372:        else
                    373:                ent->skinnum = ent->baseline.skin;
                    374: 
                    375:        if (bits & U_EFFECTS)
                    376:                ent->effects = MSG_ReadByte();
                    377:        else
                    378:                ent->effects = ent->baseline.effects;
                    379: 
                    380: // shift the known values for interpolation
                    381:        VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
                    382:        VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
                    383: 
                    384:        if (bits & U_ORIGIN1)
                    385:                ent->msg_origins[0][0] = MSG_ReadCoord ();
                    386:        else
                    387:                ent->msg_origins[0][0] = ent->baseline.origin[0];
                    388:        if (bits & U_ANGLE1)
                    389:                ent->msg_angles[0][0] = MSG_ReadAngle();
                    390:        else
                    391:                ent->msg_angles[0][0] = ent->baseline.angles[0];
                    392: 
                    393:        if (bits & U_ORIGIN2)
                    394:                ent->msg_origins[0][1] = MSG_ReadCoord ();
                    395:        else
                    396:                ent->msg_origins[0][1] = ent->baseline.origin[1];
                    397:        if (bits & U_ANGLE2)
                    398:                ent->msg_angles[0][1] = MSG_ReadAngle();
                    399:        else
                    400:                ent->msg_angles[0][1] = ent->baseline.angles[1];
                    401: 
                    402:        if (bits & U_ORIGIN3)
                    403:                ent->msg_origins[0][2] = MSG_ReadCoord ();
                    404:        else
                    405:                ent->msg_origins[0][2] = ent->baseline.origin[2];
                    406:        if (bits & U_ANGLE3)
                    407:                ent->msg_angles[0][2] = MSG_ReadAngle();
                    408:        else
                    409:                ent->msg_angles[0][2] = ent->baseline.angles[2];
                    410: 
                    411:        if ( bits & U_NOLERP )
                    412:                ent->forcelink = true;
                    413: 
                    414:        if ( forcelink )
                    415:        {       // didn't have an update last message
                    416:                VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
                    417:                VectorCopy (ent->msg_origins[0], ent->origin);
                    418:                VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
                    419:                VectorCopy (ent->msg_angles[0], ent->angles);
                    420:                ent->forcelink = true;
                    421:        }
                    422: }
                    423: 
                    424: /*
                    425: ==================
                    426: CL_ParseBaseline
                    427: ==================
                    428: */
                    429: void CL_ParseBaseline (entity_t *ent)
                    430: {
                    431:        int                     i;
                    432:        
                    433:        ent->baseline.modelindex = MSG_ReadByte ();
                    434:        ent->baseline.frame = MSG_ReadByte ();
                    435:        ent->baseline.colormap = MSG_ReadByte();
                    436:        ent->baseline.skin = MSG_ReadByte();
                    437:        for (i=0 ; i<3 ; i++)
                    438:        {
                    439:                ent->baseline.origin[i] = MSG_ReadCoord ();
                    440:                ent->baseline.angles[i] = MSG_ReadAngle ();
                    441:        }
                    442: }
                    443: 
                    444: 
                    445: /*
                    446: ==================
                    447: CL_ParseClientdata
                    448: 
                    449: Server information pertaining to this client only
                    450: ==================
                    451: */
                    452: void CL_ParseClientdata (int bits)
                    453: {
                    454:        int             i, j;
                    455:        
                    456:        if (bits & SU_VIEWHEIGHT)
                    457:                cl.viewheight = MSG_ReadChar ();
                    458:        else
                    459:                cl.viewheight = DEFAULT_VIEWHEIGHT;
                    460: 
                    461:        if (bits & SU_IDEALPITCH)
                    462:                cl.idealpitch = MSG_ReadChar ();
                    463:        else
                    464:                cl.idealpitch = 0;
                    465:        
                    466:        VectorCopy (cl.mvelocity[0], cl.mvelocity[1]);
                    467:        for (i=0 ; i<3 ; i++)
                    468:        {
                    469:                if (bits & (SU_PUNCH1<<i) )
                    470:                        cl.punchangle[i] = MSG_ReadChar();
                    471:                else
                    472:                        cl.punchangle[i] = 0;
                    473:                if (bits & (SU_VELOCITY1<<i) )
                    474:                        cl.mvelocity[0][i] = MSG_ReadChar()*16;
                    475:                else
                    476:                        cl.mvelocity[0][i] = 0;
                    477:        }
                    478: 
                    479:        if (bits & SU_ITEMS)
                    480:                i = MSG_ReadLong ();
                    481:        else
                    482:                i = DEFAULT_ITEMS;
                    483:        if (cl.items != i)
                    484:        {       // set flash times
                    485:                Sbar_Changed ();
                    486:                for (j=0 ; j<32 ; j++)
                    487:                        if ( (i & (1<<j)) && !(cl.items & (1<<j)))
                    488:                                cl.item_gettime[j] = cl.time;
                    489:                cl.items = i;
                    490:        }
                    491:                
                    492:        cl.onground = (bits & SU_ONGROUND) != 0;
                    493:        cl.inwater = (bits & SU_INWATER) != 0;
                    494: 
                    495:        if (bits & SU_WEAPONFRAME)
                    496:                cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte ();
                    497:        else
                    498:                cl.stats[STAT_WEAPONFRAME] = 0;
                    499: 
                    500:        if (bits & SU_ARMOR)
                    501:                i = MSG_ReadByte ();
                    502:        else
                    503:                i = 0;
                    504:        if (cl.stats[STAT_ARMOR] != i)
                    505:        {
                    506:                cl.stats[STAT_ARMOR] = i;
                    507:                Sbar_Changed ();
                    508:        }
                    509: 
                    510:        if (bits & SU_WEAPON)
                    511:                i = MSG_ReadByte ();
                    512:        else
                    513:                i = 0;
                    514:        if (cl.stats[STAT_WEAPON] != i)
                    515:        {
                    516:                cl.stats[STAT_WEAPON] = i;
                    517:                Sbar_Changed ();
                    518:        }
                    519:        
                    520:        i = MSG_ReadShort ();
                    521:        if (cl.stats[STAT_HEALTH] != i)
                    522:        {
                    523:                cl.stats[STAT_HEALTH] = i;
                    524:                Sbar_Changed ();
                    525:        }
                    526: 
                    527:        i = MSG_ReadByte ();
                    528:        if (cl.stats[STAT_AMMO] != i)
                    529:        {
                    530:                cl.stats[STAT_AMMO] = i;
                    531:                Sbar_Changed ();
                    532:        }
                    533: 
                    534:        for (i=0 ; i<4 ; i++)
                    535:        {
                    536:                j = MSG_ReadByte ();
                    537:                if (cl.stats[STAT_SHELLS+i] != j)
                    538:                {
                    539:                        cl.stats[STAT_SHELLS+i] = j;
                    540:                        Sbar_Changed ();
                    541:                }
                    542:        }
                    543: 
                    544:        i = MSG_ReadByte ();
                    545:        if (cl.stats[STAT_ACTIVEWEAPON] != i)
                    546:        {
                    547:                cl.stats[STAT_ACTIVEWEAPON] = i;
                    548:                Sbar_Changed ();
                    549:        }
                    550: 
                    551: }
                    552: 
                    553: /*
                    554: =====================
                    555: CL_NewTranslation
                    556: =====================
                    557: */
                    558: void CL_NewTranslation (int slot)
                    559: {
                    560:        int             i, j;
                    561:        int             top, bottom;
                    562:        byte    *dest, *source;
                    563:        
                    564:        if (slot > cl.maxclients)
                    565:                Sys_Error ("CL_NewTranslation: slot > cl.maxclients");
                    566:        dest = cl.scores[slot].translations;
                    567:        source = vid.colormap;
                    568:        memcpy (dest, vid.colormap, sizeof(cl.scores[slot].translations));
                    569:        top = cl.scores[slot].colors & 0xf0;
                    570:        bottom = (cl.scores[slot].colors &15)<<4;
                    571: 
                    572:        for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
                    573:        {
                    574:                if (top < 128)  // the artists made some backwards ranges.  sigh.
                    575:                        memcpy (dest + TOP_RANGE, source + top, 16);
                    576:                else
                    577:                        for (j=0 ; j<16 ; j++)
                    578:                                dest[TOP_RANGE+j] = source[top+15-j];
                    579:                                
                    580:                if (bottom < 128)
                    581:                        memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
                    582:                else
                    583:                        for (j=0 ; j<16 ; j++)
                    584:                                dest[BOTTOM_RANGE+j] = source[bottom+15-j];             
                    585:        }
                    586: }
                    587: 
                    588: /*
                    589: =====================
                    590: CL_ParseStatic
                    591: =====================
                    592: */
                    593: void CL_ParseStatic (void)
                    594: {
                    595:        entity_t *ent;
                    596:        int             i;
                    597:                
                    598:        i = cl.num_statics;
                    599:        if (i >= MAX_STATIC_ENTITIES)
                    600:                Host_Error ("Too many static entities");
                    601:        ent = &cl_static_entities[i];
                    602:        cl.num_statics++;
                    603:        CL_ParseBaseline (ent);
                    604: 
                    605: // copy it to the current state
                    606:        ent->model = cl.model_precache[ent->baseline.modelindex];
                    607:        ent->frame = ent->baseline.frame;
                    608:        ent->colormap = vid.colormap;
                    609:        ent->skinnum = ent->baseline.skin;
                    610:        ent->effects = ent->baseline.effects;
                    611: 
                    612:        VectorCopy (ent->baseline.origin, ent->origin);
                    613:        VectorCopy (ent->baseline.angles, ent->angles); 
                    614:        R_AddEfrags (ent);
                    615: }
                    616: 
                    617: /*
                    618: ===================
                    619: CL_ParseStaticSound
                    620: ===================
                    621: */
                    622: void CL_ParseStaticSound (void)
                    623: {
                    624:        vec3_t          org;
                    625:        int                     sound_num, vol, atten;
                    626:        int                     i;
                    627:        
                    628:        for (i=0 ; i<3 ; i++)
                    629:                org[i] = MSG_ReadCoord ();
                    630:        sound_num = MSG_ReadByte ();
                    631:        vol = MSG_ReadByte ();
                    632:        atten = MSG_ReadByte ();
                    633:        
                    634:        S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
                    635: }
                    636: 
                    637: 
                    638: #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
                    639: 
                    640: /*
                    641: =====================
                    642: CL_ParseServerMessage
                    643: =====================
                    644: */
                    645: void CL_ParseServerMessage (void)
                    646: {
                    647:        int                     cmd;
                    648:        int                     i;
                    649:        
                    650: //
                    651: // if recording demos, copy the message out
                    652: //
                    653:        if (cl_shownet.value == 1)
                    654:                Con_Printf ("%i ",net_message.cursize);
                    655:        else if (cl_shownet.value == 2)
                    656:                Con_Printf ("------------------\n");
                    657:        
                    658:        cl.onground = false;    // unless the server says otherwise     
                    659: //
                    660: // parse the message
                    661: //
                    662:        MSG_BeginReading ();
                    663:        
                    664:        while (1)
                    665:        {
                    666:                if (msg_badread)
                    667:                        Host_Error ("CL_ParseServerMessage: Bad server message");
                    668: 
                    669:                cmd = MSG_ReadByte ();
                    670: 
                    671:                if (cmd == -1)
                    672:                {
                    673:                        SHOWNET("END OF MESSAGE");
                    674:                        return;         // end of message
                    675:                }
                    676: 
                    677:        // if the high bit of the command byte is set, it is a fast update
                    678:                if (cmd & 128)
                    679:                {
                    680:                        SHOWNET("fast update");
                    681:                        CL_ParseUpdate (cmd&127);
                    682:                        continue;
                    683:                }
                    684: 
                    685:                SHOWNET(svc_strings[cmd]);
                    686:        
                    687:        // other commands
                    688:                switch (cmd)
                    689:                {
                    690:                default:
                    691:                        Host_Error ("CL_ParseServerMessage: Illegible server message\n");
                    692:                        break;
                    693:                        
                    694:                case svc_nop:
                    695: //                     Con_Printf ("svc_nop\n");
                    696:                        break;
                    697:                        
                    698:                case svc_time:
                    699:                        cl.mtime[1] = cl.mtime[0];
                    700:                        cl.mtime[0] = MSG_ReadFloat ();                 
                    701:                        break;
                    702:                        
                    703:                case svc_clientdata:
                    704:                        i = MSG_ReadShort ();
                    705:                        CL_ParseClientdata (i);
                    706:                        break;
                    707:                
                    708:                case svc_version:
                    709:                        i = MSG_ReadLong ();
                    710:                        if (i != PROTOCOL_VERSION)
                    711:                                Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
                    712:                        break;
                    713:                        
                    714:                case svc_disconnect:
                    715:                        Host_EndGame ("Server disconnected\n");
                    716: 
                    717:                case svc_print:
1.1.1.2 ! root      718:                        Con_Printf (MSG_ReadString ());
1.1       root      719:                        break;
                    720:                        
                    721:                case svc_centerprint:
                    722:                        SCR_CenterPrint (MSG_ReadString ());
                    723:                        break;
                    724:                        
                    725:                case svc_stufftext:
                    726:                        Cbuf_AddText (MSG_ReadString ());
                    727:                        break;
                    728:                        
                    729:                case svc_damage:
                    730:                        V_ParseDamage ();
                    731:                        break;
                    732:                        
                    733:                case svc_serverinfo:
                    734:                        CL_ParseServerInfo ();
                    735:                        vid.recalc_refdef = true;       // leave intermission full screen
                    736:                        break;
                    737:                        
                    738:                case svc_setangle:
                    739:                        for (i=0 ; i<3 ; i++)
                    740:                                cl.viewangles[i] = MSG_ReadAngle ();
                    741:                        break;
                    742:                        
                    743:                case svc_setview:
                    744:                        cl.viewentity = MSG_ReadShort ();
                    745:                        break;
                    746:                                        
                    747:                case svc_lightstyle:
                    748:                        i = MSG_ReadByte ();
                    749:                        if (i >= MAX_LIGHTSTYLES)
                    750:                                Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
                    751:                        Q_strcpy (cl_lightstyle[i].map,  MSG_ReadString());
                    752:                        cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
                    753:                        break;
                    754:                        
                    755:                case svc_sound:
                    756:                        CL_ParseStartSoundPacket();
                    757:                        break;
                    758:                        
                    759:                case svc_stopsound:
                    760:                        i = MSG_ReadShort();
                    761:                        S_StopSound(i>>3, i&7);
                    762:                        break;
                    763:                
                    764:                case svc_updatename:
                    765:                        Sbar_Changed ();
                    766:                        i = MSG_ReadByte ();
                    767:                        if (i >= cl.maxclients)
                    768:                                Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
                    769:                        strcpy (cl.scores[i].name, MSG_ReadString ());
                    770:                        break;
                    771:                        
                    772:                case svc_updatefrags:
                    773:                        Sbar_Changed ();
                    774:                        i = MSG_ReadByte ();
                    775:                        if (i >= cl.maxclients)
                    776:                                Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
                    777:                        cl.scores[i].frags = MSG_ReadShort ();
                    778:                        break;                  
                    779: 
                    780:                case svc_updatecolors:
                    781:                        Sbar_Changed ();
                    782:                        i = MSG_ReadByte ();
                    783:                        if (i >= cl.maxclients)
                    784:                                Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
                    785:                        cl.scores[i].colors = MSG_ReadByte ();
                    786:                        CL_NewTranslation (i);
                    787:                        break;
                    788:                        
                    789:                case svc_particle:
                    790:                        R_ParseParticleEffect ();
                    791:                        break;
                    792: 
                    793:                case svc_spawnbaseline:
                    794:                        i = MSG_ReadShort ();
                    795:                        // must use CL_EntityNum() to force cl.num_entities up
                    796:                        CL_ParseBaseline (CL_EntityNum(i));
                    797:                        break;
                    798:                case svc_spawnstatic:
                    799:                        CL_ParseStatic ();
                    800:                        break;                  
                    801:                case svc_temp_entity:
                    802:                        CL_ParseTEnt ();
                    803:                        break;
                    804: 
                    805:                case svc_setpause:
                    806:                        cl.paused = MSG_ReadByte ();
                    807:                        if (cl.paused)
                    808:                                CDAudio_Stop();
                    809:                        else
                    810:                                CDAudio_Resume();
                    811:                        break;
                    812:                        
                    813:                case svc_signonnum:
                    814:                        i = MSG_ReadByte ();
                    815:                        if (i <= cls.signon)
                    816:                                Host_Error ("Received signon %i when at %i", i, cls.signon);
                    817:                        cls.signon = i;
                    818:                        CL_SignonReply ();
                    819:                        break;
                    820: 
                    821:                case svc_killedmonster:
                    822:                        cl.stats[STAT_MONSTERS]++;
                    823:                        break;
                    824: 
                    825:                case svc_foundsecret:
                    826:                        cl.stats[STAT_SECRETS]++;
                    827:                        break;
                    828: 
                    829:                case svc_updatestat:
                    830:                        i = MSG_ReadByte ();
                    831:                        if (i < 0 || i >= MAX_CL_STATS)
                    832:                                Sys_Error ("svc_updatestat: %i is invalid", i);
                    833:                        cl.stats[i] = MSG_ReadLong ();;
                    834:                        break;
                    835:                        
                    836:                case svc_spawnstaticsound:
                    837:                        CL_ParseStaticSound ();
                    838:                        break;
                    839: 
                    840:                case svc_cdtrack:
                    841:                        cl.cdtrack = MSG_ReadByte ();
                    842:                        cl.looptrack = MSG_ReadByte ();
                    843:                        if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
                    844:                                CDAudio_Play ((byte)cls.forcetrack, true);
                    845:                        else
                    846:                                CDAudio_Play ((byte)cl.cdtrack, true);
                    847:                        break;
                    848: 
                    849:                case svc_intermission:
                    850:                        cl.intermission = 1;
                    851:                        cl.completed_time = cl.time;
                    852:                        vid.recalc_refdef = true;       // go to full screen
                    853:                        break;
                    854: 
                    855:                case svc_finale:
                    856:                        cl.intermission = 2;
                    857:                        cl.completed_time = cl.time;
                    858:                        vid.recalc_refdef = true;       // go to full screen
                    859:                        SCR_CenterPrint (MSG_ReadString ());                    
                    860:                        break;
                    861:                        
                    862:                case svc_sellscreen:
                    863:                        Cmd_ExecuteString ("help", src_command);
                    864:                        break;
                    865:                }
                    866:        }
                    867: }
                    868: 

unix.superglobalmegacorp.com

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