|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.