packetmgr.cpp 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** 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, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/wwnet/packetmgr.cpp $*
  25. * *
  26. * $Author:: Steve_t $*
  27. * *
  28. * $Modtime:: 8/08/02 3:26p $*
  29. * *
  30. * $Revision:: 36 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "packetmgr.h"
  36. #include <always.h>
  37. #include <memory.h>
  38. //#include <winsock.h>
  39. #include "systimer.h"
  40. #include <malloc.h>
  41. #include "netutil.h"
  42. #include "wwmemlog.h"
  43. #include "crc.h"
  44. #include "wwprofile.h"
  45. #include "connect.h"
  46. /*
  47. ** Single instance of PacketManagerClass.
  48. */
  49. PacketManagerClass PacketManager;
  50. /***********************************************************************************************
  51. * PacketManagerClass::Add_Bit -- Add a bit to a delta compressed packet stream *
  52. * *
  53. * *
  54. * *
  55. * INPUT: Bit to add as a bool - true or false *
  56. * Ptr to bitstream *
  57. * Bit position at pointer *
  58. * *
  59. * OUTPUT: New bit position *
  60. * *
  61. * WARNINGS: None *
  62. * *
  63. * HISTORY: *
  64. * 9/24/2001 1:34PM ST : Created *
  65. *=============================================================================================*/
  66. inline int PacketManagerClass::Add_Bit(bool bit, unsigned char * &bitstream, int &position)
  67. {
  68. pm_assert(position < 8);
  69. unsigned char whole = bit ? 1 : 0;
  70. whole <<= position;
  71. *bitstream |= whole;
  72. position++;
  73. if (position == 8) {
  74. bitstream++;
  75. *bitstream = 0;
  76. position = 0;
  77. }
  78. return(position);
  79. }
  80. /***********************************************************************************************
  81. * PacketManagerClass::Get_Bit -- Get a bit from a delta compressed bitstream *
  82. * *
  83. * *
  84. * *
  85. * INPUT: Ptr to bitstream *
  86. * Bit position *
  87. * *
  88. * OUTPUT: 0 or 1 *
  89. * *
  90. * WARNINGS: None *
  91. * *
  92. * HISTORY: *
  93. * 9/24/2001 1:35PM ST : Created *
  94. *=============================================================================================*/
  95. inline unsigned char PacketManagerClass::Get_Bit(unsigned char * &bitstream, int &position)
  96. {
  97. pm_assert(position < 8);
  98. unsigned char whole = *bitstream;
  99. whole >>= position;
  100. whole &= 1;
  101. position++;
  102. if (position == 8) {
  103. bitstream++;
  104. position = 0;
  105. }
  106. return(whole);
  107. }
  108. /***********************************************************************************************
  109. * PacketManagerClass::PacketManagerClass -- Class constructor. *
  110. * *
  111. * *
  112. * *
  113. * INPUT: Nothing *
  114. * *
  115. * OUTPUT: Nothing *
  116. * *
  117. * WARNINGS: None *
  118. * *
  119. * HISTORY: *
  120. * 9/24/2001 1:36PM ST : Created *
  121. *=============================================================================================*/
  122. PacketManagerClass::PacketManagerClass(void)
  123. {
  124. BandwidthList.Set_Growth_Step(128);
  125. //memset(PacketLengths, 0, sizeof(PacketLengths));
  126. NextPacket = 0;
  127. NumPackets = 0;
  128. NumReceivePackets = 0;
  129. CurrentPacket = 0;
  130. LastSendTime = 0;
  131. FlushFrequency = 1000 / 10; // Default = 10 times per second.
  132. AllowDeltas = true;
  133. AllowCombos = true;
  134. StatsFrequency = 10 * 1000;
  135. LastStatsUpdate = TIMEGETTIME();
  136. ErrorState = STATE_OK;
  137. ResetStatsIn = true;
  138. ResetStatsOut = true;
  139. NumSendBuffers = PACKET_MANAGER_BUFFERS;
  140. SendBuffers = new SendBufferClass[NumSendBuffers];
  141. NumReceiveBuffers = PACKET_MANAGER_RECEIVE_BUFFERS;
  142. ReceiveBuffers = new ReceiveBufferClass[NumReceiveBuffers];
  143. }
  144. /***********************************************************************************************
  145. * PacketManagerClass::~PacketManagerClass -- Class destructor *
  146. * *
  147. * *
  148. * *
  149. * INPUT: Nothing *
  150. * *
  151. * OUTPUT: Nothing *
  152. * *
  153. * WARNINGS: None *
  154. * *
  155. * HISTORY: *
  156. * 10/15/2001 11:24AM ST : Created *
  157. *=============================================================================================*/
  158. PacketManagerClass::~PacketManagerClass(void)
  159. {
  160. if (SendBuffers) {
  161. delete [] SendBuffers;
  162. SendBuffers = NULL;
  163. }
  164. if (ReceiveBuffers) {
  165. delete [] ReceiveBuffers;
  166. ReceiveBuffers = NULL;
  167. }
  168. }
  169. /***********************************************************************************************
  170. * PacketManagerClass::Set_Is_Server -- Set whether to operate in server mode or not. *
  171. * *
  172. * *
  173. * *
  174. * INPUT: is_server - true if we are to be a server *
  175. * *
  176. * OUTPUT: Nothing *
  177. * *
  178. * WARNINGS: None *
  179. * *
  180. * HISTORY: *
  181. * 10/15/2001 11:29AM ST : Created *
  182. *=============================================================================================*/
  183. void PacketManagerClass::Set_Is_Server(bool is_server)
  184. {
  185. CriticalSectionClass::LockClass lock(CriticalSection);
  186. WWMEMLOG(MEM_NETWORK);
  187. bool reset = false;
  188. if (is_server && NumSendBuffers != PACKET_MANAGER_BUFFERS_WHEN_SERVER) {
  189. NumSendBuffers = PACKET_MANAGER_BUFFERS_WHEN_SERVER;
  190. NumReceiveBuffers = PACKET_MANAGER_RECEIVE_BUFFERS_AS_SERVER;
  191. reset = true;
  192. } else {
  193. if (!is_server && NumSendBuffers != PACKET_MANAGER_BUFFERS) {
  194. NumSendBuffers = PACKET_MANAGER_BUFFERS;
  195. NumReceiveBuffers = PACKET_MANAGER_RECEIVE_BUFFERS;
  196. reset = true;
  197. }
  198. }
  199. if (reset) {
  200. NextPacket = 0;
  201. NumPackets = 0;
  202. NumReceivePackets = 0;
  203. CurrentPacket = 0;
  204. if (SendBuffers) {
  205. delete [] SendBuffers;
  206. }
  207. SendBuffers = new SendBufferClass[NumSendBuffers];
  208. if (ReceiveBuffers) {
  209. delete [] ReceiveBuffers;
  210. }
  211. ReceiveBuffers = new ReceiveBufferClass[NumReceiveBuffers];
  212. Reset_Stats();
  213. }
  214. }
  215. /***********************************************************************************************
  216. * PacketManagerClass::Build_Delta_Packet_Patch -- Calc a delta between two packets *
  217. * *
  218. * *
  219. * *
  220. * INPUT: Ptr to base packet *
  221. * Ptr to packet to compare with base packet *
  222. * Ptr to delta patch that describes differences between base and add packets *
  223. * Size of base packet (packet sizes must match) *
  224. * Size of add packet (must match base packets size) *
  225. * *
  226. * OUTPUT: Size of delta patch *
  227. * *
  228. * WARNINGS: None *
  229. * *
  230. * HISTORY: *
  231. * 9/24/2001 1:36PM ST : Created *
  232. *=============================================================================================*/
  233. int PacketManagerClass::Build_Delta_Packet_Patch(unsigned char *base_packet, unsigned char *add_packet, unsigned char *delta_packet, int base_packet_size, int add_packet_size)
  234. {
  235. /*
  236. ** Here's how this works.
  237. **
  238. ** The source and delta packets are compared 8 bytes at a time and am equality bit is set in the output stream
  239. ** for each block of 8. Then, for each non-matching block, a per byte bit is set in the output stream to indicate
  240. ** whether a byte can be used from the base packet or if a patch byte is needed. Finally, patch bytes are added to
  241. ** the stream at the end starting at a byte boundry.
  242. **
  243. */
  244. /*
  245. ** Locals.
  246. */
  247. int write_bit_pos = 0;
  248. int read_bit_pos = 0;
  249. int num_diff_bytes = 0;
  250. unsigned char diff_bytes[1024];
  251. /*
  252. ** Parameter asserts.
  253. */
  254. pm_assert(base_packet != NULL);
  255. pm_assert(add_packet != NULL);
  256. pm_assert(delta_packet != NULL);
  257. pm_assert(base_packet_size == add_packet_size);
  258. pm_assert(base_packet_size < sizeof(diff_bytes));
  259. /*
  260. ** dereference pointers to the packet header and the packet build pointer.
  261. */
  262. PacketDeltaHeaderStruct *header = (PacketDeltaHeaderStruct*) delta_packet;
  263. unsigned char *build_delta_ptr = delta_packet + sizeof(PacketDeltaHeaderStruct);
  264. unsigned char *chunk_ptr = build_delta_ptr;
  265. pm_assert(sizeof(PacketDeltaHeaderStruct) == 1);
  266. *build_delta_ptr = 0;
  267. header->BytePack = 0;
  268. if (base_packet_size == add_packet_size) {
  269. /*
  270. ** Break it up into 8 byte chunks and see whether any of the chunks are the same.
  271. */
  272. bool chunks = false;
  273. bool this_match = false;
  274. for (int i=0 ; i<base_packet_size - 7 ; i+=8) {
  275. this_match = false;
  276. if (*((long*)&base_packet[i]) == *((long*)&add_packet[i])) {
  277. if (*((long*)&base_packet[i+4]) == *((long*)&add_packet[i+4])) {
  278. chunks = true;
  279. this_match = true;
  280. }
  281. }
  282. write_bit_pos = Add_Bit(this_match, build_delta_ptr, write_bit_pos);
  283. }
  284. /*
  285. ** Mark the tail end of the buffer as different.
  286. */
  287. if ((base_packet_size & 7) != 0) {
  288. if (chunks) {
  289. write_bit_pos = Add_Bit(false, build_delta_ptr, write_bit_pos);
  290. }
  291. }
  292. /*
  293. ** If none of the chunks were the same then this is a pointless endevour. Mark in the header that we don't have
  294. ** chunk info and move on to trying byte for byte.
  295. */
  296. header->ChunkPack = chunks ? 1 : 0;
  297. /*
  298. ** Lost the useless chunk info if none of the chunks matched anyway.
  299. */
  300. if (!chunks) {
  301. build_delta_ptr = chunk_ptr;
  302. *build_delta_ptr = 0;
  303. write_bit_pos = 0;
  304. }
  305. /*
  306. ** Try a byte for byte check in the chunks that don't match. For any bytes that are different, save the changed value
  307. ** so we can add it to the end of the delta packet later.
  308. */
  309. read_bit_pos = 0;
  310. num_diff_bytes = 0;
  311. for (i=0 ; i<base_packet_size ; i+= 8) {
  312. /*
  313. ** If we have chunk info, then use it to skip matching chunks.
  314. */
  315. if (chunks) {
  316. if (Get_Bit(chunk_ptr, read_bit_pos)) {
  317. continue;
  318. }
  319. }
  320. /*
  321. ** If this chunk didn't match then go through byte by byte and note differences.
  322. */
  323. for (int j=i ; j<i+8 && j<base_packet_size ; j++) {
  324. header->BytePack = 1;
  325. this_match = (base_packet[j] == add_packet[j]) ? true : false;
  326. write_bit_pos = Add_Bit(this_match, build_delta_ptr, write_bit_pos);
  327. if (!this_match) {
  328. diff_bytes[num_diff_bytes++] = add_packet[j];
  329. }
  330. }
  331. }
  332. /*
  333. ** OK, now we have bitfields that mark the differences. A 1 in the bitfield means that the corresponding chunk or byte
  334. ** in the add packet is the same as in the base packet.
  335. ** Throw the non-matching bytes onto the end of the bitfield and we have a complete delta patch.
  336. */
  337. unsigned char *delta_bytes_ptr = build_delta_ptr;
  338. if (write_bit_pos != 0) {
  339. delta_bytes_ptr++;
  340. }
  341. memcpy(delta_bytes_ptr, diff_bytes, num_diff_bytes);
  342. /*
  343. ** Calculate the size of the whole delta patch.
  344. */
  345. int patch_size = (delta_bytes_ptr - delta_packet) + num_diff_bytes;
  346. return(patch_size);
  347. }
  348. return(-1);
  349. }
  350. /***********************************************************************************************
  351. * PacketManagerClass::Reconstruct_From_Delta -- Rebuild a packet from a delta stream *
  352. * *
  353. * *
  354. * *
  355. * INPUT: Base packet to copy same bytes from *
  356. * Buffer to store reconstructed packet into *
  357. * Ptr to delta packet stream. *
  358. * Size of base packet *
  359. * (out) bytes extracted from delta stream *
  360. * *
  361. * OUTPUT: Size of restored packet (should match size of base packet) *
  362. * *
  363. * WARNINGS: None *
  364. * *
  365. * HISTORY: *
  366. * 9/26/2001 2:14PM ST : Created *
  367. *=============================================================================================*/
  368. int PacketManagerClass::Reconstruct_From_Delta(unsigned char *base_packet, unsigned char *reconstructed_packet, unsigned char *delta_packet, int base_packet_size, int &delta_size)
  369. {
  370. if (base_packet == NULL) {
  371. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Reconstruct_From_Delta -- Bad base packet\n"));
  372. return(0);
  373. }
  374. if (reconstructed_packet == NULL) {
  375. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Reconstruct_From_Delta -- Bad reconstructed packet\n"));
  376. return(0);
  377. }
  378. if (delta_packet == NULL) {
  379. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Reconstruct_From_Delta -- Bad delta packet\n"));
  380. return(0);
  381. }
  382. if (base_packet_size > 500) {
  383. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Reconstruct_From_Delta -- Bad base packet size\n"));
  384. return(0);
  385. }
  386. pm_assert(base_packet != NULL);
  387. pm_assert(reconstructed_packet != NULL);
  388. pm_assert(delta_packet != NULL);
  389. int patch_list[1024];
  390. int num_patches = 0;
  391. int read_bit_pos = 0;
  392. int read_chunk_pos = 0;
  393. int restored_bytes = 0;
  394. PacketDeltaHeaderStruct *header = (PacketDeltaHeaderStruct*) delta_packet;
  395. unsigned char *read_delta_ptr = delta_packet + sizeof(PacketDeltaHeaderStruct);
  396. pm_assert(sizeof(PacketDeltaHeaderStruct) == 1);
  397. unsigned char *chunk_ptr = read_delta_ptr;
  398. /*
  399. ** If there is chunk info then extract that first. Use it to copy the approprate parts of the base packet into the add packet.
  400. */
  401. if (header->ChunkPack) {
  402. for (int i=0 ; i<base_packet_size - 7 ; i+=8) {
  403. if (Get_Bit(read_delta_ptr, read_bit_pos)) {
  404. memcpy(&reconstructed_packet[i], &base_packet[i], 8);
  405. restored_bytes += 8;
  406. }
  407. }
  408. /*
  409. ** If the packet isn't an even number of chunks long then pull out an extra bit and throw it away. It should always be 0.
  410. */
  411. if ((base_packet_size & 7) != 0) {
  412. //#ifdef WWDEBUG
  413. unsigned char bitty =
  414. //#endif //WWDEBUG
  415. Get_Bit(read_delta_ptr, read_bit_pos);
  416. if (bitty != 0) {
  417. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Reconstruct_From_Delta -- Bad bitty\n"));
  418. return(0);
  419. }
  420. pm_assert(bitty == 0);
  421. }
  422. }
  423. /*
  424. ** Now use the per byte bitmask to restore the rest of the data.
  425. */
  426. for (int i=0 ; i<base_packet_size ; i+= 8) {
  427. /*
  428. ** If we have chunk info, then use it to skip matching chunks.
  429. */
  430. if (header->ChunkPack) {
  431. if (Get_Bit(chunk_ptr, read_chunk_pos)) {
  432. continue;
  433. }
  434. }
  435. /*
  436. ** If this chunk didn't match then go through byte by byte and note differences.
  437. */
  438. for (int j=i ; j<i+8 && j<base_packet_size ; j++) {
  439. if (Get_Bit(read_delta_ptr, read_bit_pos)) {
  440. reconstructed_packet[j] = base_packet[j];
  441. restored_bytes++;
  442. } else {
  443. patch_list[num_patches++] = j;
  444. }
  445. }
  446. }
  447. /*
  448. ** Well, the patch bytes must be here somewhere.
  449. */
  450. unsigned char *patch_bytes = read_delta_ptr;
  451. if (read_bit_pos != 0) {
  452. patch_bytes++;
  453. }
  454. /*
  455. ** Work out how many delta bytes we processed - it's needed for meta packet decoding.
  456. */
  457. delta_size = (patch_bytes - delta_packet) + num_patches;
  458. /*
  459. ** Copy the patch bytes into the correct positions.
  460. */
  461. for (int p=0 ; p<num_patches ; p++) {
  462. reconstructed_packet[patch_list[p]] = *patch_bytes++;
  463. }
  464. restored_bytes += num_patches;
  465. //pm_assert(restored_bytes == base_packet_size);
  466. return(restored_bytes);
  467. }
  468. /***********************************************************************************************
  469. * PacketManagerClass::Get_Next_Free_Buffer_Index -- Get next buffer to use for taking packets *
  470. * *
  471. * *
  472. * *
  473. * INPUT: Nothing *
  474. * *
  475. * OUTPUT: Buffer index (-1 if none free) *
  476. * *
  477. * WARNINGS: None *
  478. * *
  479. * HISTORY: *
  480. * 9/26/2001 2:17PM ST : Created *
  481. *=============================================================================================*/
  482. int PacketManagerClass::Get_Next_Free_Buffer_Index(void)
  483. {
  484. int return_index = -1;
  485. for (int i=0 ; i<NumSendBuffers ; i++) {
  486. NextPacket++;
  487. if (NextPacket >= NumSendBuffers) {
  488. NextPacket = 0;
  489. }
  490. if (SendBuffers[NextPacket].PacketLength == 0) {
  491. return_index = NextPacket;
  492. break;
  493. }
  494. }
  495. return(return_index);
  496. }
  497. /***********************************************************************************************
  498. * PacketManagerClass::Take_Packet -- Intercept a packet before it's sent *
  499. * *
  500. * *
  501. * *
  502. * INPUT: Ptr to packet *
  503. * Length of packet *
  504. * IP of packet recipient *
  505. * Port of packet recipient *
  506. * *
  507. * OUTPUT: True if packet was accepted *
  508. * *
  509. * WARNINGS: None *
  510. * *
  511. * HISTORY: *
  512. * 9/18/2001 4:24PM ST : Created *
  513. *=============================================================================================*/
  514. bool PacketManagerClass::Take_Packet(unsigned char *packet, int packet_len, unsigned char *dest_ip, unsigned short dest_port, SOCKET source_socket)
  515. {
  516. CriticalSectionClass::LockClass lock(CriticalSection);
  517. if (NumPackets < NumSendBuffers) {
  518. if (packet_len > 0 && packet_len < (PACKET_MANAGER_MTU - sizeof(PacketPackHeaderStruct))) {
  519. int index = Get_Next_Free_Buffer_Index();
  520. if (index != -1) {
  521. memcpy(SendBuffers[index].PacketBuffer, packet, packet_len);
  522. SendBuffers[index].PacketLength = packet_len;
  523. SendBuffers[index].Port = dest_port;
  524. memcpy(&SendBuffers[index].IPAddress[0], dest_ip, 4);
  525. SendBuffers[index].PacketSendSocket = source_socket;
  526. NumPackets++;
  527. //WWDEBUG_SAY(("NumPackets = %d (added packet at index %d)\n", NumPackets, index));
  528. if (NumPackets > NumSendBuffers - 4) {
  529. WWDEBUG_SAY(("***WARNING*** Outgoing packet buffer full - NumPackets = %d\n", NumPackets, index));
  530. Flush(true);
  531. WWDEBUG_SAY(("NumPackets = %d after flush\n", NumPackets, index));
  532. }
  533. Register_Packet_Out(dest_ip, dest_port, 0, packet_len + UDP_HEADER_SIZE);
  534. return(true);
  535. }
  536. }
  537. }
  538. return(false);
  539. }
  540. /***********************************************************************************************
  541. * PacketManagerClass::Flush -- Coalesce and send any pending packets *
  542. * *
  543. * *
  544. * *
  545. * INPUT: Forced - set to true if packets should be sent even if it's not time *
  546. * *
  547. * OUTPUT: Nothing *
  548. * *
  549. * WARNINGS: None *
  550. * *
  551. * HISTORY: *
  552. * 9/26/2001 2:19PM ST : Created *
  553. *=============================================================================================*/
  554. void PacketManagerClass::Flush(bool forced)
  555. {
  556. {
  557. WWPROFILE("PMgr Flush");
  558. CriticalSectionClass::LockClass lock(CriticalSection);
  559. int base_index = -1;
  560. int length = 0;
  561. unsigned char *base_packet = NULL;
  562. int new_length = 0;
  563. PacketPackHeaderStruct *header = (PacketPackHeaderStruct*) BuildPacket;
  564. unsigned char *next_packet_pos = NULL;
  565. int index = 0;
  566. int i;
  567. SOCKET socket = INVALID_SOCKET;
  568. /*
  569. ** If it's not time to send packets yet then just return.
  570. */
  571. unsigned long time = TIMEGETTIME();
  572. if (!forced && FlushFrequency != 0) {
  573. if (time - LastSendTime < FlushFrequency) {
  574. return;
  575. }
  576. }
  577. LastSendTime = time;
  578. //WWDEBUG_SAY(("NumPackets = %d\n", NumPackets));
  579. /*
  580. ** Clear the array that indicates whether a packet is ready to be sent.
  581. */
  582. for (i=0 ; i<NumSendBuffers ; i++) {
  583. SendBuffers[i].PacketReady = false;
  584. }
  585. /*
  586. ** Loop until we process all packets.
  587. */
  588. while (NumPackets) {
  589. /*
  590. ** Get a packet to start with. Find the oldest packet first in each case.
  591. */
  592. index = NextPacket + 1;
  593. if (index >= NumSendBuffers) {
  594. index = 0;
  595. }
  596. base_index = -1;
  597. for (i=0 ; i<NumSendBuffers ; i++) {
  598. if (SendBuffers[index].PacketLength != 0) {
  599. base_index = index;
  600. length = SendBuffers[index].PacketLength;
  601. base_packet = (unsigned char *) SendBuffers[index].PacketBuffer;
  602. //WWDEBUG_SAY(("Found base packet %d\n", base_index));
  603. socket = SendBuffers[index].PacketSendSocket;
  604. header->NumPackets = 1;
  605. header->PacketSize = length;
  606. header->MorePackets = 0;
  607. pm_assert(header->NumPackets > 0 && header->NumPackets <= PACKET_MANAGER_MAX_PACKETS);
  608. next_packet_pos = BuildPacket + sizeof(*header);
  609. memcpy(next_packet_pos, base_packet, length);
  610. next_packet_pos += length;
  611. new_length = length + sizeof(*header);
  612. //WWDEBUG_SAY(("Added base packet %d to metapacket - %d (+2) bytes\n", index, length));
  613. index++;
  614. if (index >= NumSendBuffers) {
  615. index = 0;
  616. }
  617. break;
  618. }
  619. index++;
  620. if (index >= NumSendBuffers) {
  621. index = 0;
  622. }
  623. }
  624. /*
  625. ** If we found a packet, see if there are more packets of the same size that we can package up with it.
  626. */
  627. if (base_index != -1 && NumPackets > 1) {
  628. if ((new_length + length + sizeof(PacketDeltaHeaderStruct)) < PACKET_MANAGER_MTU) {
  629. for (int j=i ; j<NumSendBuffers ; j++) {
  630. /*
  631. ** If we can't fit any more packets in this packet then break out of the loop and send it as is.
  632. */
  633. if (header->NumPackets == PACKET_MANAGER_MAX_PACKETS) {
  634. break;
  635. }
  636. /*
  637. ** Is this packet the same length? If so, it might be suitable for coagulation.
  638. */
  639. if (SendBuffers[index].PacketLength == length && SendBuffers[index].PacketSendSocket == socket) {
  640. pm_assert(index != base_index);
  641. /*
  642. ** Is this packet for the same recipient?
  643. */
  644. if (SendBuffers[base_index].Port == SendBuffers[index].Port && (*(unsigned long*)(&SendBuffers[index].IPAddress[0])) == (*(unsigned long*)(&SendBuffers[base_index].IPAddress[0]))) {
  645. //WWDEBUG_SAY(("Found secondary packet %d\n", index));
  646. /*
  647. ** See if using a delta of the two packets would be smaller than including the whole packet.
  648. */
  649. int bytes = Build_Delta_Packet_Patch(base_packet, SendBuffers[index].PacketBuffer->Buffer, DeltaPacket, length, length);
  650. if (bytes < length && AllowDeltas) {
  651. /*
  652. ** Yes, the delta is smaller so use that.
  653. */
  654. memcpy(next_packet_pos, DeltaPacket, bytes);
  655. next_packet_pos += bytes;
  656. new_length += bytes;
  657. //WWDEBUG_SAY(("Added delta packet %d to metapacket - %d bytes\n", index, bytes));
  658. header->NumPackets++;
  659. pm_assert(header->NumPackets > 0 && header->NumPackets <= PACKET_MANAGER_MAX_PACKETS);
  660. } else {
  661. /*
  662. ** The delta was no better than the original. Stick a 0 byte in to say it's not a delta and then
  663. ** Copy the whole thing.
  664. */
  665. PacketDeltaHeaderStruct *delta_header = (PacketDeltaHeaderStruct*) next_packet_pos;
  666. delta_header->ChunkPack = 0;
  667. delta_header->BytePack = 0;
  668. next_packet_pos += sizeof(PacketDeltaHeaderStruct);
  669. new_length += sizeof(PacketDeltaHeaderStruct);
  670. memcpy(next_packet_pos, SendBuffers[index].PacketBuffer, length);
  671. next_packet_pos += length;
  672. new_length += length;
  673. //WWDEBUG_SAY(("Added secondary packet %d to metapacket - %d (+1) bytes\n", index, length));
  674. header->NumPackets++;
  675. pm_assert(header->NumPackets > 0 && header->NumPackets <= PACKET_MANAGER_MAX_PACKETS);
  676. }
  677. /*
  678. ** Discard the packet buffer now that we have added this packet to the current staging buffer area.
  679. */
  680. SendBuffers[index].PacketLength = 0;
  681. NumPackets--;
  682. //WWDEBUG_SAY(("NumPackets = %d (discarding secondary packet index %d)\n", NumPackets, index));
  683. pm_assert(header->NumPackets > 0 && header->NumPackets <= PACKET_MANAGER_MAX_PACKETS);
  684. /*
  685. ** If there's no room for any more of these packets then bail out.
  686. */
  687. if ((new_length + length + sizeof(PacketDeltaHeaderStruct)) >= PACKET_MANAGER_MTU) {
  688. break;
  689. }
  690. }
  691. }
  692. index++;
  693. if (index >= NumSendBuffers) {
  694. index = 0;
  695. }
  696. }
  697. }
  698. }
  699. pm_assert(header->NumPackets > 0 && header->NumPackets <= PACKET_MANAGER_MAX_PACKETS);
  700. /*
  701. ** Allright, it's time to send this sucker.
  702. */
  703. if (base_index != -1) {
  704. /*
  705. ** Just copy it back into the base index for now and mark it as ready to go.
  706. */
  707. memcpy(SendBuffers[base_index].PacketBuffer, BuildPacket, new_length);
  708. SendBuffers[base_index].PacketReady = true;
  709. SendBuffers[base_index].PacketSendLength = new_length;
  710. SendBuffers[base_index].PacketLength = 0;
  711. NumPackets--;
  712. //WWDEBUG_SAY(("NumPackets = %d (discarding base packet %d)\n", NumPackets, base_index));
  713. pm_assert(NumPackets >= 0);
  714. }
  715. pm_assert(header->NumPackets > 0 && header->NumPackets <= PACKET_MANAGER_MAX_PACKETS);
  716. }
  717. /*
  718. ** Merge ready buffers where possible. This is the step that adds runs of different sizeed packets into the same packet.
  719. */
  720. if (AllowCombos) {
  721. for (i=0 ; i<NumSendBuffers ; i++) {
  722. if (SendBuffers[i].PacketReady) {
  723. PacketPackHeaderStruct *current_header = (PacketPackHeaderStruct*) SendBuffers[i].PacketBuffer;
  724. int current_len = SendBuffers[i].PacketSendLength;
  725. socket = SendBuffers[i].PacketSendSocket;
  726. /*
  727. ** See if we can find another packet for the same destination that will fit into the same buffer.
  728. */
  729. #ifdef WWDEBUG
  730. int num_sub_packets = 1;
  731. #endif //WWDEBUG
  732. for (int j=i+1 ; j<NumSendBuffers ; j++) {
  733. if (SendBuffers[j].PacketReady && SendBuffers[j].PacketSendSocket == socket) {
  734. if (SendBuffers[i].PacketSendLength + SendBuffers[j].PacketSendLength < PACKET_MANAGER_MTU) {
  735. if (SendBuffers[i].Port == SendBuffers[j].Port && (*(unsigned long*)(&SendBuffers[i].IPAddress[0])) == (*(unsigned long*)(&SendBuffers[j].IPAddress[0]))) {
  736. unsigned char *dest_ptr = &SendBuffers[i].PacketBuffer->Buffer[current_len];
  737. memcpy(dest_ptr, SendBuffers[j].PacketBuffer, SendBuffers[j].PacketSendLength);
  738. current_header->MorePackets = 1;
  739. current_header = (PacketPackHeaderStruct*) dest_ptr;
  740. current_len += SendBuffers[j].PacketSendLength;
  741. SendBuffers[i].PacketSendLength = current_len;
  742. SendBuffers[j].PacketReady = false;
  743. #ifdef WWDEBUG
  744. num_sub_packets++;
  745. #endif //WWDEBUG
  746. //WWDEBUG_SAY(("Added packet %d with %d sub packets to packet %d\n", j, ((PacketPackHeaderStruct*)&PacketBuffers[j][0])->NumPackets, i));
  747. //WWDEBUG_SAY(("Packet %d has %d packets total\n", i, num_sub_packets));
  748. }
  749. }
  750. }
  751. }
  752. }
  753. }
  754. }
  755. /*
  756. ** Send any packets marked as ready.
  757. */
  758. for (i=0 ; i<NumSendBuffers ; i++) {
  759. if (SendBuffers[i].PacketReady) {
  760. sockaddr_in addr;
  761. addr.sin_family = AF_INET;
  762. addr.sin_port = SendBuffers[i].Port;
  763. memcpy (&addr.sin_addr.s_addr, &SendBuffers[i].IPAddress[0], 4);
  764. socket = SendBuffers[i].PacketSendSocket;
  765. #ifdef WWDEBUG
  766. int debug_num_packets = (int)(((PacketPackHeaderStruct*)SendBuffers[i].PacketBuffer)->NumPackets);
  767. int debug_packet_size = (int)(((PacketPackHeaderStruct*)SendBuffers[i].PacketBuffer)->PacketSize);
  768. pm_assert(debug_num_packets > 0);
  769. pm_assert(debug_packet_size < PACKET_MANAGER_MTU);
  770. pm_assert(SendBuffers[i].PacketSendLength < PACKET_MANAGER_MTU);
  771. //WWDEBUG_SAY(("Sending packet %d (%d bytes) to %s. Packet has %d packets of %d bytes each\n", i, PacketSendLength[i], Addr_As_String(&addr), debug_num_packets, debug_packet_size));
  772. #endif //WWDEBUG
  773. #ifdef WRAPPER_CRC
  774. unsigned long crc = CRC::Memory((unsigned char*)SendBuffers[i].PacketBuffer, SendBuffers[i].PacketSendLength);
  775. #if (1)
  776. /*
  777. ** Reverse byte order to prevent the demo from having the same CRC as the game.
  778. */
  779. _asm {
  780. push eax;
  781. mov eax,crc;
  782. bswap eax;
  783. mov crc,eax;
  784. pop eax;
  785. };
  786. #endif //(0)
  787. char *crc_and_buffer = (char*)_alloca(SendBuffers[i].PacketSendLength + sizeof(crc));
  788. *((unsigned long*) crc_and_buffer) = crc;
  789. memcpy(crc_and_buffer + sizeof(crc), (const char*)SendBuffers[i].PacketBuffer, SendBuffers[i].PacketSendLength);
  790. Register_Packet_Out(&SendBuffers[i].IPAddress[0], SendBuffers[i].Port, SendBuffers[i].PacketSendLength + UDP_HEADER_SIZE + sizeof(crc), 0);
  791. int result = sendto(socket, crc_and_buffer, SendBuffers[i].PacketSendLength + sizeof(crc), 0, (LPSOCKADDR) &addr, sizeof(SOCKADDR_IN));
  792. #else //WRAPPER_CRC
  793. Register_Packet_Out(&SendBuffers[i].IPAddress[0], SendBuffers[i].Port, SendBuffers[i].PacketSendLength + UDP_HEADER_SIZE, 0);
  794. int result = sendto(socket, (const char*)SendBuffers[i].PacketBuffer, SendBuffers[i].PacketSendLength, 0, (LPSOCKADDR) &addr, sizeof(SOCKADDR_IN));
  795. #endif //WRAPPER_CRC
  796. if (result == SOCKET_ERROR){
  797. if (WSAGetLastError() != WSAEWOULDBLOCK) {
  798. int error_code = 0;
  799. error_code = WSAGetLastError();// avoid release build compiler warning
  800. WWDEBUG_SAY(("PacketManagerClass - sendto returned error code %d - %s\n", error_code, cNetUtil::Winsock_Error_Text(error_code)));
  801. Clear_Socket_Error(socket);
  802. } else {
  803. /*
  804. ** No more room for outgoing packets. Unfortunately, this means we lose the lot.
  805. */
  806. WWDEBUG_SAY(("PacketManagerClass - sendto returned WSAEWOULDBLOCK\n"));
  807. Sleep(0);
  808. ErrorState = STATE_WS_BUFFERS_FULL;
  809. }
  810. }
  811. /*
  812. ** Send some random garbage to see if we crash.
  813. */
  814. //char garbage[640];
  815. //for (int i=0 ; i<540 ; i++) {
  816. // garbage[i] = rand();
  817. //}
  818. //sendto(socket, (const char*)garbage, 540, 0, (LPSOCKADDR) &addr, sizeof(SOCKADDR_IN));
  819. }
  820. }
  821. Update_Stats();
  822. }
  823. }
  824. /***********************************************************************************************
  825. * PacketManagerClass::Disable_Optimizations -- Disable all low level optimizations *
  826. * *
  827. * *
  828. * *
  829. * INPUT: Nothing *
  830. * *
  831. * OUTPUT: Nothing *
  832. * *
  833. * WARNINGS: None *
  834. * *
  835. * HISTORY: *
  836. * 9/26/2001 2:24PM TSS : Created *
  837. *=============================================================================================*/
  838. void PacketManagerClass::Disable_Optimizations(void)
  839. {
  840. FlushFrequency = 0;
  841. AllowDeltas = false;
  842. AllowCombos = false;
  843. }
  844. /***********************************************************************************************
  845. * PacketManagerClass::Break_Packet -- Break up in incoming packet into it's original packets *
  846. * *
  847. * *
  848. * *
  849. * INPUT: Nothing *
  850. * *
  851. * OUTPUT: Nothing *
  852. * *
  853. * WARNINGS: None *
  854. * *
  855. * HISTORY: *
  856. * 9/26/2001 2:25PM ST : Created *
  857. *=============================================================================================*/
  858. bool PacketManagerClass::Break_Packet(unsigned char *packet, int original_packet_size, unsigned char *ip_address, unsigned short port)
  859. {
  860. /*
  861. ** Dereference a pointer to the packet header.
  862. */
  863. PacketPackHeaderStruct *header = (PacketPackHeaderStruct*) packet;
  864. /*
  865. ** Pull out the number of packets and the size of each.
  866. */
  867. int num_packets = header->NumPackets;
  868. int packet_size = header->PacketSize;
  869. bool more_packets = header->MorePackets;
  870. if (num_packets < 1 || packet_size > PACKET_MANAGER_MTU) {
  871. WWDEBUG_SAY(("PacketManager - Packet decode error. num_packets = %d\n, packet_size = %d\n", num_packets, packet_size));
  872. return(false);
  873. }
  874. pm_assert(num_packets >= 1);
  875. pm_assert(packet_size <= PACKET_MANAGER_MTU);
  876. /*
  877. ** Get the first packet. This is needed as a reference for other delta packets.
  878. */
  879. unsigned char *packet_ptr = packet + sizeof(*header);
  880. memcpy(&ReceiveBuffers[NumReceivePackets].ReceiveHoldingBuffer[0], packet_ptr, packet_size);
  881. ReceiveBuffers[NumReceivePackets].ReceivePacketLength = packet_size;
  882. Register_Packet_In(ip_address, port, 0, packet_size + UDP_HEADER_SIZE);
  883. int delta_base_index = NumReceivePackets;
  884. memcpy(ReceiveIPAddress, ip_address, 4);
  885. ReceivePort = port;
  886. NumReceivePackets++;
  887. //WWDEBUG_SAY(("Extracted base packet from metapacket - %d bytes\n", packet_size));
  888. packet_ptr += packet_size;
  889. /*
  890. ** Get the rest of the packets.
  891. */
  892. for (int i=0 ; i<num_packets-1 ; i++) {
  893. PacketDeltaHeaderStruct * delta_header = (PacketDeltaHeaderStruct*) packet_ptr;
  894. /*
  895. ** If this is a delta packet then we need to reconstruct it before copying it into the buffer.
  896. */
  897. if (delta_header->ChunkPack || delta_header->BytePack) {
  898. int delta_size = 0;
  899. //#ifdef WWDEBUG
  900. int bytes =
  901. //#endif //WWDEBUG
  902. Reconstruct_From_Delta(&ReceiveBuffers[delta_base_index].ReceiveHoldingBuffer[0], &ReceiveBuffers[NumReceivePackets].ReceiveHoldingBuffer[0], (unsigned char *)delta_header, packet_size, delta_size);
  903. if (bytes != packet_size) {
  904. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Break_Packet -- bytes != packet_size\n"));
  905. return(false);
  906. }
  907. if (delta_size <= 0) {
  908. WWDEBUG_SAY(("*** WARNING: MALFORMED PACKET - PacketManagerClass::Break_Packet -- delta_size <= 0\n"));
  909. return(false);
  910. }
  911. pm_assert(bytes == packet_size);
  912. pm_assert(delta_size > 0);
  913. ReceiveBuffers[NumReceivePackets].ReceivePacketLength = packet_size;
  914. NumReceivePackets++;
  915. packet_ptr += delta_size;
  916. Register_Packet_In(ip_address, port, 0, packet_size + UDP_HEADER_SIZE);
  917. //WWDEBUG_SAY(("Extracted delta packet from metapacket - %d bytes (delta size = %d)\n", bytes, delta_size));
  918. } else {
  919. /*
  920. ** Not a delta, just copy the whole thing.
  921. */
  922. packet_ptr += sizeof(*delta_header);
  923. memcpy(&ReceiveBuffers[NumReceivePackets].ReceiveHoldingBuffer[0], packet_ptr, packet_size);
  924. ReceiveBuffers[NumReceivePackets].ReceivePacketLength = packet_size;
  925. packet_ptr += packet_size;
  926. NumReceivePackets++;
  927. Register_Packet_In(ip_address, port, 0, packet_size + UDP_HEADER_SIZE);
  928. //WWDEBUG_SAY(("Extracted secondary packet from metapacket - %d (+1) bytes\n", PacketLength));
  929. }
  930. if (NumReceivePackets >= PACKET_MANAGER_RECEIVE_BUFFERS) {
  931. break;
  932. }
  933. }
  934. int bytes_pulled_from_packet = packet_ptr - packet;
  935. /*
  936. ** More packets in this buffer?
  937. */
  938. if (more_packets && NumReceivePackets < PACKET_MANAGER_RECEIVE_BUFFERS) {
  939. if (!Break_Packet(packet_ptr, original_packet_size - bytes_pulled_from_packet, ip_address, port)) {
  940. return(false);
  941. }
  942. }
  943. //if (NumReceivePackets > 20) {
  944. // WWDEBUG_SAY(("Sub packet broken into %d packets\n", NumReceivePackets));
  945. //}
  946. return(true);
  947. }
  948. /***********************************************************************************************
  949. * PacketManagerClass::Clear_Socket_Error -- Clear an error condition on a socket *
  950. * *
  951. * *
  952. * *
  953. * INPUT: Socket *
  954. * *
  955. * OUTPUT: Nothing *
  956. * *
  957. * WARNINGS: None *
  958. * *
  959. * HISTORY: *
  960. * 10/17/2001 12:19PM ST : Created *
  961. *=============================================================================================*/
  962. void PacketManagerClass::Clear_Socket_Error(SOCKET socket)
  963. {
  964. unsigned long error_code;
  965. int length = 4;
  966. assert(socket != INVALID_SOCKET);
  967. if (socket != INVALID_SOCKET) {
  968. getsockopt (socket, SOL_SOCKET, SO_ERROR, (char*)&error_code, &length);
  969. WWDEBUG_SAY(("Per socket error is %d - %s\n", error_code, cNetUtil::Winsock_Error_Text(error_code)));
  970. }
  971. }
  972. /***********************************************************************************************
  973. * PacketManagerClass::Get_Packet -- Return the next incoming packet to the app *
  974. * *
  975. * *
  976. * *
  977. * INPUT: Socket to use *
  978. * Ptr to packet buffer *
  979. * Size of packet buffer *
  980. * (out) Ptr to ip_address *
  981. * (out) Port number *
  982. * *
  983. * OUTPUT: Size of packet (0 = no packet, -1 = fatal socket error) *
  984. * *
  985. * WARNINGS: None *
  986. * *
  987. * HISTORY: *
  988. * 9/26/2001 2:28PM ST : Created *
  989. *=============================================================================================*/
  990. int PacketManagerClass::Get_Packet(SOCKET socket, unsigned char *packet_buffer, int packet_buffer_size, unsigned char *ip_address, unsigned short &port)
  991. {
  992. {
  993. WWPROFILE("Pmgr Get");
  994. CriticalSectionClass::LockClass lock(CriticalSection);
  995. if (NumReceivePackets == 0) {
  996. int address_size = sizeof(sockaddr_in);
  997. sockaddr_in addr;
  998. memset(&addr, 0, sizeof(addr));
  999. pm_assert(packet_buffer_size >= PACKET_MANAGER_MTU);
  1000. int bytes;
  1001. int result = ioctlsocket(socket, FIONREAD, (unsigned long *)&bytes);
  1002. if (result == 0 && bytes != 0) {
  1003. bytes = recvfrom(socket, (char*)packet_buffer, packet_buffer_size, 0, (LPSOCKADDR) &addr, &address_size);
  1004. if (bytes > 0) {
  1005. #ifndef WRAPPER_CRC
  1006. Register_Packet_In((unsigned char*) &addr.sin_addr.s_addr, addr.sin_port, bytes + UDP_HEADER_SIZE, 0);
  1007. #endif //WRAPPER_CRC
  1008. #ifdef WRAPPER_CRC
  1009. unsigned long crc = CRC::Memory((unsigned char*)packet_buffer + 4, bytes - sizeof(crc));
  1010. #if (1)
  1011. /*
  1012. ** Reverse byte order to prevent the demo from having the same CRC as the game.
  1013. */
  1014. _asm {
  1015. push eax;
  1016. mov eax,crc;
  1017. bswap eax;
  1018. mov crc,eax;
  1019. pop eax;
  1020. };
  1021. #endif //(0)
  1022. if (crc != *((unsigned long*)packet_buffer)) {
  1023. WWDEBUG_SAY(("PMC::Get_Packet: Socket %d, received packet %d bytes long from %s\n", socket, bytes, Addr_As_String(&addr)));
  1024. WWDEBUG_SAY(("PMC::Get_Packet: *** PACKET WRAPPER CRC ERROR ***"));
  1025. NumReceivePackets = 0;
  1026. } else {
  1027. Register_Packet_In((unsigned char*) &addr.sin_addr.s_addr, addr.sin_port, bytes + UDP_HEADER_SIZE, 0);
  1028. bytes -= sizeof(crc);
  1029. memmove(packet_buffer, packet_buffer + sizeof(crc), bytes);
  1030. #endif //WRAPPER_CRC
  1031. //WWDEBUG_SAY(("PMC::Get_Packet: Socket %d, received packet %d bytes long from %s\n", socket, bytes, Addr_As_String(&addr)));
  1032. ReceiveSocket = socket;
  1033. //WWDEBUG_SAY(("Breaking packet %d bytes long from %s\n", bytes, Addr_As_String(&addr)));
  1034. bool broken = Break_Packet(packet_buffer, bytes, (unsigned char*) &addr.sin_addr.s_addr, addr.sin_port);
  1035. if (!broken) {
  1036. WWDEBUG_SAY(("Failed to break packet %d bytes long from %s\n", bytes, Addr_As_String(&addr)));
  1037. WWDEBUG_SAY(("Discarding %d suspect packets due to decode failure\n", NumReceivePackets));
  1038. NumReceivePackets = 0;
  1039. } else {
  1040. //WWDEBUG_SAY(("PMC::Get_Packet: Packet broken into %d packets\n", NumReceivePackets));
  1041. }
  1042. CurrentPacket = 0;
  1043. #ifdef WRAPPER_CRC
  1044. }
  1045. #endif //WRAPPER_CRC
  1046. } else {
  1047. if (bytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) {
  1048. int error_code = 0;
  1049. error_code = WSAGetLastError();// avoid release build compiler warning
  1050. WWDEBUG_SAY(("PacketManagerClass - recvfrom failed with error %d - %s\n", error_code, cNetUtil::Winsock_Error_Text(error_code)));
  1051. Clear_Socket_Error(socket);
  1052. if (error_code == WSAECONNRESET) {
  1053. WWDEBUG_SAY(("PacketManagerClass - WSAECONNRESET from address %s\n", Addr_As_String(&addr)));
  1054. memcpy(ip_address, &addr.sin_addr.s_addr, 4);
  1055. port = addr.sin_port;
  1056. return(-1);
  1057. }
  1058. } else {
  1059. WWDEBUG_SAY(("PacketManagerClass - recvfrom failed with error WSAEWOULDBLOCK\n", WSAGetLastError()));
  1060. }
  1061. }
  1062. }
  1063. }
  1064. if (CurrentPacket < NumReceivePackets && socket == ReceiveSocket) {
  1065. /*
  1066. ** Copy the current packet into the return buffer. We have to zero out the rest of the buffer or the CRC won't come out
  1067. ** right. Lordy. FIxed in CRC code now ST - 9/24/2001 3:36PM
  1068. */
  1069. int size = (int)ReceiveBuffers[CurrentPacket].ReceivePacketLength;
  1070. memcpy(packet_buffer, &ReceiveBuffers[CurrentPacket].ReceiveHoldingBuffer[0], min(size, packet_buffer_size));
  1071. //if (size < packet_buffer_size) {
  1072. // memset(packet_buffer + size, 0, packet_buffer_size - size);
  1073. //}
  1074. memcpy(ip_address, ReceiveIPAddress, 4);
  1075. port = ReceivePort;
  1076. CurrentPacket++;
  1077. if (CurrentPacket >= NumReceivePackets) {
  1078. CurrentPacket = 0;
  1079. NumReceivePackets = 0;
  1080. }
  1081. return(size);
  1082. }
  1083. return(0);
  1084. }
  1085. }
  1086. /***********************************************************************************************
  1087. * PacketManager::Reset_Stats -- Reset bandwidth stats *
  1088. * *
  1089. * *
  1090. * *
  1091. * INPUT: Nothing *
  1092. * *
  1093. * OUTPUT: Nothing *
  1094. * *
  1095. * WARNINGS: None *
  1096. * *
  1097. * HISTORY: *
  1098. * 10/9/2001 8:54AM ST : Created *
  1099. *=============================================================================================*/
  1100. void PacketManagerClass::Reset_Stats(void)
  1101. {
  1102. CriticalSectionClass::LockClass lock(CriticalSection);
  1103. WWDEBUG_SAY(("PacketManagerClass Resetting stats\n"));
  1104. BandwidthList.Delete_All();
  1105. LastStatsUpdate = TIMEGETTIME();
  1106. ResetStatsIn = true;
  1107. ResetStatsOut = true;
  1108. }
  1109. /***********************************************************************************************
  1110. * PacketManager::Get_Stats_Index -- Get stats struct index for ip/port pair *
  1111. * *
  1112. * *
  1113. * *
  1114. * INPUT: IP *
  1115. * Port *
  1116. * Can create - true if allowed to create an entry if one doesn't exist *
  1117. * *
  1118. * OUTPUT: Index of stats struct for this ip/port, -1 for not found *
  1119. * *
  1120. * WARNINGS: None *
  1121. * *
  1122. * HISTORY: *
  1123. * 10/9/2001 8:54AM ST : Created *
  1124. *=============================================================================================*/
  1125. int PacketManagerClass::Get_Stats_Index(unsigned long ip_address, unsigned short port, bool can_create)
  1126. {
  1127. /*
  1128. ** Find the stats struct entry for this ip/port.
  1129. */
  1130. for (int i=0 ; i<BandwidthList.Count() ; i++) {
  1131. if (ip_address == BandwidthList[i].IPAddress && port == BandwidthList[i].Port) {
  1132. return(i);
  1133. }
  1134. }
  1135. if (can_create) {
  1136. /*
  1137. ** No entry found - create a new one.
  1138. */
  1139. BandwidthStatsStruct stats;
  1140. stats.IPAddress = ip_address;
  1141. stats.Port = port;
  1142. stats.UncompressedBytesIn = 0;
  1143. stats.UncompressedBytesOut = 0;
  1144. stats.CompressedBytesIn = 0;
  1145. stats.CompressedBytesOut = 0;
  1146. stats.UncompressedBandwidthIn = 0;
  1147. stats.UncompressedBandwidthOut = 0;
  1148. stats.CompressedBandwidthIn = 0;
  1149. stats.CompressedBandwidthOut = 0;
  1150. BandwidthList.Add(stats);
  1151. return(BandwidthList.Count()-1);
  1152. }
  1153. return(-1);
  1154. }
  1155. /***********************************************************************************************
  1156. * PacketManager::Register_Packet_In -- Register an incoming packet for bandwidth stats *
  1157. * *
  1158. * *
  1159. * *
  1160. * INPUT: IP address packet came from *
  1161. * Port packet came from *
  1162. * Compressed size of packet (can be 0) *
  1163. * Uncompressed size of packet (can be 0) *
  1164. * *
  1165. * OUTPUT: Nothing *
  1166. * *
  1167. * WARNINGS: None *
  1168. * *
  1169. * HISTORY: *
  1170. * 10/9/2001 8:56AM ST : Created *
  1171. *=============================================================================================*/
  1172. void PacketManagerClass::Register_Packet_In(unsigned char *ip_address, unsigned short port, unsigned long compressed_size, unsigned long uncompressed_size)
  1173. {
  1174. static unsigned long _last_ip = 0;
  1175. static unsigned short _last_port = 0;
  1176. static int _last_stats = -1;
  1177. unsigned long long_ip = *((unsigned long*)ip_address);
  1178. if (ResetStatsIn) {
  1179. _last_ip = 0;
  1180. _last_port = 0;
  1181. _last_stats = -1;
  1182. ResetStatsIn = false;
  1183. }
  1184. if (_last_stats != -1 && _last_ip == long_ip && _last_port == port && BandwidthList.Count()) {
  1185. BandwidthList[_last_stats].UncompressedBytesIn += uncompressed_size;
  1186. BandwidthList[_last_stats].CompressedBytesIn += compressed_size;
  1187. } else {
  1188. int stats_index = Get_Stats_Index(long_ip, port);
  1189. assert(stats_index != -1);
  1190. if (stats_index != -1) {
  1191. BandwidthList[stats_index].UncompressedBytesIn += uncompressed_size;
  1192. BandwidthList[stats_index].CompressedBytesIn += compressed_size;
  1193. _last_stats = stats_index;
  1194. _last_ip = long_ip;
  1195. _last_port = port;
  1196. }
  1197. }
  1198. }
  1199. /***********************************************************************************************
  1200. * PacketManager::Register_Packet_Out -- Register an outgoing packet for bandwidth stats *
  1201. * *
  1202. * *
  1203. * *
  1204. * INPUT: IP address packet is going to *
  1205. * Port the packet is going to *
  1206. * Compressed size of packet (can be 0) *
  1207. * Uncompressed size of packet (can be 0) *
  1208. * *
  1209. * OUTPUT: Nothing *
  1210. * *
  1211. * WARNINGS: None *
  1212. * *
  1213. * HISTORY: *
  1214. * 10/9/2001 8:56AM ST : Created *
  1215. *=============================================================================================*/
  1216. void PacketManagerClass::Register_Packet_Out(unsigned char *ip_address, unsigned short port, unsigned long compressed_size, unsigned long uncompressed_size)
  1217. {
  1218. static unsigned long _last_ip = 0;
  1219. static unsigned short _last_port = 0;
  1220. static int _last_stats = -1;
  1221. unsigned long long_ip = *((unsigned long*)ip_address);
  1222. if (ResetStatsOut) {
  1223. _last_ip = 0;
  1224. _last_port = 0;
  1225. _last_stats = -1;
  1226. ResetStatsOut = false;
  1227. }
  1228. if (_last_stats != -1 && _last_ip == long_ip && _last_port == port && BandwidthList.Count()) {
  1229. BandwidthList[_last_stats].UncompressedBytesOut += uncompressed_size;
  1230. BandwidthList[_last_stats].CompressedBytesOut += compressed_size;
  1231. } else {
  1232. int stats_index = Get_Stats_Index(long_ip, port);
  1233. assert(stats_index != -1);
  1234. if (stats_index != -1) {
  1235. BandwidthList[stats_index].UncompressedBytesOut += uncompressed_size;
  1236. BandwidthList[stats_index].CompressedBytesOut += compressed_size;
  1237. _last_stats = stats_index;
  1238. _last_ip = long_ip;
  1239. _last_port = port;
  1240. }
  1241. }
  1242. }
  1243. /***********************************************************************************************
  1244. * PacketManagerClass::Update_Stats -- Periodically update the bandwidth stats *
  1245. * *
  1246. * *
  1247. * *
  1248. * INPUT: Nothing *
  1249. * *
  1250. * OUTPUT: Nothing *
  1251. * *
  1252. * WARNINGS: None *
  1253. * *
  1254. * HISTORY: *
  1255. * 10/9/2001 8:57AM ST : Created *
  1256. *=============================================================================================*/
  1257. void PacketManagerClass::Update_Stats(bool forced)
  1258. {
  1259. CriticalSectionClass::LockClass lock(CriticalSection);
  1260. unsigned long time = TIMEGETTIME();
  1261. /*
  1262. ** Handle timer resetting.
  1263. */
  1264. if (time < LastStatsUpdate) {
  1265. LastStatsUpdate = 0;
  1266. }
  1267. /*
  1268. ** Only update every 'n' seconds.
  1269. */
  1270. if (time - LastStatsUpdate > StatsFrequency || forced) {
  1271. LastStatsUpdate = time;
  1272. /*
  1273. ** Reset the bandwidth totals.
  1274. */
  1275. TotalCompressedBandwidthIn = 0;
  1276. TotalCompressedBandwidthOut = 0;
  1277. TotalUncompressedBandwidthIn = 0;
  1278. TotalUncompressedBandwidthOut = 0;
  1279. /*
  1280. ** Go through the entry for each ip/port and work out the averages.
  1281. */
  1282. for (int i=0 ; i<BandwidthList.Count() ; i++) {
  1283. BandwidthStatsStruct *stats = &BandwidthList[i];
  1284. if (stats->CompressedBytesOut) {
  1285. //stats->CompressedBandwidthOut = (stats->CompressedBytesOut * 8) / StatsFrequency;
  1286. stats->CompressedBandwidthOut = (int)((1000 * stats->CompressedBytesOut * 8) / (float) StatsFrequency);
  1287. stats->CompressedBytesOut = 0;
  1288. TotalCompressedBandwidthOut += stats->CompressedBandwidthOut;
  1289. }
  1290. if (stats->CompressedBytesIn) {
  1291. //stats->CompressedBandwidthIn = (stats->CompressedBytesIn * 8) / StatsFrequency;
  1292. stats->CompressedBandwidthIn = (int)((1000 * stats->CompressedBytesIn * 8) / (float) StatsFrequency);
  1293. stats->CompressedBytesIn = 0;
  1294. TotalCompressedBandwidthIn += stats->CompressedBandwidthIn;
  1295. }
  1296. if (stats->UncompressedBytesOut) {
  1297. //stats->UncompressedBandwidthOut = (stats->UncompressedBytesOut * 8) / StatsFrequency;
  1298. stats->UncompressedBandwidthOut = (int)((1000 * stats->UncompressedBytesOut * 8) / (float) StatsFrequency);
  1299. stats->UncompressedBytesOut = 0;
  1300. TotalUncompressedBandwidthOut += stats->UncompressedBandwidthOut;
  1301. }
  1302. if (stats->UncompressedBytesIn) {
  1303. //stats->UncompressedBandwidthIn = (stats->UncompressedBytesIn * 8) / StatsFrequency;
  1304. stats->UncompressedBandwidthIn = (int)((1000 * stats->UncompressedBytesIn * 8) / (float) StatsFrequency);
  1305. stats->UncompressedBytesIn = 0;
  1306. TotalUncompressedBandwidthIn += stats->UncompressedBandwidthIn;
  1307. }
  1308. }
  1309. /*
  1310. ** Just debug output.
  1311. */
  1312. //WWDEBUG_SAY(("TotalUncompressedBandwidthOut = %d bits per second\n", TotalUncompressedBandwidthOut));
  1313. //WWDEBUG_SAY(("TotalCompressedBandwidthOut = %d bits per second\n", TotalCompressedBandwidthOut));
  1314. //WWDEBUG_SAY(("TotalUncompressedBandwidthIn = %d bits per second\n", TotalUncompressedBandwidthIn));
  1315. //WWDEBUG_SAY(("TotalCompressedBandwidthIn = %d bits per second\n", TotalCompressedBandwidthIn));
  1316. //unsigned long comp_out = 100 - ((100 * TotalCompressedBandwidthOut) / TotalUncompressedBandwidthOut);
  1317. //unsigned long comp_in = 100 - ((100 * TotalCompressedBandwidthIn) / TotalUncompressedBandwidthIn);
  1318. //WWDEBUG_SAY(("Compression out = %d percent\n", comp_out));
  1319. //WWDEBUG_SAY(("Compression in = %d percent\n", comp_in));
  1320. }
  1321. }
  1322. /***********************************************************************************************
  1323. * PacketManager::Get_Total_Raw_Bandwidth_In -- Get total uncompressed bandwidth in *
  1324. * *
  1325. * *
  1326. * *
  1327. * INPUT: Nothing *
  1328. * *
  1329. * OUTPUT: Total bandwidth before compression, in bits per second *
  1330. * *
  1331. * WARNINGS: None *
  1332. * *
  1333. * HISTORY: *
  1334. * 10/9/2001 8:59AM ST : Created *
  1335. *=============================================================================================*/
  1336. unsigned long PacketManagerClass::Get_Total_Raw_Bandwidth_In(void)
  1337. {
  1338. return(TotalUncompressedBandwidthIn);
  1339. }
  1340. /***********************************************************************************************
  1341. * PacketManager::Get_Total_Raw_Bandwidth_Out -- Get total uncompressed bandwidth out *
  1342. * *
  1343. * *
  1344. * *
  1345. * INPUT: Nothing *
  1346. * *
  1347. * OUTPUT: Total bandwidth before compression, in bits per second *
  1348. * *
  1349. * WARNINGS: None *
  1350. * *
  1351. * HISTORY: *
  1352. * 10/9/2001 8:59AM ST : Created *
  1353. *=============================================================================================*/
  1354. unsigned long PacketManagerClass::Get_Total_Raw_Bandwidth_Out(void)
  1355. {
  1356. return(TotalUncompressedBandwidthOut);
  1357. }
  1358. /***********************************************************************************************
  1359. * PacketManager::Get_Total_Compressed_Bandwidth_In -- Get total compressed bandwidth in *
  1360. * *
  1361. * *
  1362. * *
  1363. * INPUT: Nothing *
  1364. * *
  1365. * OUTPUT: Total bandwidth after compression, in bits per second *
  1366. * *
  1367. * WARNINGS: None *
  1368. * *
  1369. * HISTORY: *
  1370. * 10/9/2001 8:59AM ST : Created *
  1371. *=============================================================================================*/
  1372. unsigned long PacketManagerClass::Get_Total_Compressed_Bandwidth_In(void)
  1373. {
  1374. return(TotalCompressedBandwidthIn);
  1375. }
  1376. /***********************************************************************************************
  1377. * PacketManager::Get_Total_Compressed_Bandwidth_Out -- Get total compressed bandwidth out *
  1378. * *
  1379. * *
  1380. * *
  1381. * INPUT: Nothing *
  1382. * *
  1383. * OUTPUT: Total bandwidth after compression, in bits per second *
  1384. * *
  1385. * WARNINGS: None *
  1386. * *
  1387. * HISTORY: *
  1388. * 10/9/2001 8:59AM ST : Created *
  1389. *=============================================================================================*/
  1390. unsigned long PacketManagerClass::Get_Total_Compressed_Bandwidth_Out(void)
  1391. {
  1392. return(TotalCompressedBandwidthOut);
  1393. }
  1394. /***********************************************************************************************
  1395. * PacketManager::Get_Raw_Bandwidth_In -- Get uncompressed bandwidth in from given address *
  1396. * *
  1397. * *
  1398. * *
  1399. * INPUT: Address *
  1400. * *
  1401. * OUTPUT: Uncompressed bandwidth from address, in bits per second *
  1402. * *
  1403. * WARNINGS: None *
  1404. * *
  1405. * HISTORY: *
  1406. * 10/9/2001 9:01AM ST : Created *
  1407. *=============================================================================================*/
  1408. unsigned long PacketManagerClass::Get_Raw_Bandwidth_In(SOCKADDR_IN *address)
  1409. {
  1410. CriticalSectionClass::LockClass lock(CriticalSection);
  1411. unsigned long ip = *((unsigned long*)&address->sin_addr.s_addr);
  1412. unsigned short port = address->sin_port;
  1413. int stats = Get_Stats_Index(ip, port, false);
  1414. unsigned long bw = 0;
  1415. if (stats != -1) {
  1416. bw = BandwidthList[stats].UncompressedBandwidthIn;
  1417. }
  1418. return(bw);
  1419. }
  1420. /***********************************************************************************************
  1421. * PacketManager::Get_Raw_Bandwidth_Out -- Get uncompressed bandwidth to given address *
  1422. * *
  1423. * *
  1424. * *
  1425. * INPUT: Address *
  1426. * *
  1427. * OUTPUT: Uncompressed bandwidth to address, in bits per second *
  1428. * *
  1429. * WARNINGS: None *
  1430. * *
  1431. * HISTORY: *
  1432. * 10/9/2001 9:01AM ST : Created *
  1433. *=============================================================================================*/
  1434. unsigned long PacketManagerClass::Get_Raw_Bandwidth_Out(SOCKADDR_IN *address)
  1435. {
  1436. CriticalSectionClass::LockClass lock(CriticalSection);
  1437. unsigned long ip = *((unsigned long*)&address->sin_addr.s_addr);
  1438. unsigned short port = address->sin_port;
  1439. int stats = Get_Stats_Index(ip, port, false);
  1440. unsigned long bw = 0;
  1441. if (stats != -1) {
  1442. bw = BandwidthList[stats].UncompressedBandwidthOut;
  1443. }
  1444. return(bw);
  1445. }
  1446. /***********************************************************************************************
  1447. * PacketManager::Get_Raw_Bytes_Out -- Get uncompressed bytes to given address *
  1448. * *
  1449. * *
  1450. * *
  1451. * INPUT: Address *
  1452. * *
  1453. * OUTPUT: Uncompressed bytes sent to address. *
  1454. * *
  1455. * WARNINGS: None *
  1456. * *
  1457. * HISTORY: *
  1458. * 10/9/2001 9:01AM ST : Created *
  1459. *=============================================================================================*/
  1460. unsigned long PacketManagerClass::Get_Raw_Bytes_Out(SOCKADDR_IN *address)
  1461. {
  1462. CriticalSectionClass::LockClass lock(CriticalSection);
  1463. unsigned long ip = *((unsigned long*)&address->sin_addr.s_addr);
  1464. unsigned short port = address->sin_port;
  1465. int stats = Get_Stats_Index(ip, port, false);
  1466. unsigned long bytes = 0;
  1467. if (stats != -1) {
  1468. bytes = BandwidthList[stats].UncompressedBytesOut;
  1469. }
  1470. return(bytes);
  1471. }
  1472. /***********************************************************************************************
  1473. * PacketManager::Get_Compressed_Bandwidth_In -- Get compressed bandwidth in from address *
  1474. * *
  1475. * *
  1476. * *
  1477. * INPUT: Address *
  1478. * *
  1479. * OUTPUT: Compressed bandwidth in from address, in bits per second *
  1480. * *
  1481. * WARNINGS: None *
  1482. * *
  1483. * HISTORY: *
  1484. * 10/9/2001 9:01AM ST : Created *
  1485. *=============================================================================================*/
  1486. unsigned long PacketManagerClass::Get_Compressed_Bandwidth_In(SOCKADDR_IN *address)
  1487. {
  1488. CriticalSectionClass::LockClass lock(CriticalSection);
  1489. unsigned long ip = *((unsigned long*)&address->sin_addr.s_addr);
  1490. unsigned short port = address->sin_port;
  1491. int stats = Get_Stats_Index(ip, port, false);
  1492. unsigned long bw = 0;
  1493. if (stats != -1) {
  1494. bw = BandwidthList[stats].CompressedBandwidthIn;
  1495. }
  1496. return(bw);
  1497. }
  1498. /***********************************************************************************************
  1499. * PacketManager::Get_Compressed_Bandwidth_Out -- Get compressed bandwidth to address *
  1500. * *
  1501. * *
  1502. * *
  1503. * INPUT: Address *
  1504. * *
  1505. * OUTPUT: Compressed bandwidth to address, in bits per second *
  1506. * *
  1507. * WARNINGS: None *
  1508. * *
  1509. * HISTORY: *
  1510. * 10/9/2001 9:01AM ST : Created *
  1511. *=============================================================================================*/
  1512. unsigned long PacketManagerClass::Get_Compressed_Bandwidth_Out(SOCKADDR_IN *address)
  1513. {
  1514. CriticalSectionClass::LockClass lock(CriticalSection);
  1515. unsigned long ip = *((unsigned long*)&address->sin_addr.s_addr);
  1516. unsigned short port = address->sin_port;
  1517. int stats = Get_Stats_Index(ip, port, false);
  1518. unsigned long bw = 0;
  1519. if (stats != -1) {
  1520. bw = BandwidthList[stats].CompressedBandwidthOut;
  1521. }
  1522. return(bw);
  1523. }
  1524. /***********************************************************************************************
  1525. * PacketManagerClass::Set_Stats_Sampling_Frequency -- Set sample freq for stats *
  1526. * *
  1527. * *
  1528. * *
  1529. * INPUT: New frequency (delay in ms) *
  1530. * *
  1531. * OUTPUT: Nothing *
  1532. * *
  1533. * WARNINGS: None *
  1534. * *
  1535. * HISTORY: *
  1536. * 10/9/2001 9:58AM ST : Created *
  1537. *=============================================================================================*/
  1538. void PacketManagerClass::Set_Stats_Sampling_Frequency_Delay(unsigned long time_ms)
  1539. {
  1540. assert(time_ms > 0);
  1541. StatsFrequency = time_ms;
  1542. Reset_Stats();
  1543. }
  1544. /***********************************************************************************************
  1545. * PacketManagerClass::Get_Error_State -- Report and clear winsock error state *
  1546. * *
  1547. * *
  1548. * *
  1549. * INPUT: Nothing *
  1550. * *
  1551. * OUTPUT: Class error state *
  1552. * *
  1553. * WARNINGS: None *
  1554. * *
  1555. * HISTORY: *
  1556. * 10/24/2001 1:53PM ST : Created *
  1557. *=============================================================================================*/
  1558. PacketManagerClass::ErrorStateEnum PacketManagerClass::Get_Error_State(void)
  1559. {
  1560. ErrorStateEnum state = ErrorState;
  1561. ErrorState = STATE_OK;
  1562. return(state);
  1563. }
  1564. /*
  1565. ** Operators required to allow us to add BandwidthStateStruct to a dynamic vector.
  1566. */
  1567. bool PacketManagerClass::BandwidthStatsStruct::operator == (BandwidthStatsStruct const &stats) {
  1568. return((memcmp(this, &stats, sizeof(*this)) == 0) ? true : false);
  1569. }
  1570. bool PacketManagerClass::BandwidthStatsStruct::operator != (BandwidthStatsStruct const &stats) {
  1571. return((memcmp(this, &stats, sizeof(*this)) == 0) ? false : true);
  1572. }