cl_parse.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // cl_parse.c -- parse a message received from the server
  16. #include "quakedef.h"
  17. char *svc_strings[] =
  18. {
  19. "svc_bad",
  20. "svc_nop",
  21. "svc_disconnect",
  22. "svc_updatestat",
  23. "svc_version", // [long] server version
  24. "svc_setview", // [short] entity number
  25. "svc_sound", // <see code>
  26. "svc_time", // [float] server time
  27. "svc_print", // [string] null terminated string
  28. "svc_stufftext", // [string] stuffed into client's console buffer
  29. // the string should be \n terminated
  30. "svc_setangle", // [vec3] set the view angle to this absolute value
  31. "svc_serverdata", // [long] version ...
  32. "svc_lightstyle", // [byte] [string]
  33. "svc_updatename", // [byte] [string]
  34. "svc_updatefrags", // [byte] [short]
  35. "svc_clientdata", // <shortbits + data>
  36. "svc_stopsound", // <see code>
  37. "svc_updatecolors", // [byte] [byte]
  38. "svc_particle", // [vec3] <variable>
  39. "svc_damage", // [byte] impact [byte] blood [vec3] from
  40. "svc_spawnstatic",
  41. "OBSOLETE svc_spawnbinary",
  42. "svc_spawnbaseline",
  43. "svc_temp_entity", // <variable>
  44. "svc_setpause",
  45. "svc_signonnum",
  46. "svc_centerprint",
  47. "svc_killedmonster",
  48. "svc_foundsecret",
  49. "svc_spawnstaticsound",
  50. "svc_intermission",
  51. "svc_finale",
  52. "svc_cdtrack",
  53. "svc_sellscreen",
  54. "svc_smallkick",
  55. "svc_bigkick",
  56. "svc_updateping",
  57. "svc_updateentertime",
  58. "svc_updatestatlong",
  59. "svc_muzzleflash",
  60. "svc_updateuserinfo",
  61. "svc_download",
  62. "svc_playerinfo",
  63. "svc_nails",
  64. "svc_choke",
  65. "svc_modellist",
  66. "svc_soundlist",
  67. "svc_packetentities",
  68. "svc_deltapacketentities",
  69. "svc_maxspeed",
  70. "svc_entgravity",
  71. "svc_setinfo",
  72. "svc_serverinfo",
  73. "svc_updatepl",
  74. "NEW PROTOCOL",
  75. "NEW PROTOCOL",
  76. "NEW PROTOCOL",
  77. "NEW PROTOCOL",
  78. "NEW PROTOCOL",
  79. "NEW PROTOCOL",
  80. "NEW PROTOCOL",
  81. "NEW PROTOCOL",
  82. "NEW PROTOCOL",
  83. "NEW PROTOCOL",
  84. "NEW PROTOCOL",
  85. "NEW PROTOCOL",
  86. "NEW PROTOCOL"
  87. };
  88. int oldparsecountmod;
  89. int parsecountmod;
  90. double parsecounttime;
  91. int cl_spikeindex, cl_playerindex, cl_flagindex;
  92. //=============================================================================
  93. int packet_latency[NET_TIMINGS];
  94. int CL_CalcNet (void)
  95. {
  96. int a, i;
  97. frame_t *frame;
  98. int lost;
  99. char st[80];
  100. for (i=cls.netchan.outgoing_sequence-UPDATE_BACKUP+1
  101. ; i <= cls.netchan.outgoing_sequence
  102. ; i++)
  103. {
  104. frame = &cl.frames[i&UPDATE_MASK];
  105. if (frame->receivedtime == -1)
  106. packet_latency[i&NET_TIMINGSMASK] = 9999; // dropped
  107. else if (frame->receivedtime == -2)
  108. packet_latency[i&NET_TIMINGSMASK] = 10000; // choked
  109. else if (frame->invalid)
  110. packet_latency[i&NET_TIMINGSMASK] = 9998; // invalid delta
  111. else
  112. packet_latency[i&NET_TIMINGSMASK] = (frame->receivedtime - frame->senttime)*20;
  113. }
  114. lost = 0;
  115. for (a=0 ; a<NET_TIMINGS ; a++)
  116. {
  117. i = (cls.netchan.outgoing_sequence-a) & NET_TIMINGSMASK;
  118. if (packet_latency[i] == 9999)
  119. lost++;
  120. }
  121. return lost * 100 / NET_TIMINGS;
  122. }
  123. //=============================================================================
  124. /*
  125. ===============
  126. CL_CheckOrDownloadFile
  127. Returns true if the file exists, otherwise it attempts
  128. to start a download from the server.
  129. ===============
  130. */
  131. qboolean CL_CheckOrDownloadFile (char *filename)
  132. {
  133. FILE *f;
  134. if (strstr (filename, ".."))
  135. {
  136. Con_Printf ("Refusing to download a path with ..\n");
  137. return true;
  138. }
  139. COM_FOpenFile (filename, &f);
  140. if (f)
  141. { // it exists, no need to download
  142. fclose (f);
  143. return true;
  144. }
  145. //ZOID - can't download when recording
  146. if (cls.demorecording) {
  147. Con_Printf("Unable to download %s in record mode.\n", cls.downloadname);
  148. return true;
  149. }
  150. //ZOID - can't download when playback
  151. if (cls.demoplayback)
  152. return true;
  153. strcpy (cls.downloadname, filename);
  154. Con_Printf ("Downloading %s...\n", cls.downloadname);
  155. // download to a temp name, and only rename
  156. // to the real name when done, so if interrupted
  157. // a runt file wont be left
  158. COM_StripExtension (cls.downloadname, cls.downloadtempname);
  159. strcat (cls.downloadtempname, ".tmp");
  160. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  161. MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname));
  162. cls.downloadnumber++;
  163. return false;
  164. }
  165. /*
  166. =================
  167. Model_NextDownload
  168. =================
  169. */
  170. void Model_NextDownload (void)
  171. {
  172. char *s;
  173. int i;
  174. extern char gamedirfile[];
  175. if (cls.downloadnumber == 0)
  176. {
  177. Con_Printf ("Checking models...\n");
  178. cls.downloadnumber = 1;
  179. }
  180. cls.downloadtype = dl_model;
  181. for (
  182. ; cl.model_name[cls.downloadnumber][0]
  183. ; cls.downloadnumber++)
  184. {
  185. s = cl.model_name[cls.downloadnumber];
  186. if (s[0] == '*')
  187. continue; // inline brush model
  188. if (!CL_CheckOrDownloadFile(s))
  189. return; // started a download
  190. }
  191. for (i=1 ; i<MAX_MODELS ; i++)
  192. {
  193. if (!cl.model_name[i][0])
  194. break;
  195. cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
  196. if (!cl.model_precache[i])
  197. {
  198. Con_Printf ("\nThe required model file '%s' could not be found or downloaded.\n\n"
  199. , cl.model_name[i]);
  200. Con_Printf ("You may need to download or purchase a %s client "
  201. "pack in order to play on this server.\n\n", gamedirfile);
  202. CL_Disconnect ();
  203. return;
  204. }
  205. }
  206. // all done
  207. cl.worldmodel = cl.model_precache[1];
  208. R_NewMap ();
  209. Hunk_Check (); // make sure nothing is hurt
  210. // done with modellist, request first of static signon messages
  211. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  212. // MSG_WriteString (&cls.netchan.message, va("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2));
  213. MSG_WriteString (&cls.netchan.message, va(prespawn_name, cl.servercount, cl.worldmodel->checksum2));
  214. }
  215. /*
  216. =================
  217. Sound_NextDownload
  218. =================
  219. */
  220. void Sound_NextDownload (void)
  221. {
  222. char *s;
  223. int i;
  224. if (cls.downloadnumber == 0)
  225. {
  226. Con_Printf ("Checking sounds...\n");
  227. cls.downloadnumber = 1;
  228. }
  229. cls.downloadtype = dl_sound;
  230. for (
  231. ; cl.sound_name[cls.downloadnumber][0]
  232. ; cls.downloadnumber++)
  233. {
  234. s = cl.sound_name[cls.downloadnumber];
  235. if (!CL_CheckOrDownloadFile(va("sound/%s",s)))
  236. return; // started a download
  237. }
  238. for (i=1 ; i<MAX_SOUNDS ; i++)
  239. {
  240. if (!cl.sound_name[i][0])
  241. break;
  242. cl.sound_precache[i] = S_PrecacheSound (cl.sound_name[i]);
  243. }
  244. // done with sounds, request models now
  245. memset (cl.model_precache, 0, sizeof(cl.model_precache));
  246. cl_playerindex = -1;
  247. cl_spikeindex = -1;
  248. cl_flagindex = -1;
  249. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  250. // MSG_WriteString (&cls.netchan.message, va("modellist %i 0", cl.servercount));
  251. MSG_WriteString (&cls.netchan.message, va(modellist_name, cl.servercount, 0));
  252. }
  253. /*
  254. ======================
  255. CL_RequestNextDownload
  256. ======================
  257. */
  258. void CL_RequestNextDownload (void)
  259. {
  260. switch (cls.downloadtype)
  261. {
  262. case dl_single:
  263. break;
  264. case dl_skin:
  265. Skin_NextDownload ();
  266. break;
  267. case dl_model:
  268. Model_NextDownload ();
  269. break;
  270. case dl_sound:
  271. Sound_NextDownload ();
  272. break;
  273. case dl_none:
  274. default:
  275. Con_DPrintf("Unknown download type.\n");
  276. }
  277. }
  278. /*
  279. =====================
  280. CL_ParseDownload
  281. A download message has been received from the server
  282. =====================
  283. */
  284. void CL_ParseDownload (void)
  285. {
  286. int size, percent;
  287. byte name[1024];
  288. int r;
  289. // read the data
  290. size = MSG_ReadShort ();
  291. percent = MSG_ReadByte ();
  292. if (cls.demoplayback) {
  293. if (size > 0)
  294. msg_readcount += size;
  295. return; // not in demo playback
  296. }
  297. if (size == -1)
  298. {
  299. Con_Printf ("File not found.\n");
  300. if (cls.download)
  301. {
  302. Con_Printf ("cls.download shouldn't have been set\n");
  303. fclose (cls.download);
  304. cls.download = NULL;
  305. }
  306. CL_RequestNextDownload ();
  307. return;
  308. }
  309. // open the file if not opened yet
  310. if (!cls.download)
  311. {
  312. if (strncmp(cls.downloadtempname,"skins/",6))
  313. sprintf (name, "%s/%s", com_gamedir, cls.downloadtempname);
  314. else
  315. sprintf (name, "qw/%s", cls.downloadtempname);
  316. COM_CreatePath (name);
  317. cls.download = fopen (name, "wb");
  318. if (!cls.download)
  319. {
  320. msg_readcount += size;
  321. Con_Printf ("Failed to open %s\n", cls.downloadtempname);
  322. CL_RequestNextDownload ();
  323. return;
  324. }
  325. }
  326. fwrite (net_message.data + msg_readcount, 1, size, cls.download);
  327. msg_readcount += size;
  328. if (percent != 100)
  329. {
  330. // change display routines by zoid
  331. // request next block
  332. #if 0
  333. Con_Printf (".");
  334. if (10*(percent/10) != cls.downloadpercent)
  335. {
  336. cls.downloadpercent = 10*(percent/10);
  337. Con_Printf ("%i%%", cls.downloadpercent);
  338. }
  339. #endif
  340. cls.downloadpercent = percent;
  341. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  342. SZ_Print (&cls.netchan.message, "nextdl");
  343. }
  344. else
  345. {
  346. char oldn[MAX_OSPATH];
  347. char newn[MAX_OSPATH];
  348. #if 0
  349. Con_Printf ("100%%\n");
  350. #endif
  351. fclose (cls.download);
  352. // rename the temp file to it's final name
  353. if (strcmp(cls.downloadtempname, cls.downloadname)) {
  354. if (strncmp(cls.downloadtempname,"skins/",6)) {
  355. sprintf (oldn, "%s/%s", com_gamedir, cls.downloadtempname);
  356. sprintf (newn, "%s/%s", com_gamedir, cls.downloadname);
  357. } else {
  358. sprintf (oldn, "qw/%s", cls.downloadtempname);
  359. sprintf (newn, "qw/%s", cls.downloadname);
  360. }
  361. r = rename (oldn, newn);
  362. if (r)
  363. Con_Printf ("failed to rename.\n");
  364. }
  365. cls.download = NULL;
  366. cls.downloadpercent = 0;
  367. // get another file if needed
  368. CL_RequestNextDownload ();
  369. }
  370. }
  371. static byte *upload_data;
  372. static int upload_pos;
  373. static int upload_size;
  374. void CL_NextUpload(void)
  375. {
  376. byte buffer[1024];
  377. int r;
  378. int percent;
  379. int size;
  380. if (!upload_data)
  381. return;
  382. r = upload_size - upload_pos;
  383. if (r > 768)
  384. r = 768;
  385. memcpy(buffer, upload_data + upload_pos, r);
  386. MSG_WriteByte (&cls.netchan.message, clc_upload);
  387. MSG_WriteShort (&cls.netchan.message, r);
  388. upload_pos += r;
  389. size = upload_size;
  390. if (!size)
  391. size = 1;
  392. percent = upload_pos*100/size;
  393. MSG_WriteByte (&cls.netchan.message, percent);
  394. SZ_Write (&cls.netchan.message, buffer, r);
  395. Con_DPrintf ("UPLOAD: %6d: %d written\n", upload_pos - r, r);
  396. if (upload_pos != upload_size)
  397. return;
  398. Con_Printf ("Upload completed\n");
  399. free(upload_data);
  400. upload_data = 0;
  401. upload_pos = upload_size = 0;
  402. }
  403. void CL_StartUpload (byte *data, int size)
  404. {
  405. if (cls.state < ca_onserver)
  406. return; // gotta be connected
  407. // override
  408. if (upload_data)
  409. free(upload_data);
  410. Con_DPrintf("Upload starting of %d...\n", size);
  411. upload_data = malloc(size);
  412. memcpy(upload_data, data, size);
  413. upload_size = size;
  414. upload_pos = 0;
  415. CL_NextUpload();
  416. }
  417. qboolean CL_IsUploading(void)
  418. {
  419. if (upload_data)
  420. return true;
  421. return false;
  422. }
  423. void CL_StopUpload(void)
  424. {
  425. if (upload_data)
  426. free(upload_data);
  427. upload_data = NULL;
  428. }
  429. /*
  430. =====================================================================
  431. SERVER CONNECTING MESSAGES
  432. =====================================================================
  433. */
  434. /*
  435. ==================
  436. CL_ParseServerData
  437. ==================
  438. */
  439. void CL_ParseServerData (void)
  440. {
  441. char *str;
  442. FILE *f;
  443. char fn[MAX_OSPATH];
  444. qboolean cflag = false;
  445. extern char gamedirfile[MAX_OSPATH];
  446. int protover;
  447. Con_DPrintf ("Serverdata packet received.\n");
  448. //
  449. // wipe the client_state_t struct
  450. //
  451. CL_ClearState ();
  452. // parse protocol version number
  453. // allow 2.2 and 2.29 demos to play
  454. protover = MSG_ReadLong ();
  455. if (protover != PROTOCOL_VERSION &&
  456. !(cls.demoplayback && (protover == 26 || protover == 27 || protover == 28)))
  457. Host_EndGame ("Server returned version %i, not %i\nYou probably need to upgrade.\nCheck http://www.quakeworld.net/", protover, PROTOCOL_VERSION);
  458. cl.servercount = MSG_ReadLong ();
  459. // game directory
  460. str = MSG_ReadString ();
  461. if (stricmp(gamedirfile, str)) {
  462. // save current config
  463. Host_WriteConfiguration ();
  464. cflag = true;
  465. }
  466. COM_Gamedir(str);
  467. //ZOID--run the autoexec.cfg in the gamedir
  468. //if it exists
  469. if (cflag) {
  470. sprintf(fn, "%s/%s", com_gamedir, "config.cfg");
  471. if ((f = fopen(fn, "r")) != NULL) {
  472. fclose(f);
  473. Cbuf_AddText ("cl_warncmd 0\n");
  474. Cbuf_AddText("exec config.cfg\n");
  475. Cbuf_AddText("exec frontend.cfg\n");
  476. Cbuf_AddText ("cl_warncmd 1\n");
  477. }
  478. }
  479. // parse player slot, high bit means spectator
  480. cl.playernum = MSG_ReadByte ();
  481. if (cl.playernum & 128)
  482. {
  483. cl.spectator = true;
  484. cl.playernum &= ~128;
  485. }
  486. // get the full level name
  487. str = MSG_ReadString ();
  488. strncpy (cl.levelname, str, sizeof(cl.levelname)-1);
  489. // get the movevars
  490. movevars.gravity = MSG_ReadFloat();
  491. movevars.stopspeed = MSG_ReadFloat();
  492. movevars.maxspeed = MSG_ReadFloat();
  493. movevars.spectatormaxspeed = MSG_ReadFloat();
  494. movevars.accelerate = MSG_ReadFloat();
  495. movevars.airaccelerate = MSG_ReadFloat();
  496. movevars.wateraccelerate = MSG_ReadFloat();
  497. movevars.friction = MSG_ReadFloat();
  498. movevars.waterfriction = MSG_ReadFloat();
  499. movevars.entgravity = MSG_ReadFloat();
  500. // seperate the printfs so the server message can have a color
  501. 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");
  502. Con_Printf ("%c%s\n", 2, str);
  503. // ask for the sound list next
  504. memset(cl.sound_name, 0, sizeof(cl.sound_name));
  505. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  506. // MSG_WriteString (&cls.netchan.message, va("soundlist %i 0", cl.servercount));
  507. MSG_WriteString (&cls.netchan.message, va(soundlist_name, cl.servercount, 0));
  508. // now waiting for downloads, etc
  509. cls.state = ca_onserver;
  510. }
  511. /*
  512. ==================
  513. CL_ParseSoundlist
  514. ==================
  515. */
  516. void CL_ParseSoundlist (void)
  517. {
  518. int numsounds;
  519. char *str;
  520. int n;
  521. // precache sounds
  522. // memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
  523. numsounds = MSG_ReadByte();
  524. for (;;) {
  525. str = MSG_ReadString ();
  526. if (!str[0])
  527. break;
  528. numsounds++;
  529. if (numsounds == MAX_SOUNDS)
  530. Host_EndGame ("Server sent too many sound_precache");
  531. strcpy (cl.sound_name[numsounds], str);
  532. }
  533. n = MSG_ReadByte();
  534. if (n) {
  535. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  536. // MSG_WriteString (&cls.netchan.message, va("soundlist %i %i", cl.servercount, n));
  537. MSG_WriteString (&cls.netchan.message, va(soundlist_name, cl.servercount, n));
  538. return;
  539. }
  540. cls.downloadnumber = 0;
  541. cls.downloadtype = dl_sound;
  542. Sound_NextDownload ();
  543. }
  544. /*
  545. ==================
  546. CL_ParseModellist
  547. ==================
  548. */
  549. void CL_ParseModellist (void)
  550. {
  551. int nummodels;
  552. char *str;
  553. int n;
  554. // precache models and note certain default indexes
  555. nummodels = MSG_ReadByte();
  556. for (;;)
  557. {
  558. str = MSG_ReadString ();
  559. if (!str[0])
  560. break;
  561. nummodels++;
  562. if (nummodels==MAX_MODELS)
  563. Host_EndGame ("Server sent too many model_precache");
  564. strcpy (cl.model_name[nummodels], str);
  565. if (!strcmp(cl.model_name[nummodels],"progs/spike.mdl"))
  566. cl_spikeindex = nummodels;
  567. if (!strcmp(cl.model_name[nummodels],"progs/player.mdl"))
  568. cl_playerindex = nummodels;
  569. if (!strcmp(cl.model_name[nummodels],"progs/flag.mdl"))
  570. cl_flagindex = nummodels;
  571. }
  572. n = MSG_ReadByte();
  573. if (n) {
  574. MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
  575. // MSG_WriteString (&cls.netchan.message, va("modellist %i %i", cl.servercount, n));
  576. MSG_WriteString (&cls.netchan.message, va(modellist_name, cl.servercount, n));
  577. return;
  578. }
  579. cls.downloadnumber = 0;
  580. cls.downloadtype = dl_model;
  581. Model_NextDownload ();
  582. }
  583. /*
  584. ==================
  585. CL_ParseBaseline
  586. ==================
  587. */
  588. void CL_ParseBaseline (entity_state_t *es)
  589. {
  590. int i;
  591. es->modelindex = MSG_ReadByte ();
  592. es->frame = MSG_ReadByte ();
  593. es->colormap = MSG_ReadByte();
  594. es->skinnum = MSG_ReadByte();
  595. for (i=0 ; i<3 ; i++)
  596. {
  597. es->origin[i] = MSG_ReadCoord ();
  598. es->angles[i] = MSG_ReadAngle ();
  599. }
  600. }
  601. /*
  602. =====================
  603. CL_ParseStatic
  604. Static entities are non-interactive world objects
  605. like torches
  606. =====================
  607. */
  608. void CL_ParseStatic (void)
  609. {
  610. entity_t *ent;
  611. int i;
  612. entity_state_t es;
  613. CL_ParseBaseline (&es);
  614. i = cl.num_statics;
  615. if (i >= MAX_STATIC_ENTITIES)
  616. Host_EndGame ("Too many static entities");
  617. ent = &cl_static_entities[i];
  618. cl.num_statics++;
  619. // copy it to the current state
  620. ent->model = cl.model_precache[es.modelindex];
  621. ent->frame = es.frame;
  622. ent->colormap = vid.colormap;
  623. ent->skinnum = es.skinnum;
  624. VectorCopy (es.origin, ent->origin);
  625. VectorCopy (es.angles, ent->angles);
  626. R_AddEfrags (ent);
  627. }
  628. /*
  629. ===================
  630. CL_ParseStaticSound
  631. ===================
  632. */
  633. void CL_ParseStaticSound (void)
  634. {
  635. vec3_t org;
  636. int sound_num, vol, atten;
  637. int i;
  638. for (i=0 ; i<3 ; i++)
  639. org[i] = MSG_ReadCoord ();
  640. sound_num = MSG_ReadByte ();
  641. vol = MSG_ReadByte ();
  642. atten = MSG_ReadByte ();
  643. S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
  644. }
  645. /*
  646. =====================================================================
  647. ACTION MESSAGES
  648. =====================================================================
  649. */
  650. /*
  651. ==================
  652. CL_ParseStartSoundPacket
  653. ==================
  654. */
  655. void CL_ParseStartSoundPacket(void)
  656. {
  657. vec3_t pos;
  658. int channel, ent;
  659. int sound_num;
  660. int volume;
  661. float attenuation;
  662. int i;
  663. channel = MSG_ReadShort();
  664. if (channel & SND_VOLUME)
  665. volume = MSG_ReadByte ();
  666. else
  667. volume = DEFAULT_SOUND_PACKET_VOLUME;
  668. if (channel & SND_ATTENUATION)
  669. attenuation = MSG_ReadByte () / 64.0;
  670. else
  671. attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
  672. sound_num = MSG_ReadByte ();
  673. for (i=0 ; i<3 ; i++)
  674. pos[i] = MSG_ReadCoord ();
  675. ent = (channel>>3)&1023;
  676. channel &= 7;
  677. if (ent > MAX_EDICTS)
  678. Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent);
  679. S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
  680. }
  681. /*
  682. ==================
  683. CL_ParseClientdata
  684. Server information pertaining to this client only, sent every frame
  685. ==================
  686. */
  687. void CL_ParseClientdata (void)
  688. {
  689. int i;
  690. float latency;
  691. frame_t *frame;
  692. // calculate simulated time of message
  693. oldparsecountmod = parsecountmod;
  694. i = cls.netchan.incoming_acknowledged;
  695. cl.parsecount = i;
  696. i &= UPDATE_MASK;
  697. parsecountmod = i;
  698. frame = &cl.frames[i];
  699. parsecounttime = cl.frames[i].senttime;
  700. frame->receivedtime = realtime;
  701. // calculate latency
  702. latency = frame->receivedtime - frame->senttime;
  703. if (latency < 0 || latency > 1.0)
  704. {
  705. // Con_Printf ("Odd latency: %5.2f\n", latency);
  706. }
  707. else
  708. {
  709. // drift the average latency towards the observed latency
  710. if (latency < cls.latency)
  711. cls.latency = latency;
  712. else
  713. cls.latency += 0.001; // drift up, so correction are needed
  714. }
  715. }
  716. /*
  717. =====================
  718. CL_NewTranslation
  719. =====================
  720. */
  721. void CL_NewTranslation (int slot)
  722. {
  723. #ifdef GLQUAKE
  724. if (slot > MAX_CLIENTS)
  725. Sys_Error ("CL_NewTranslation: slot > MAX_CLIENTS");
  726. R_TranslatePlayerSkin(slot);
  727. #else
  728. int i, j;
  729. int top, bottom;
  730. byte *dest, *source;
  731. player_info_t *player;
  732. char s[512];
  733. if (slot > MAX_CLIENTS)
  734. Sys_Error ("CL_NewTranslation: slot > MAX_CLIENTS");
  735. player = &cl.players[slot];
  736. strcpy(s, Info_ValueForKey(player->userinfo, "skin"));
  737. COM_StripExtension(s, s);
  738. if (player->skin && !stricmp(s, player->skin->name))
  739. player->skin = NULL;
  740. if (player->_topcolor != player->topcolor ||
  741. player->_bottomcolor != player->bottomcolor || !player->skin) {
  742. player->_topcolor = player->topcolor;
  743. player->_bottomcolor = player->bottomcolor;
  744. dest = player->translations;
  745. source = vid.colormap;
  746. memcpy (dest, vid.colormap, sizeof(player->translations));
  747. top = player->topcolor;
  748. if (top > 13 || top < 0)
  749. top = 13;
  750. top *= 16;
  751. bottom = player->bottomcolor;
  752. if (bottom > 13 || bottom < 0)
  753. bottom = 13;
  754. bottom *= 16;
  755. for (i=0 ; i<VID_GRADES ; i++, dest += 256, source+=256)
  756. {
  757. if (top < 128) // the artists made some backwards ranges. sigh.
  758. memcpy (dest + TOP_RANGE, source + top, 16);
  759. else
  760. for (j=0 ; j<16 ; j++)
  761. dest[TOP_RANGE+j] = source[top+15-j];
  762. if (bottom < 128)
  763. memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
  764. else
  765. for (j=0 ; j<16 ; j++)
  766. dest[BOTTOM_RANGE+j] = source[bottom+15-j];
  767. }
  768. }
  769. #endif
  770. }
  771. /*
  772. ==============
  773. CL_UpdateUserinfo
  774. ==============
  775. */
  776. void CL_ProcessUserInfo (int slot, player_info_t *player)
  777. {
  778. strncpy (player->name, Info_ValueForKey (player->userinfo, "name"), sizeof(player->name)-1);
  779. player->topcolor = atoi(Info_ValueForKey (player->userinfo, "topcolor"));
  780. player->bottomcolor = atoi(Info_ValueForKey (player->userinfo, "bottomcolor"));
  781. if (Info_ValueForKey (player->userinfo, "*spectator")[0])
  782. player->spectator = true;
  783. else
  784. player->spectator = false;
  785. if (cls.state == ca_active)
  786. Skin_Find (player);
  787. Sbar_Changed ();
  788. CL_NewTranslation (slot);
  789. }
  790. /*
  791. ==============
  792. CL_UpdateUserinfo
  793. ==============
  794. */
  795. void CL_UpdateUserinfo (void)
  796. {
  797. int slot;
  798. player_info_t *player;
  799. slot = MSG_ReadByte ();
  800. if (slot >= MAX_CLIENTS)
  801. Host_EndGame ("CL_ParseServerMessage: svc_updateuserinfo > MAX_SCOREBOARD");
  802. player = &cl.players[slot];
  803. player->userid = MSG_ReadLong ();
  804. strncpy (player->userinfo, MSG_ReadString(), sizeof(player->userinfo)-1);
  805. CL_ProcessUserInfo (slot, player);
  806. }
  807. /*
  808. ==============
  809. CL_SetInfo
  810. ==============
  811. */
  812. void CL_SetInfo (void)
  813. {
  814. int slot;
  815. player_info_t *player;
  816. char key[MAX_MSGLEN];
  817. char value[MAX_MSGLEN];
  818. slot = MSG_ReadByte ();
  819. if (slot >= MAX_CLIENTS)
  820. Host_EndGame ("CL_ParseServerMessage: svc_setinfo > MAX_SCOREBOARD");
  821. player = &cl.players[slot];
  822. strncpy (key, MSG_ReadString(), sizeof(key) - 1);
  823. key[sizeof(key) - 1] = 0;
  824. strncpy (value, MSG_ReadString(), sizeof(value) - 1);
  825. key[sizeof(value) - 1] = 0;
  826. Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, value);
  827. Info_SetValueForKey (player->userinfo, key, value, MAX_INFO_STRING);
  828. CL_ProcessUserInfo (slot, player);
  829. }
  830. /*
  831. ==============
  832. CL_ServerInfo
  833. ==============
  834. */
  835. void CL_ServerInfo (void)
  836. {
  837. int slot;
  838. player_info_t *player;
  839. char key[MAX_MSGLEN];
  840. char value[MAX_MSGLEN];
  841. strncpy (key, MSG_ReadString(), sizeof(key) - 1);
  842. key[sizeof(key) - 1] = 0;
  843. strncpy (value, MSG_ReadString(), sizeof(value) - 1);
  844. key[sizeof(value) - 1] = 0;
  845. Con_DPrintf("SERVERINFO: %s=%s\n", key, value);
  846. Info_SetValueForKey (cl.serverinfo, key, value, MAX_SERVERINFO_STRING);
  847. }
  848. /*
  849. =====================
  850. CL_SetStat
  851. =====================
  852. */
  853. void CL_SetStat (int stat, int value)
  854. {
  855. int j;
  856. if (stat < 0 || stat >= MAX_CL_STATS)
  857. Sys_Error ("CL_SetStat: %i is invalid", stat);
  858. Sbar_Changed ();
  859. if (stat == STAT_ITEMS)
  860. { // set flash times
  861. Sbar_Changed ();
  862. for (j=0 ; j<32 ; j++)
  863. if ( (value & (1<<j)) && !(cl.stats[stat] & (1<<j)))
  864. cl.item_gettime[j] = cl.time;
  865. }
  866. cl.stats[stat] = value;
  867. }
  868. /*
  869. ==============
  870. CL_MuzzleFlash
  871. ==============
  872. */
  873. void CL_MuzzleFlash (void)
  874. {
  875. vec3_t fv, rv, uv;
  876. dlight_t *dl;
  877. int i;
  878. player_state_t *pl;
  879. i = MSG_ReadShort ();
  880. if ((unsigned)(i-1) >= MAX_CLIENTS)
  881. return;
  882. #ifdef GLQUAKE
  883. // don't draw our own muzzle flash in gl if flashblending
  884. if (i-1 == cl.playernum && gl_flashblend.value)
  885. return;
  886. #endif
  887. pl = &cl.frames[parsecountmod].playerstate[i-1];
  888. dl = CL_AllocDlight (i);
  889. VectorCopy (pl->origin, dl->origin);
  890. AngleVectors (pl->viewangles, fv, rv, uv);
  891. VectorMA (dl->origin, 18, fv, dl->origin);
  892. dl->radius = 200 + (rand()&31);
  893. dl->minlight = 32;
  894. dl->die = cl.time + 0.1;
  895. dl->color[0] = 0.2;
  896. dl->color[1] = 0.1;
  897. dl->color[2] = 0.05;
  898. dl->color[3] = 0.7;
  899. }
  900. #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
  901. /*
  902. =====================
  903. CL_ParseServerMessage
  904. =====================
  905. */
  906. int received_framecount;
  907. void CL_ParseServerMessage (void)
  908. {
  909. int cmd;
  910. char *s;
  911. int i, j;
  912. received_framecount = host_framecount;
  913. cl.last_servermessage = realtime;
  914. CL_ClearProjectiles ();
  915. //
  916. // if recording demos, copy the message out
  917. //
  918. if (cl_shownet.value == 1)
  919. Con_Printf ("%i ",net_message.cursize);
  920. else if (cl_shownet.value == 2)
  921. Con_Printf ("------------------\n");
  922. CL_ParseClientdata ();
  923. //
  924. // parse the message
  925. //
  926. while (1)
  927. {
  928. if (msg_badread)
  929. {
  930. Host_EndGame ("CL_ParseServerMessage: Bad server message");
  931. break;
  932. }
  933. cmd = MSG_ReadByte ();
  934. if (cmd == -1)
  935. {
  936. msg_readcount++; // so the EOM showner has the right value
  937. SHOWNET("END OF MESSAGE");
  938. break;
  939. }
  940. SHOWNET(svc_strings[cmd]);
  941. // other commands
  942. switch (cmd)
  943. {
  944. default:
  945. Host_EndGame ("CL_ParseServerMessage: Illegible server message");
  946. break;
  947. case svc_nop:
  948. // Con_Printf ("svc_nop\n");
  949. break;
  950. case svc_disconnect:
  951. if (cls.state == ca_connected)
  952. Host_EndGame ("Server disconnected\n"
  953. "Server version may not be compatible");
  954. else
  955. Host_EndGame ("Server disconnected");
  956. break;
  957. case svc_print:
  958. i = MSG_ReadByte ();
  959. if (i == PRINT_CHAT)
  960. {
  961. S_LocalSound ("misc/talk.wav");
  962. con_ormask = 128;
  963. }
  964. Con_Printf ("%s", MSG_ReadString ());
  965. con_ormask = 0;
  966. break;
  967. case svc_centerprint:
  968. SCR_CenterPrint (MSG_ReadString ());
  969. break;
  970. case svc_stufftext:
  971. s = MSG_ReadString ();
  972. Con_DPrintf ("stufftext: %s\n", s);
  973. Cbuf_AddText (s);
  974. break;
  975. case svc_damage:
  976. V_ParseDamage ();
  977. break;
  978. case svc_serverdata:
  979. Cbuf_Execute (); // make sure any stuffed commands are done
  980. CL_ParseServerData ();
  981. vid.recalc_refdef = true; // leave full screen intermission
  982. break;
  983. case svc_setangle:
  984. for (i=0 ; i<3 ; i++)
  985. cl.viewangles[i] = MSG_ReadAngle ();
  986. // cl.viewangles[PITCH] = cl.viewangles[ROLL] = 0;
  987. break;
  988. case svc_lightstyle:
  989. i = MSG_ReadByte ();
  990. if (i >= MAX_LIGHTSTYLES)
  991. Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
  992. Q_strcpy (cl_lightstyle[i].map, MSG_ReadString());
  993. cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
  994. break;
  995. case svc_sound:
  996. CL_ParseStartSoundPacket();
  997. break;
  998. case svc_stopsound:
  999. i = MSG_ReadShort();
  1000. S_StopSound(i>>3, i&7);
  1001. break;
  1002. case svc_updatefrags:
  1003. Sbar_Changed ();
  1004. i = MSG_ReadByte ();
  1005. if (i >= MAX_CLIENTS)
  1006. Host_EndGame ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
  1007. cl.players[i].frags = MSG_ReadShort ();
  1008. break;
  1009. case svc_updateping:
  1010. i = MSG_ReadByte ();
  1011. if (i >= MAX_CLIENTS)
  1012. Host_EndGame ("CL_ParseServerMessage: svc_updateping > MAX_SCOREBOARD");
  1013. cl.players[i].ping = MSG_ReadShort ();
  1014. break;
  1015. case svc_updatepl:
  1016. i = MSG_ReadByte ();
  1017. if (i >= MAX_CLIENTS)
  1018. Host_EndGame ("CL_ParseServerMessage: svc_updatepl > MAX_SCOREBOARD");
  1019. cl.players[i].pl = MSG_ReadByte ();
  1020. break;
  1021. case svc_updateentertime:
  1022. // time is sent over as seconds ago
  1023. i = MSG_ReadByte ();
  1024. if (i >= MAX_CLIENTS)
  1025. Host_EndGame ("CL_ParseServerMessage: svc_updateentertime > MAX_SCOREBOARD");
  1026. cl.players[i].entertime = realtime - MSG_ReadFloat ();
  1027. break;
  1028. case svc_spawnbaseline:
  1029. i = MSG_ReadShort ();
  1030. CL_ParseBaseline (&cl_baselines[i]);
  1031. break;
  1032. case svc_spawnstatic:
  1033. CL_ParseStatic ();
  1034. break;
  1035. case svc_temp_entity:
  1036. CL_ParseTEnt ();
  1037. break;
  1038. case svc_killedmonster:
  1039. cl.stats[STAT_MONSTERS]++;
  1040. break;
  1041. case svc_foundsecret:
  1042. cl.stats[STAT_SECRETS]++;
  1043. break;
  1044. case svc_updatestat:
  1045. i = MSG_ReadByte ();
  1046. j = MSG_ReadByte ();
  1047. CL_SetStat (i, j);
  1048. break;
  1049. case svc_updatestatlong:
  1050. i = MSG_ReadByte ();
  1051. j = MSG_ReadLong ();
  1052. CL_SetStat (i, j);
  1053. break;
  1054. case svc_spawnstaticsound:
  1055. CL_ParseStaticSound ();
  1056. break;
  1057. case svc_cdtrack:
  1058. cl.cdtrack = MSG_ReadByte ();
  1059. CDAudio_Play ((byte)cl.cdtrack, true);
  1060. break;
  1061. case svc_intermission:
  1062. cl.intermission = 1;
  1063. cl.completed_time = realtime;
  1064. vid.recalc_refdef = true; // go to full screen
  1065. for (i=0 ; i<3 ; i++)
  1066. cl.simorg[i] = MSG_ReadCoord ();
  1067. for (i=0 ; i<3 ; i++)
  1068. cl.simangles[i] = MSG_ReadAngle ();
  1069. VectorCopy (vec3_origin, cl.simvel);
  1070. break;
  1071. case svc_finale:
  1072. cl.intermission = 2;
  1073. cl.completed_time = realtime;
  1074. vid.recalc_refdef = true; // go to full screen
  1075. SCR_CenterPrint (MSG_ReadString ());
  1076. break;
  1077. case svc_sellscreen:
  1078. Cmd_ExecuteString ("help");
  1079. break;
  1080. case svc_smallkick:
  1081. cl.punchangle = -2;
  1082. break;
  1083. case svc_bigkick:
  1084. cl.punchangle = -4;
  1085. break;
  1086. case svc_muzzleflash:
  1087. CL_MuzzleFlash ();
  1088. break;
  1089. case svc_updateuserinfo:
  1090. CL_UpdateUserinfo ();
  1091. break;
  1092. case svc_setinfo:
  1093. CL_SetInfo ();
  1094. break;
  1095. case svc_serverinfo:
  1096. CL_ServerInfo ();
  1097. break;
  1098. case svc_download:
  1099. CL_ParseDownload ();
  1100. break;
  1101. case svc_playerinfo:
  1102. CL_ParsePlayerinfo ();
  1103. break;
  1104. case svc_nails:
  1105. CL_ParseProjectiles ();
  1106. break;
  1107. case svc_chokecount: // some preceding packets were choked
  1108. i = MSG_ReadByte ();
  1109. for (j=0 ; j<i ; j++)
  1110. cl.frames[ (cls.netchan.incoming_acknowledged-1-j)&UPDATE_MASK ].receivedtime = -2;
  1111. break;
  1112. case svc_modellist:
  1113. CL_ParseModellist ();
  1114. break;
  1115. case svc_soundlist:
  1116. CL_ParseSoundlist ();
  1117. break;
  1118. case svc_packetentities:
  1119. CL_ParsePacketEntities (false);
  1120. break;
  1121. case svc_deltapacketentities:
  1122. CL_ParsePacketEntities (true);
  1123. break;
  1124. case svc_maxspeed :
  1125. movevars.maxspeed = MSG_ReadFloat();
  1126. break;
  1127. case svc_entgravity :
  1128. movevars.entgravity = MSG_ReadFloat();
  1129. break;
  1130. case svc_setpause:
  1131. cl.paused = MSG_ReadByte ();
  1132. if (cl.paused)
  1133. CDAudio_Pause ();
  1134. else
  1135. CDAudio_Resume ();
  1136. break;
  1137. }
  1138. }
  1139. CL_SetSolidEntities ();
  1140. }