home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / server / sv_send.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  20KB  |  807 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. // sv_main.c -- server main program
  21.  
  22. #include "qwsvdef.h"
  23.  
  24. #define CHAN_AUTO   0
  25. #define CHAN_WEAPON 1
  26. #define CHAN_VOICE  2
  27. #define CHAN_ITEM   3
  28. #define CHAN_BODY   4
  29.  
  30. /*
  31. =============================================================================
  32.  
  33. Con_Printf redirection
  34.  
  35. =============================================================================
  36. */
  37.  
  38. char  outputbuf[8000];
  39.  
  40. redirect_t  sv_redirected;
  41.  
  42. extern cvar_t sv_phs;
  43.  
  44. /*
  45. ==================
  46. SV_FlushRedirect
  47. ==================
  48. */
  49. void SV_FlushRedirect (void)
  50. {
  51.   char  send[8000+6];
  52.  
  53.   if (sv_redirected == RD_PACKET)
  54.   {
  55.     send[0] = 0xff;
  56.     send[1] = 0xff;
  57.     send[2] = 0xff;
  58.     send[3] = 0xff;
  59.     send[4] = A2C_PRINT;
  60.     memcpy (send+5, outputbuf, strlen(outputbuf)+1);
  61.  
  62.     NET_SendPacket (strlen(send)+1, send, net_from);
  63.   }
  64.   else if (sv_redirected == RD_CLIENT)
  65.   {
  66.     ClientReliableWrite_Begin (host_client, svc_print, strlen(outputbuf)+3);
  67.     ClientReliableWrite_Byte (host_client, PRINT_HIGH);
  68.     ClientReliableWrite_String (host_client, outputbuf);
  69.   }
  70.  
  71.   // clear it
  72.   outputbuf[0] = 0;
  73. }
  74.  
  75.  
  76. /*
  77. ==================
  78. SV_BeginRedirect
  79.  
  80.   Send Con_Printf data to the remote client
  81.   instead of the console
  82. ==================
  83. */
  84. void SV_BeginRedirect (redirect_t rd)
  85. {
  86.   sv_redirected = rd;
  87.   outputbuf[0] = 0;
  88. }
  89.  
  90. void SV_EndRedirect (void)
  91. {
  92.   SV_FlushRedirect ();
  93.   sv_redirected = RD_NONE;
  94. }
  95.  
  96.  
  97. /*
  98. ================
  99. Con_Printf
  100.  
  101. Handles cursor positioning, line wrapping, etc
  102. ================
  103. */
  104. #define MAXPRINTMSG 4096
  105. // FIXME: make a buffer size safe vsprintf?
  106. void Con_Printf (char *fmt, ...)
  107. {
  108.   va_list   argptr;
  109.   char    msg[MAXPRINTMSG];
  110.   
  111.   va_start (argptr,fmt);
  112.   vsprintf (msg,fmt,argptr);
  113.   va_end (argptr);
  114.  
  115.   // add to redirected message
  116.   if (sv_redirected)
  117.   {
  118.     if (strlen (msg) + strlen(outputbuf) > sizeof(outputbuf) - 1)
  119.       SV_FlushRedirect ();
  120.     strcat (outputbuf, msg);
  121.     return;
  122.   }
  123.  
  124.   Sys_Printf ("%s", msg); // also echo to debugging console
  125.   if (sv_logfile)
  126.     fprintf (sv_logfile, "%s", msg);
  127. }
  128.  
  129. /*
  130. ================
  131. Con_DPrintf
  132.  
  133. A Con_Printf that only shows up if the "developer" cvar is set
  134. ================
  135. */
  136. void Con_DPrintf (char *fmt, ...)
  137. {
  138.   va_list   argptr;
  139.   char    msg[MAXPRINTMSG];
  140.  
  141.   if (!developer.value)
  142.     return;
  143.  
  144.   va_start (argptr,fmt);
  145.   vsprintf (msg,fmt,argptr);
  146.   va_end (argptr);
  147.   
  148.   Con_Printf ("%s", msg);
  149. }
  150.  
  151. /*
  152. =============================================================================
  153.  
  154. EVENT MESSAGES
  155.  
  156. =============================================================================
  157. */
  158.  
  159. static void SV_PrintToClient(client_t *cl, int level, char *string)
  160. {
  161.   ClientReliableWrite_Begin (cl, svc_print, strlen(string)+3);
  162.   ClientReliableWrite_Byte (cl, level);
  163.   ClientReliableWrite_String (cl, string);
  164. }
  165.  
  166.  
  167. /*
  168. =================
  169. SV_ClientPrintf
  170.  
  171. Sends text across to be displayed if the level passes
  172. =================
  173. */
  174. void SV_ClientPrintf (client_t *cl, int level, char *fmt, ...)
  175. {
  176.   va_list   argptr;
  177.   char    string[1024];
  178.   
  179.   if (level < cl->messagelevel)
  180.     return;
  181.   
  182.   va_start (argptr,fmt);
  183.   vsprintf (string, fmt,argptr);
  184.   va_end (argptr);
  185.  
  186.   SV_PrintToClient(cl, level, string);
  187. }
  188.  
  189. /*
  190. =================
  191. SV_BroadcastPrintf
  192.  
  193. Sends text to all active clients
  194. =================
  195. */
  196. void SV_BroadcastPrintf (int level, char *fmt, ...)
  197. {
  198.   va_list   argptr;
  199.   char    string[1024];
  200.   client_t  *cl;
  201.   int     i;
  202.  
  203.   va_start (argptr,fmt);
  204.   vsprintf (string, fmt,argptr);
  205.   va_end (argptr);
  206.   
  207.   Sys_Printf ("%s", string);  // print to the console
  208.  
  209.   for (i=0, cl = svs.clients ; i<MAX_CLIENTS ; i++, cl++)
  210.   {
  211.     if (level < cl->messagelevel)
  212.       continue;
  213.     if (!cl->state)
  214.       continue;
  215.  
  216.     SV_PrintToClient(cl, level, string);
  217.   }
  218. }
  219.  
  220. /*
  221. =================
  222. SV_BroadcastCommand
  223.  
  224. Sends text to all active clients
  225. =================
  226. */
  227. void SV_BroadcastCommand (char *fmt, ...)
  228. {
  229.   va_list   argptr;
  230.   char    string[1024];
  231.   
  232.   if (!sv.state)
  233.     return;
  234.   va_start (argptr,fmt);
  235.   vsprintf (string, fmt,argptr);
  236.   va_end (argptr);
  237.  
  238.   MSG_WriteByte (&sv.reliable_datagram, svc_stufftext);
  239.   MSG_WriteString (&sv.reliable_datagram, string);
  240. }
  241.  
  242.  
  243. /*
  244. =================
  245. SV_Multicast
  246.  
  247. Sends the contents of sv.multicast to a subset of the clients,
  248. then clears sv.multicast.
  249.  
  250. MULTICAST_ALL same as broadcast
  251. MULTICAST_PVS send to clients potentially visible from org
  252. MULTICAST_PHS send to clients potentially hearable from org
  253. =================
  254. */
  255. void SV_Multicast (vec3_t origin, int to)
  256. {
  257.   client_t  *client;
  258.   byte    *mask;
  259.   mleaf_t   *leaf;
  260.   int     leafnum;
  261.   int     j;
  262.   qboolean  reliable;
  263.  
  264.   leaf = Mod_PointInLeaf (origin, sv.worldmodel);
  265.   if (!leaf)
  266.     leafnum = 0;
  267.   else
  268.     leafnum = leaf - sv.worldmodel->leafs;
  269.  
  270.   reliable = false;
  271.  
  272.   switch (to)
  273.   {
  274.   case MULTICAST_ALL_R:
  275.     reliable = true;  // intentional fallthrough
  276.   case MULTICAST_ALL:
  277.     mask = sv.pvs;    // leaf 0 is everything;
  278.     break;
  279.  
  280.   case MULTICAST_PHS_R:
  281.     reliable = true;  // intentional fallthrough
  282.   case MULTICAST_PHS:
  283.     mask = sv.phs + leafnum * 4*((sv.worldmodel->numleafs+31)>>5);
  284.     break;
  285.  
  286.   case MULTICAST_PVS_R:
  287.     reliable = true;  // intentional fallthrough
  288.   case MULTICAST_PVS:
  289.     mask = sv.pvs + leafnum * 4*((sv.worldmodel->numleafs+31)>>5);
  290.     break;
  291.  
  292.   default:
  293.     mask = NULL;
  294.     SV_Error ("SV_Multicast: bad to:%i", to);
  295.   }
  296.  
  297.   // send the data to all relevent clients
  298.   for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
  299.   {
  300.     if (client->state != cs_spawned)
  301.       continue;
  302.  
  303.     if (to == MULTICAST_PHS_R || to == MULTICAST_PHS) {
  304.       vec3_t delta;
  305.       VectorSubtract(origin, client->edict->v.origin, delta);
  306.       if (Length(delta) <= 1024)
  307.         goto inrange;
  308.     }
  309.  
  310.     leaf = Mod_PointInLeaf (client->edict->v.origin, sv.worldmodel);
  311.     if (leaf)
  312.     {
  313.       // -1 is because pvs rows are 1 based, not 0 based like leafs
  314.       leafnum = leaf - sv.worldmodel->leafs - 1;
  315.       if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
  316.       {
  317. //        Con_Printf ("supressed multicast\n");
  318.         continue;
  319.       }
  320.     }
  321.  
  322. inrange:
  323.     if (reliable) {
  324.       ClientReliableCheckBlock(client, sv.multicast.cursize);
  325.       ClientReliableWrite_SZ(client, sv.multicast.data, sv.multicast.cursize);
  326.     } else
  327.       SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
  328.   }
  329.  
  330.   SZ_Clear (&sv.multicast);
  331. }
  332.  
  333.  
  334. /*  
  335. ==================
  336. SV_StartSound
  337.  
  338. Each entity can have eight independant sound sources, like voice,
  339. weapon, feet, etc.
  340.  
  341. Channel 0 is an auto-allocate channel, the others override anything
  342. allready running on that entity/channel pair.
  343.  
  344. An attenuation of 0 will play full volume everywhere in the level.
  345. Larger attenuations will drop off.  (max 4 attenuation)
  346.  
  347. ==================
  348. */  
  349. void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
  350.     float attenuation)
  351. {       
  352.     int         sound_num;
  353.     int     field_mask;
  354.     int     i;
  355.   int     ent;
  356.   vec3_t    origin;
  357.   qboolean  use_phs;
  358.   qboolean  reliable = false;
  359.  
  360.   if (volume < 0 || volume > 255)
  361.     SV_Error ("SV_StartSound: volume = %i", volume);
  362.  
  363.   if (attenuation < 0 || attenuation > 4)
  364.     SV_Error ("SV_StartSound: attenuation = %f", attenuation);
  365.  
  366.   if (channel < 0 || channel > 15)
  367.     SV_Error ("SV_StartSound: channel = %i", channel);
  368.  
  369. // find precache number for sound
  370.     for (sound_num=1 ; sound_num<MAX_SOUNDS
  371.         && sv.sound_precache[sound_num] ; sound_num++)
  372.         if (!strcmp(sample, sv.sound_precache[sound_num]))
  373.             break;
  374.     
  375.     if ( sound_num == MAX_SOUNDS || !sv.sound_precache[sound_num] )
  376.     {
  377.         Con_Printf ("SV_StartSound: %s not precacheed\n", sample);
  378.         return;
  379.     }
  380.     
  381.   ent = NUM_FOR_EDICT(entity);
  382.  
  383.   if ((channel & 8) || !sv_phs.value) // no PHS flag
  384.   {
  385.     if (channel & 8)
  386.       reliable = true; // sounds that break the phs are reliable
  387.     use_phs = false;
  388.     channel &= 7;
  389.   }
  390.   else
  391.     use_phs = true;
  392.  
  393. //  if (channel == CHAN_BODY || channel == CHAN_VOICE)
  394. //    reliable = true;
  395.  
  396.   channel = (ent<<3) | channel;
  397.  
  398.   field_mask = 0;
  399.   if (volume != DEFAULT_SOUND_PACKET_VOLUME)
  400.     channel |= SND_VOLUME;
  401.   if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
  402.     channel |= SND_ATTENUATION;
  403.  
  404.   // use the entity origin unless it is a bmodel
  405.   if (entity->v.solid == SOLID_BSP)
  406.   {
  407.     for (i=0 ; i<3 ; i++)
  408.       origin[i] = entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]);
  409.   }
  410.   else
  411.   {
  412.     VectorCopy (entity->v.origin, origin);
  413.   }
  414.  
  415.   MSG_WriteByte (&sv.multicast, svc_sound);
  416.   MSG_WriteShort (&sv.multicast, channel);
  417.   if (channel & SND_VOLUME)
  418.     MSG_WriteByte (&sv.multicast, volume);
  419.   if (channel & SND_ATTENUATION)
  420.     MSG_WriteByte (&sv.multicast, attenuation*64);
  421.   MSG_WriteByte (&sv.multicast, sound_num);
  422.   for (i=0 ; i<3 ; i++)
  423.     MSG_WriteCoord (&sv.multicast, origin[i]);
  424.  
  425.   if (use_phs)
  426.     SV_Multicast (origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS);
  427.   else
  428.     SV_Multicast (origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL);
  429. }           
  430.  
  431.  
  432. /*
  433. ===============================================================================
  434.  
  435. FRAME UPDATES
  436.  
  437. ===============================================================================
  438. */
  439.  
  440. int   sv_nailmodel, sv_supernailmodel, sv_playermodel;
  441.  
  442. void SV_FindModelNumbers (void)
  443. {
  444.   int   i;
  445.  
  446.   sv_nailmodel = -1;
  447.   sv_supernailmodel = -1;
  448.   sv_playermodel = -1;
  449.  
  450.   for (i=0 ; i<MAX_MODELS ; i++)
  451.   {
  452.     if (!sv.model_precache[i])
  453.       break;
  454.     if (!strcmp(sv.model_precache[i],"progs/spike.mdl"))
  455.       sv_nailmodel = i;
  456.     if (!strcmp(sv.model_precache[i],"progs/s_spike.mdl"))
  457.       sv_supernailmodel = i;
  458.     if (!strcmp(sv.model_precache[i],"progs/player.mdl"))
  459.       sv_playermodel = i;
  460.   }
  461. }
  462.  
  463.  
  464. /*
  465. ==================
  466. SV_WriteClientdataToMessage
  467.  
  468. ==================
  469. */
  470. void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
  471. {
  472.   int   i;
  473.   edict_t *other;
  474.   edict_t *ent;
  475.  
  476.   ent = client->edict;
  477.  
  478.   // send the chokecount for r_netgraph
  479.   if (client->chokecount)
  480.   {
  481.     MSG_WriteByte (msg, svc_chokecount);
  482.     MSG_WriteByte (msg, client->chokecount);
  483.     client->chokecount = 0;
  484.   }
  485.  
  486.   // send a damage message if the player got hit this frame
  487.   if (ent->v.dmg_take || ent->v.dmg_save)
  488.   {
  489.     other = PROG_TO_EDICT(ent->v.dmg_inflictor);
  490.     MSG_WriteByte (msg, svc_damage);
  491.     MSG_WriteByte (msg, ent->v.dmg_save);
  492.     MSG_WriteByte (msg, ent->v.dmg_take);
  493.     for (i=0 ; i<3 ; i++)
  494.       MSG_WriteCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]));
  495.   
  496.     ent->v.dmg_take = 0;
  497.     ent->v.dmg_save = 0;
  498.   }
  499.  
  500.   // a fixangle might get lost in a dropped packet.  Oh well.
  501.   if ( ent->v.fixangle )
  502.   {
  503.     MSG_WriteByte (msg, svc_setangle);
  504.     for (i=0 ; i < 3 ; i++)
  505.       MSG_WriteAngle (msg, ent->v.angles[i] );
  506.     ent->v.fixangle = 0;
  507.   }
  508. }
  509.  
  510. /*
  511. =======================
  512. SV_UpdateClientStats
  513.  
  514. Performs a delta update of the stats array.  This should only be performed
  515. when a reliable message can be delivered this frame.
  516. =======================
  517. */
  518. void SV_UpdateClientStats (client_t *client)
  519. {
  520.   edict_t *ent;
  521.   int   stats[MAX_CL_STATS];
  522.   int   i;
  523.   
  524.   ent = client->edict;
  525.   memset (stats, 0, sizeof(stats));
  526.   
  527.   // if we are a spectator and we are tracking a player, we get his stats
  528.   // so our status bar reflects his
  529.   if (client->spectator && client->spec_track > 0)
  530.     ent = svs.clients[client->spec_track - 1].edict;
  531.  
  532.   stats[STAT_HEALTH] = ent->v.health;
  533.   stats[STAT_WEAPON] = SV_ModelIndex(PR_GetString(ent->v.weaponmodel));
  534.   stats[STAT_AMMO] = ent->v.currentammo;
  535.   stats[STAT_ARMOR] = ent->v.armorvalue;
  536.   stats[STAT_SHELLS] = ent->v.ammo_shells;
  537.   stats[STAT_NAILS] = ent->v.ammo_nails;
  538.   stats[STAT_ROCKETS] = ent->v.ammo_rockets;
  539.   stats[STAT_CELLS] = ent->v.ammo_cells;
  540.   if (!client->spectator)
  541.     stats[STAT_ACTIVEWEAPON] = ent->v.weapon;
  542.   // stuff the sigil bits into the high bits of items for sbar
  543.   stats[STAT_ITEMS] = (int)ent->v.items | ((int)pr_global_struct->serverflags << 28);
  544.  
  545.   for (i=0 ; i<MAX_CL_STATS ; i++)
  546.     if (stats[i] != client->stats[i])
  547.     {
  548.       client->stats[i] = stats[i];
  549.       if (stats[i] >=0 && stats[i] <= 255)
  550.       {
  551.         ClientReliableWrite_Begin(client, svc_updatestat, 3);
  552.         ClientReliableWrite_Byte(client, i);
  553.         ClientReliableWrite_Byte(client, stats[i]);
  554.       }
  555.       else
  556.       {
  557.         ClientReliableWrite_Begin(client, svc_updatestatlong, 6);
  558.         ClientReliableWrite_Byte(client, i);
  559.         ClientReliableWrite_Long(client, stats[i]);
  560.       }
  561.     }
  562. }
  563.  
  564. /*
  565. =======================
  566. SV_SendClientDatagram
  567. =======================
  568. */
  569. qboolean SV_SendClientDatagram (client_t *client)
  570. {
  571.   byte    buf[MAX_DATAGRAM];
  572.   sizebuf_t msg;
  573.  
  574.   msg.data = buf;
  575.   msg.maxsize = sizeof(buf);
  576.   msg.cursize = 0;
  577.   msg.allowoverflow = true;
  578.   msg.overflowed = false;
  579.  
  580.   // add the client specific data to the datagram
  581.   SV_WriteClientdataToMessage (client, &msg);
  582.  
  583.   // send over all the objects that are in the PVS
  584.   // this will include clients, a packetentities, and
  585.   // possibly a nails update
  586.   SV_WriteEntitiesToClient (client, &msg);
  587.  
  588.   // copy the accumulated multicast datagram
  589.   // for this client out to the message
  590.   if (client->datagram.overflowed)
  591.     Con_Printf ("WARNING: datagram overflowed for %s\n", client->name);
  592.   else
  593.     SZ_Write (&msg, client->datagram.data, client->datagram.cursize);
  594.   SZ_Clear (&client->datagram);
  595.  
  596.   // send deltas over reliable stream
  597.   if (Netchan_CanReliable (&client->netchan))
  598.     SV_UpdateClientStats (client);
  599.  
  600.   if (msg.overflowed)
  601.   {
  602.     Con_Printf ("WARNING: msg overflowed for %s\n", client->name);
  603.     SZ_Clear (&msg);
  604.   }
  605.  
  606.   // send the datagram
  607.   Netchan_Transmit (&client->netchan, msg.cursize, buf);
  608.  
  609.   return true;
  610. }
  611.  
  612. /*
  613. =======================
  614. SV_UpdateToReliableMessages
  615. =======================
  616. */
  617. void SV_UpdateToReliableMessages (void)
  618. {
  619.   int     i, j;
  620.   client_t *client;
  621.   eval_t *val;
  622.   edict_t *ent;
  623.  
  624. // check for changes to be sent over the reliable streams to all clients
  625.   for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
  626.   {
  627.     if (host_client->state != cs_spawned)
  628.       continue;
  629.     if (host_client->sendinfo)
  630.     {
  631.       host_client->sendinfo = false;
  632.       SV_FullClientUpdate (host_client, &sv.reliable_datagram);
  633.     }
  634.     if (host_client->old_frags != host_client->edict->v.frags)
  635.     {
  636.       for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
  637.       {
  638.         if (client->state < cs_connected)
  639.           continue;
  640.         ClientReliableWrite_Begin(client, svc_updatefrags, 4);
  641.         ClientReliableWrite_Byte(client, i);
  642.         ClientReliableWrite_Short(client, host_client->edict->v.frags);
  643.       }
  644.  
  645.       host_client->old_frags = host_client->edict->v.frags;
  646.     }
  647.  
  648.     // maxspeed/entgravity changes
  649.     ent = host_client->edict;
  650.  
  651.     val = GetEdictFieldValue(ent, "gravity");
  652.     if (val && host_client->entgravity != val->_float) {
  653.       host_client->entgravity = val->_float;
  654.       ClientReliableWrite_Begin(host_client, svc_entgravity, 5);
  655.       ClientReliableWrite_Float(host_client, host_client->entgravity);
  656.     }
  657.     val = GetEdictFieldValue(ent, "maxspeed");
  658.     if (val && host_client->maxspeed != val->_float) {
  659.       host_client->maxspeed = val->_float;
  660.       ClientReliableWrite_Begin(host_client, svc_maxspeed, 5);
  661.       ClientReliableWrite_Float(host_client, host_client->maxspeed);
  662.     }
  663.  
  664.   }
  665.  
  666.   if (sv.datagram.overflowed)
  667.     SZ_Clear (&sv.datagram);
  668.  
  669.   // append the broadcast messages to each client messages
  670.   for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
  671.   {
  672.     if (client->state < cs_connected)
  673.       continue; // reliables go to all connected or spawned
  674.  
  675.     ClientReliableCheckBlock(client, sv.reliable_datagram.cursize);
  676.     ClientReliableWrite_SZ(client, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
  677.  
  678.     if (client->state != cs_spawned)
  679.       continue; // datagrams only go to spawned
  680.     SZ_Write (&client->datagram
  681.       , sv.datagram.data
  682.       , sv.datagram.cursize);
  683.   }
  684.  
  685.   SZ_Clear (&sv.reliable_datagram);
  686.   SZ_Clear (&sv.datagram);
  687. }
  688.  
  689. #ifdef _WIN32
  690. #pragma optimize( "", off )
  691. #endif
  692.  
  693.  
  694.  
  695. /*
  696. =======================
  697. SV_SendClientMessages
  698. =======================
  699. */
  700. void SV_SendClientMessages (void)
  701. {
  702.   int     i, j;
  703.   client_t  *c;
  704.  
  705. // update frags, names, etc
  706.   SV_UpdateToReliableMessages ();
  707.  
  708. // build individual updates
  709.   for (i=0, c = svs.clients ; i<MAX_CLIENTS ; i++, c++)
  710.   {
  711.     if (!c->state)
  712.       continue;
  713.  
  714.     if (c->drop) {
  715.       SV_DropClient(c);
  716.       c->drop = false;
  717.       continue;
  718.     }
  719.  
  720.     // check to see if we have a backbuf to stick in the reliable
  721.     if (c->num_backbuf) {
  722.       // will it fit?
  723.       if (c->netchan.message.cursize + c->backbuf_size[0] <
  724.         c->netchan.message.maxsize) {
  725.  
  726.         Con_DPrintf("%s: backbuf %d bytes\n",
  727.           c->name, c->backbuf_size[0]);
  728.  
  729.         // it'll fit
  730.         SZ_Write(&c->netchan.message, c->backbuf_data[0],
  731.           c->backbuf_size[0]);
  732.         
  733.         //move along, move along
  734.         for (j = 1; j < c->num_backbuf; j++) {
  735.           memcpy(c->backbuf_data[j - 1], c->backbuf_data[j],
  736.             c->backbuf_size[j]);
  737.           c->backbuf_size[j - 1] = c->backbuf_size[j];
  738.         }
  739.  
  740.         c->num_backbuf--;
  741.         if (c->num_backbuf) {
  742.           memset(&c->backbuf, 0, sizeof(c->backbuf));
  743.           c->backbuf.data = c->backbuf_data[c->num_backbuf - 1];
  744.           c->backbuf.cursize = c->backbuf_size[c->num_backbuf - 1];
  745.           c->backbuf.maxsize = sizeof(c->backbuf_data[c->num_backbuf - 1]);
  746.         }
  747.       }
  748.     }
  749.  
  750.     // if the reliable message overflowed,
  751.     // drop the client
  752.     if (c->netchan.message.overflowed)
  753.     {
  754.       SZ_Clear (&c->netchan.message);
  755.       SZ_Clear (&c->datagram);
  756.       SV_BroadcastPrintf (PRINT_HIGH, "%s overflowed\n", c->name);
  757.       Con_Printf ("WARNING: reliable overflow for %s\n",c->name);
  758.       SV_DropClient (c);
  759.       c->send_message = true;
  760.       c->netchan.cleartime = 0; // don't choke this message
  761.     }
  762.  
  763.     // only send messages if the client has sent one
  764.     // and the bandwidth is not choked
  765.     if (!c->send_message)
  766.       continue;
  767.     c->send_message = false;  // try putting this after choke?
  768.     if (!sv.paused && !Netchan_CanPacket (&c->netchan))
  769.     {
  770.       c->chokecount++;
  771.       continue;   // bandwidth choke
  772.     }
  773.  
  774.     if (c->state == cs_spawned)
  775.       SV_SendClientDatagram (c);
  776.     else
  777.       Netchan_Transmit (&c->netchan, 0, NULL);  // just update reliable
  778.       
  779.   }
  780. }
  781.  
  782. #ifdef _WIN32
  783. #pragma optimize( "", on )
  784. #endif
  785.  
  786.  
  787.  
  788. /*
  789. =======================
  790. SV_SendMessagesToAll
  791.  
  792. FIXME: does this sequence right?
  793. =======================
  794. */
  795. void SV_SendMessagesToAll (void)
  796. {
  797.   int     i;
  798.   client_t  *c;
  799.  
  800.   for (i=0, c = svs.clients ; i<MAX_CLIENTS ; i++, c++)
  801.     if (c->state)   // FIXME: should this only send to active?
  802.       c->send_message = true;
  803.   
  804.   SV_SendClientMessages ();
  805. }
  806.  
  807.