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

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

unix.superglobalmegacorp.com

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