sv_send.c 18 KB

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