home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / cl_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  31.0 KB  |  1,387 lines

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