bandwidthcheck.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  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/Commando/bandwidthcheck.cpp $*
  25. * *
  26. * $Author:: Bhayes $*
  27. * *
  28. * $Modtime:: 3/06/02 11:48a $*
  29. * *
  30. * $Revision:: 25 $*
  31. * *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * *
  35. * *
  36. *---------------------------------------------------------------------------------------------*
  37. * *
  38. * Functions: *
  39. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  40. /*
  41. ** Disable warning about exception handling not being enabled.
  42. */
  43. #pragma warning(disable : 4530)
  44. #include "always.h"
  45. #include <windows.h>
  46. #include "systimer.h"
  47. #include <stddef.h>
  48. #include "bandwidthcheck.h"
  49. #include "autostart.h"
  50. #include "registry.h"
  51. #include "_globals.h"
  52. #include "useroptions.h"
  53. #include "translatedb.h"
  54. #include "string_ids.h"
  55. #include "consolemode.h"
  56. #include "specialbuilds.h"
  57. #include "gamespyadmin.h"
  58. #include <WWOnline\WOLSession.h>
  59. /*
  60. ** Class statics.
  61. */
  62. BandwidthCheckerClass::BandwidthCheckerThreadClass BandwidthCheckerClass::Thread;
  63. HANDLE BandwidthCheckerClass::EventNotify = NULL;
  64. unsigned long BandwidthCheckerClass::UpstreamBandwidth = 0;
  65. unsigned long BandwidthCheckerClass::ReportedUpstreamBandwidth = 0;
  66. unsigned short *BandwidthCheckerClass::UpstreamBandwidthString = NULL;
  67. unsigned long BandwidthCheckerClass::DownstreamBandwidth = 0;
  68. unsigned long BandwidthCheckerClass::ReportedDownstreamBandwidth = 0;
  69. unsigned short *BandwidthCheckerClass::DownstreamBandwidthString = NULL;
  70. int BandwidthCheckerClass::FailureCode = BANDTEST_OK;
  71. bool BandwidthCheckerClass::GotBandwidth = false;
  72. const char *BandwidthCheckerClass::DefaultServerName = "www.westwood.com";
  73. /*
  74. ** Possible error codes from the bandwidth test.
  75. */
  76. char *BandwidthCheckerClass::ErrorList[13] = {
  77. "BANDTEST_OK",
  78. "BANDTEST_NO_WINSOCK2",
  79. "BANDTEST_NO_RAW_SOCKET_PERMISSION",
  80. "BANDTEST_NO_RAW_SOCKET_CREATE",
  81. "BANDTEST_NO_UDP_SOCKET_BIND",
  82. "BANDTEST_NO_TTL_SET",
  83. "BANDTEST_NO_PING_RESPONSE",
  84. "BANDTEST_NO_FINAL_PING_TIME",
  85. "BANDTEST_NO_EXTERNAL_ROUTER",
  86. "BANDTEST_NO_IP_DETECT",
  87. "BANDTEST_UNKNOWN_ERROR",
  88. "BANDTEST_WRONG_API_VERSION",
  89. "BANDTEST_BAD_PARAM"
  90. };
  91. #define NUM_BANDS 12
  92. #ifdef FREEDEDICATEDSERVER
  93. #define DEFAULT_BAND 9
  94. #else //FREEDEDICATEDSERVER
  95. #define DEFAULT_BAND 3
  96. #endif //FREEDEDICATEDSERVER
  97. /*
  98. ** Lower and upper limits for each level of bandwidth.
  99. */
  100. unsigned long BandwidthCheckerClass::Bandwidths[NUM_BANDS * 2] = {
  101. 12000, 14400,
  102. 28000, 28800,
  103. 29999, 33600,
  104. 53000, 57600,
  105. 62000, 67200,
  106. 105000, 115200,
  107. 125000, 128000,
  108. 250000, 256000,
  109. 500000, 512000,
  110. 999999, 1024000,
  111. 1999999, 2048000,
  112. 3999999, 4096000
  113. };
  114. /*
  115. ** Human readable names for each bandwidth level.
  116. */
  117. unsigned short *BandwidthCheckerClass::BandwidthNames [NUM_BANDS+1] = {
  118. L"14400",
  119. L"28800",
  120. L"33600",
  121. L"57600",
  122. L"67200",
  123. L"115200",
  124. L"128k",
  125. L"256k",
  126. L"512k",
  127. L"1M",
  128. L"2M",
  129. L"4M",
  130. L"> 4M"
  131. };
  132. /***********************************************************************************************
  133. * BandwidthCheckerClass::Detect -- Create the bandwidth detect wait object *
  134. * *
  135. * *
  136. * *
  137. * INPUT: Nothing *
  138. * *
  139. * OUTPUT: Nothing *
  140. * *
  141. * WARNINGS: None *
  142. * *
  143. * HISTORY: *
  144. * 11/21/2001 2:53PM ST : Created *
  145. *=============================================================================================*/
  146. RefPtr<WaitCondition> BandwidthCheckerClass::Detect(void)
  147. {
  148. return(BandwidthDetectWait::Create());
  149. }
  150. /***********************************************************************************************
  151. * Start the bandwidth detection thread *
  152. * *
  153. * *
  154. * *
  155. * INPUT: Nothing *
  156. * *
  157. * OUTPUT: Nothing *
  158. * *
  159. * WARNINGS: None *
  160. * *
  161. * HISTORY: *
  162. * 11/21/2001 2:53PM ST : Created *
  163. *=============================================================================================*/
  164. void BandwidthCheckerClass::Check_Now(HANDLE event)
  165. {
  166. EventNotify = event;
  167. /*
  168. ** If the thread didn't finish for some reason then we need to take action.
  169. ** This will stall the dialogs but at least it won't crash.
  170. */
  171. if (Thread.Is_Running()) {
  172. unsigned long timeout = 10 * 1000;
  173. unsigned long time = TIMEGETTIME();
  174. while (Thread.Is_Running() && (TIMEGETTIME() - time) < timeout) {
  175. Sleep(1);
  176. }
  177. }
  178. if (Thread.Is_Running()) {
  179. Thread.Stop(2000);
  180. }
  181. WWASSERT(!Thread.Is_Running());
  182. Thread.Execute();
  183. }
  184. /***********************************************************************************************
  185. * BandwidthCheckerClass::Get_Ping_Server_Name -- Get the name of a server to ping *
  186. * *
  187. * *
  188. * *
  189. * INPUT: Nothing *
  190. * *
  191. * OUTPUT: Ptr to server name *
  192. * *
  193. * WARNINGS: None *
  194. * *
  195. * HISTORY: *
  196. * 11/27/2001 1:17PM ST : Created *
  197. *=============================================================================================*/
  198. const char *BandwidthCheckerClass::Get_Ping_Server_Name(void)
  199. {
  200. static char server_name_copy[128];
  201. DynamicVectorClass<StringClass> list;
  202. const char *server_name = DefaultServerName;
  203. /*
  204. ** See if there are ping servers in the registry from a previous run.
  205. */
  206. RegistryClass reg(APPLICATION_SUB_KEY_NAME_SERVER_LIST);
  207. WWASSERT(list.Count() == 0);
  208. reg.Get_Value_List(list);
  209. if (list.Count() > 0) {
  210. /*
  211. ** Get average and lowest ping server ping time.
  212. */
  213. int num_times = 0;
  214. unsigned long total = 0;
  215. int lowest = 0xffff;
  216. int lowest_index = -1;
  217. for (int i=0 ; i<list.Count() ; i++) {
  218. int time = reg.Get_Int(list[i].Peek_Buffer(), 0);
  219. if (time > 0 && time < 0xffff) {
  220. total += (unsigned long) time;
  221. num_times++;
  222. if (time < lowest) {
  223. lowest = time;
  224. lowest_index = i;
  225. }
  226. }
  227. }
  228. if (num_times) {
  229. int average_time = (int) (total / (unsigned) num_times);
  230. /*
  231. ** Pick one a little closer.
  232. */
  233. average_time = average_time / 2;
  234. /*
  235. ** Find the server closest to the average time.
  236. */
  237. int closest_index = -1;
  238. int closest_diff = 0x7fffffff;
  239. for (i=0 ; i<list.Count() ; i++) {
  240. int time = reg.Get_Int(list[i].Peek_Buffer(), 0);
  241. if (time > 0 && time < 0xffff) {
  242. int diff = abs(time - average_time);
  243. if (diff < closest_diff) {
  244. /*
  245. ** Ignore the nearest server.
  246. */
  247. if (i != lowest_index) {
  248. closest_diff = diff;
  249. closest_index = i;
  250. }
  251. }
  252. }
  253. }
  254. if (closest_index != -1) {
  255. WWASSERT(closest_index >= 0);
  256. WWASSERT(closest_index < list.Count());
  257. strncpy(server_name_copy, list[closest_index].Peek_Buffer(), sizeof(server_name_copy));
  258. server_name_copy[sizeof(server_name_copy) - 1] = 0;
  259. server_name = (const char*) server_name_copy;
  260. }
  261. }
  262. }
  263. return(server_name);
  264. }
  265. /***********************************************************************************************
  266. * BandwidthCheckerClass::Check -- Check bandwidth. This is called from bandwidth thread. *
  267. * *
  268. * *
  269. * *
  270. * INPUT: Nothing *
  271. * *
  272. * OUTPUT: Nothing *
  273. * *
  274. * WARNINGS: None *
  275. * *
  276. * HISTORY: *
  277. * 11/21/2001 2:54PM ST : Created *
  278. *=============================================================================================*/
  279. void BandwidthCheckerClass::Check(void)
  280. {
  281. struct hostent *host;
  282. struct sockaddr_in address;
  283. int failure_code;
  284. /*
  285. ** If we are auto starting then just use the previous settings from the registry.
  286. */
  287. if (AutoRestart.Is_Active()) {
  288. RegistryClass reg(APPLICATION_SUB_KEY_NAME_BANDTEST);
  289. int up = reg.Get_Int("Up", 0);
  290. int down = reg.Get_Int("Down", up);
  291. UpstreamBandwidth = up;
  292. DownstreamBandwidth = down;
  293. if (up) {
  294. GotBandwidth = true;
  295. SetEvent(EventNotify);
  296. return;
  297. }
  298. }
  299. ConsoleBox.Print("Detecting bandwidth...\n");
  300. const char *host_name = NULL;
  301. if (cGameSpyAdmin::Is_Gamespy_Game()) {
  302. // US West Ping server
  303. host_name = "159.153.192.10";
  304. } else {
  305. host_name = Get_Ping_Server_Name();
  306. }
  307. WWDEBUG_SAY(("BandwidthCheckerClass::Check -- Trying server %s\n", host_name));
  308. host = gethostbyname(host_name);
  309. if (host == NULL) {
  310. host_name = DefaultServerName;
  311. WWDEBUG_SAY(("BandwidthCheckerClass::Check -- Trying server %s\n", host_name));
  312. host = gethostbyname(host_name);
  313. }
  314. if (host == NULL) {
  315. /*
  316. ** No DNS or no connection at all. Either way we are in trouble.
  317. */
  318. WWDEBUG_SAY(("BandwidthCheckerClass - Unable to resolve host name\n"));
  319. ConsoleBox.Print("Unable to resolve host name for bandwidth check\n");
  320. #ifdef FREEDEDICATEDSERVER
  321. UpstreamBandwidth = 1000000;
  322. DownstreamBandwidth = 1000000;
  323. ReportedUpstreamBandwidth = 1000000;
  324. ReportedDownstreamBandwidth = 1000000;
  325. #else //FREEDEDICATEDSERVER
  326. UpstreamBandwidth = 55000;
  327. DownstreamBandwidth = 55000;
  328. ReportedUpstreamBandwidth = 57600;
  329. ReportedDownstreamBandwidth = 57600;
  330. #endif //FREEDEDICATEDSERVER
  331. UpstreamBandwidthString = BandwidthNames[DEFAULT_BAND];
  332. DownstreamBandwidthString = BandwidthNames[DEFAULT_BAND];
  333. FailureCode = BANDTEST_NO_IP_DETECT;
  334. GotBandwidth = false;
  335. } else {
  336. memcpy(&(address.sin_addr), host->h_addr, host->h_length);
  337. /*
  338. ** Init the settings for the detection.
  339. */
  340. BandtestSettingsStruct settings = {
  341. 0, //AlwaysICMP
  342. 0, //TTLScatter
  343. 50, //FastPingPackets
  344. 12, //SlowPingPackets
  345. 25, //Fast ping threshold
  346. 0 //PingProfile
  347. };
  348. /*
  349. ** Call the .dll function to do the actual detection.
  350. */
  351. UpstreamBandwidth = Detect_Bandwidth(ntohl(address.sin_addr.s_addr), 0, 2, failure_code, DownstreamBandwidth, BANDTEST_API_VERSION, &settings, APPLICATION_SUB_KEY_NAME_BANDTEST);
  352. /*
  353. ** If we failed due to a missing final ping then try again with fewer packets and no retries.
  354. */
  355. if (UpstreamBandwidth == 0) {
  356. if (failure_code == BANDTEST_NO_FINAL_PING_TIME ||
  357. (cGameSpyAdmin::Is_Gamespy_Game() &&
  358. failure_code == BANDTEST_NO_EXTERNAL_ROUTER)) {
  359. BandtestSettingsStruct settings = {
  360. 0, //AlwaysICMP
  361. 0, //TTLScatter
  362. 25, //FastPingPackets
  363. 8, //SlowPingPackets
  364. 25, //Fast ping threshold
  365. 0 //PingProfile
  366. };
  367. if (cGameSpyAdmin::Is_Gamespy_Game()) {
  368. // US East Ping server
  369. address.sin_addr.s_addr = inet_addr("159.153.224.10");
  370. }
  371. UpstreamBandwidth = Detect_Bandwidth(ntohl(address.sin_addr.s_addr), 0, 0, failure_code, DownstreamBandwidth, BANDTEST_API_VERSION, &settings);
  372. }
  373. }
  374. /*
  375. ** If it's 0, we failed.
  376. */
  377. if (UpstreamBandwidth == 0) {
  378. WWDEBUG_SAY(("Failed to get bandwidth - error code %s\n", ErrorList[failure_code]));
  379. /*
  380. ** Default to 57600.
  381. */
  382. #ifdef FREEDEDICATEDSERVER
  383. ConsoleBox.Print("Failed to get bandwidth - error code %s, Setting 1Mbps bandwidth\n", ErrorList[failure_code]);
  384. UpstreamBandwidth = 1000000;
  385. DownstreamBandwidth = 1000000;
  386. #else //FREEDEDICATEDSERVER
  387. if (cGameSpyAdmin::Is_Gamespy_Game()) {
  388. UpstreamBandwidth = 128000;
  389. DownstreamBandwidth = 128000;
  390. } else {
  391. UpstreamBandwidth = 55000;
  392. DownstreamBandwidth = 55000;
  393. }
  394. #endif //FREEDEDICATEDSERVER
  395. FailureCode = failure_code;
  396. GotBandwidth = true; //false;
  397. } else {
  398. GotBandwidth = true;
  399. }
  400. /*
  401. ** Fix up the upstream bandwidth into one of our connection type bands.
  402. */
  403. if (UpstreamBandwidth > 0x7fffffff) {
  404. WWDEBUG_SAY(("Upstream bandwidth is huge :-)\n"));
  405. WWDEBUG_SAY(("Reported upstream connection bandwidth is > 4M bits per second\n"));
  406. UpstreamBandwidth = 4096000;
  407. ReportedUpstreamBandwidth = 4096000;
  408. UpstreamBandwidthString = BandwidthNames[NUM_BANDS];
  409. } else {
  410. if (UpstreamBandwidth > 100000) {
  411. #ifdef WWDEBUG
  412. float floater = (float)UpstreamBandwidth / 1024;
  413. #endif //WWDEBUG
  414. WWDEBUG_SAY(("Upstream bandwidth to external router is %.1f kilobits per second\n", floater));
  415. } else {
  416. WWDEBUG_SAY(("Upstream bandwidth to external router is %d bits per second\n", UpstreamBandwidth));
  417. }
  418. bool got_bw_str = false;
  419. for (int i=0 ; i<NUM_BANDS ; i++) {
  420. if (UpstreamBandwidth < Bandwidths[(i*2) + 1]) {
  421. //WWDEBUG_SAY(("\nReported upstream connection bandwidth is %s bits per second\n", BandwidthNames[i]));
  422. UpstreamBandwidthString = BandwidthNames[i];
  423. ReportedUpstreamBandwidth = Bandwidths[(i*2)+1];
  424. got_bw_str = true;
  425. break;
  426. }
  427. }
  428. if (!got_bw_str) {
  429. WWDEBUG_SAY(("\nReported upstream connection bandwidth is > 4M bits per second\n"));
  430. ReportedUpstreamBandwidth = 4096000;
  431. UpstreamBandwidthString = BandwidthNames[NUM_BANDS];
  432. }
  433. StringClass little_string;
  434. WideStringClass(UpstreamBandwidthString, true).Convert_To(little_string);
  435. ConsoleBox.Print("Upstream bandwidth of %s bps detected\n", little_string.Peek_Buffer());
  436. }
  437. /*
  438. ** Fix up the downstream bandwidth into one of our connection type bands.
  439. */
  440. if (DownstreamBandwidth > 0x7fffffff) {
  441. WWDEBUG_SAY(("Downstream bandwidth is huge :-)\n"));
  442. WWDEBUG_SAY(("Reported downstream connection bandwidth is > 4M bits per second\n"));
  443. DownstreamBandwidth = 4096000;
  444. ReportedDownstreamBandwidth = 4096000;
  445. DownstreamBandwidthString = BandwidthNames[NUM_BANDS];
  446. } else {
  447. if (DownstreamBandwidth > 100000) {
  448. #ifdef WWDEBUG
  449. float floater = (float)DownstreamBandwidth / 1024;
  450. #endif //WWDEBUG
  451. WWDEBUG_SAY(("Downstream bandwidth to external router is %.1f kilobits per second\n", floater));
  452. } else {
  453. WWDEBUG_SAY(("Downstream bandwidth to external router is %d bits per second\n", DownstreamBandwidth));
  454. }
  455. bool got_bw_str = false;
  456. for (int i=0 ; i<NUM_BANDS ; i++) {
  457. if (DownstreamBandwidth < Bandwidths[(i*2) + 1]) {
  458. //WWDEBUG_SAY(("\nReported downstream connection bandwidth is %s bits per second\n", BandwidthNames[i]));
  459. DownstreamBandwidthString = BandwidthNames[i];
  460. ReportedDownstreamBandwidth = Bandwidths[(i*2)+1];
  461. got_bw_str = true;
  462. break;
  463. }
  464. }
  465. if (!got_bw_str) {
  466. WWDEBUG_SAY(("\nReported downstream connection bandwidth is > 4M bits per second\n"));
  467. ReportedDownstreamBandwidth = 4096000;
  468. DownstreamBandwidthString = BandwidthNames[NUM_BANDS];
  469. }
  470. }
  471. /*
  472. ** Testy.
  473. */
  474. #ifdef _DEBUG
  475. PackedBandwidthType packed = Get_Packed_Bandwidth();
  476. WWDEBUG_SAY(("Packed bandwidth as string = %s\n", Get_Bandwidth_As_String(packed)));
  477. #endif //_DEBUG
  478. }
  479. SetEvent(EventNotify);
  480. }
  481. /***********************************************************************************************
  482. * BandwidthCheckerClass::Force_Upstream_Bandwidth -- Set actual upstream bandwidth *
  483. * *
  484. * *
  485. * *
  486. * INPUT: Upstream bandwidth in buts per second *
  487. * *
  488. * OUTPUT: Nothing *
  489. * *
  490. * WARNINGS: None *
  491. * *
  492. * HISTORY: *
  493. * 11/21/2001 2:54PM ST : Created *
  494. *=============================================================================================*/
  495. void BandwidthCheckerClass::Force_Upstream_Bandwidth(unsigned int up)
  496. {
  497. WWASSERT(up);
  498. WWASSERT(cGameSpyAdmin::Is_Gamespy_Game());
  499. UpstreamBandwidth = up;
  500. }
  501. /***********************************************************************************************
  502. * BandwidthCheckerClass::Get_Upstream_Bandwidth -- Get actual upstream bandwidth *
  503. * *
  504. * *
  505. * *
  506. * INPUT: Nothing *
  507. * *
  508. * OUTPUT: Upstream bandwidth in buts per second *
  509. * *
  510. * WARNINGS: None *
  511. * *
  512. * HISTORY: *
  513. * 11/21/2001 2:54PM ST : Created *
  514. *=============================================================================================*/
  515. unsigned long BandwidthCheckerClass::Get_Upstream_Bandwidth(void)
  516. {
  517. return(UpstreamBandwidth);
  518. }
  519. /***********************************************************************************************
  520. * BandwidthCheckerClass::Get_Reported_Upstream_Bandwidth -- Get reported up bandwidth *
  521. * *
  522. * *
  523. * *
  524. * INPUT: Nothing *
  525. * *
  526. * OUTPUT: Reported upstream bandwidth in bits per second *
  527. * *
  528. * WARNINGS: None *
  529. * *
  530. * HISTORY: *
  531. * 11/21/2001 2:55PM ST : Created *
  532. *=============================================================================================*/
  533. unsigned long BandwidthCheckerClass::Get_Reported_Upstream_Bandwidth(void)
  534. {
  535. return(ReportedUpstreamBandwidth);
  536. }
  537. /***********************************************************************************************
  538. * BandwidthCheckerClass::Get_Upstream_Bandwidth_As_String -- Human readable upsream bw *
  539. * *
  540. * *
  541. * *
  542. * INPUT: Nothing *
  543. * *
  544. * OUTPUT: Ptr to bandwidth string *
  545. * *
  546. * WARNINGS: None *
  547. * *
  548. * HISTORY: *
  549. * 11/21/2001 2:56PM ST : Created *
  550. *=============================================================================================*/
  551. unsigned short *BandwidthCheckerClass::Get_Upstream_Bandwidth_As_String(void)
  552. {
  553. return(UpstreamBandwidthString);
  554. }
  555. /***********************************************************************************************
  556. * BandwidthCheckerClass::Get_Downstream_Bandwidth -- Get actual downstream bandwidth *
  557. * *
  558. * *
  559. * *
  560. * INPUT: Nothing *
  561. * *
  562. * OUTPUT: Actual down bw in bits per second *
  563. * *
  564. * WARNINGS: None *
  565. * *
  566. * HISTORY: *
  567. * 11/21/2001 2:56PM ST : Created *
  568. *=============================================================================================*/
  569. unsigned long BandwidthCheckerClass::Get_Downstream_Bandwidth(void)
  570. {
  571. return(DownstreamBandwidth);
  572. }
  573. /***********************************************************************************************
  574. * BandwidthCheckerClass::Get_Reported_Downstream_Bandwidth -- Get reported down bw *
  575. * *
  576. * *
  577. * *
  578. * INPUT: Nothing *
  579. * *
  580. * OUTPUT: Reported down bw in bits per second *
  581. * *
  582. * WARNINGS: None *
  583. * *
  584. * HISTORY: *
  585. * 11/21/2001 2:57PM ST : Created *
  586. *=============================================================================================*/
  587. unsigned long BandwidthCheckerClass::Get_Reported_Downstream_Bandwidth(void)
  588. {
  589. return(ReportedDownstreamBandwidth);
  590. }
  591. /***********************************************************************************************
  592. * BandwidthCheckerClass::Get_Downstream_Bandwidth_As_String -- Get down bw as a string *
  593. * *
  594. * *
  595. * *
  596. * INPUT: Nothing *
  597. * *
  598. * OUTPUT: Ptr to down bw string *
  599. * *
  600. * WARNINGS: None *
  601. * *
  602. * HISTORY: *
  603. * 11/21/2001 2:57PM ST : Created *
  604. *=============================================================================================*/
  605. unsigned short *BandwidthCheckerClass::Get_Downstream_Bandwidth_As_String(void)
  606. {
  607. return(DownstreamBandwidthString);
  608. }
  609. /***********************************************************************************************
  610. * BandwidthCheckerClass::Get_Bandwidth_As_String -- Get bandwidth description string *
  611. * *
  612. * *
  613. * *
  614. * INPUT: Nothing *
  615. * *
  616. * OUTPUT: Ptr to string *
  617. * *
  618. * WARNINGS: None *
  619. * *
  620. * HISTORY: *
  621. * 11/21/2001 2:58PM ST : Created *
  622. *=============================================================================================*/
  623. unsigned short *BandwidthCheckerClass::Get_Bandwidth_As_String(void)
  624. {
  625. if (cUserOptions::Get_Bandwidth_Type() == BANDWIDTH_AUTO) {
  626. static unsigned short _build_string[256];
  627. swprintf(_build_string, L"%s,%s", DownstreamBandwidthString, UpstreamBandwidthString);
  628. return(_build_string);
  629. } else {
  630. return((unsigned short*)cBandwidth::Get_Bandwidth_String_From_Type(
  631. (BANDWIDTH_TYPE_ENUM)cUserOptions::Get_Bandwidth_Type()));
  632. }
  633. }
  634. /***********************************************************************************************
  635. * BandwidthCheckerClass::Get_Bandwidth_As_String -- Get bandwidth description string *
  636. * *
  637. * *
  638. * *
  639. * INPUT: Packed up/down bandwidth *
  640. * *
  641. * OUTPUT: Ptr to bandwidth description string *
  642. * *
  643. * WARNINGS: None *
  644. * *
  645. * HISTORY: *
  646. * 11/21/2001 2:58PM ST : Created *
  647. *=============================================================================================*/
  648. unsigned short *BandwidthCheckerClass::Get_Bandwidth_As_String(PackedBandwidthType bandwidth)
  649. {
  650. static unsigned short _build_string[256];
  651. assert(bandwidth.Bandwidth.Up < NUM_BANDS + 1);
  652. assert(bandwidth.Bandwidth.Down < NUM_BANDS + 1);
  653. swprintf(_build_string, L"%s,%s", BandwidthNames[bandwidth.Bandwidth.Down], BandwidthNames[bandwidth.Bandwidth.Up]);
  654. return(_build_string);
  655. }
  656. /***********************************************************************************************
  657. * BandwidthCheckerClass::Get_Packed_Bandwidth -- Get bandwidth packed into a byte *
  658. * *
  659. * *
  660. * *
  661. * INPUT: Nothing *
  662. * *
  663. * OUTPUT: Bandwidth as a byte *
  664. * *
  665. * WARNINGS: None *
  666. * *
  667. * HISTORY: *
  668. * 11/21/2001 2:59PM ST : Created *
  669. *=============================================================================================*/
  670. BandwidthCheckerClass::PackedBandwidthType BandwidthCheckerClass::Get_Packed_Bandwidth(void)
  671. {
  672. PackedBandwidthType bandwidth = {0,0};
  673. assert(sizeof(bandwidth) == 1);
  674. unsigned long bwu = ReportedUpstreamBandwidth;
  675. unsigned long bwd = ReportedDownstreamBandwidth;
  676. bool automode = true;
  677. if (cUserOptions::Get_Bandwidth_Type() != BANDWIDTH_AUTO) {
  678. bwu = cBandwidth::Get_Bandwidth_Bps_From_Type((BANDWIDTH_TYPE_ENUM)cUserOptions::Get_Bandwidth_Type());
  679. bwd = bwu;
  680. automode = false;
  681. }
  682. /*
  683. ** Just return 0s if we haven't detected bandwidth yet.
  684. */
  685. if (!automode || UpstreamBandwidth != 0) {
  686. for (int i=0 ; i<NUM_BANDS+1 ; i++) {
  687. if (bwu <= Bandwidths[(i*2)+1]) {
  688. bandwidth.Bandwidth.Up = i;
  689. break;
  690. }
  691. }
  692. for (i=0 ; i<NUM_BANDS+1 ; i++) {
  693. if (bwd <= Bandwidths[(i*2)+1]) {
  694. bandwidth.Bandwidth.Down = i;
  695. break;
  696. }
  697. }
  698. }
  699. return(bandwidth);
  700. }
  701. /***********************************************************************************************
  702. * BandwidthCheckerClass::Get_Compact_Log -- Get basic log information to send to server *
  703. * *
  704. * *
  705. * *
  706. * INPUT: String to add info to *
  707. * *
  708. * OUTPUT: Nothing *
  709. * *
  710. * WARNINGS: None *
  711. * *
  712. * HISTORY: *
  713. * 12/4/2001 1:12PM ST : Created *
  714. *=============================================================================================*/
  715. void BandwidthCheckerClass::Get_Compact_Log(StringClass &log_string)
  716. {
  717. char temp[128];
  718. sprintf(temp, "%d\t%d\t%d\t", UpstreamBandwidth, DownstreamBandwidth, cUserOptions::Get_Bandwidth_Type());
  719. log_string = temp;
  720. }
  721. /***********************************************************************************************
  722. * BandwidthDetectWait::Create -- Create the wait object for bandwidth detection *
  723. * *
  724. * *
  725. * *
  726. * INPUT: Nothing *
  727. * *
  728. * OUTPUT: Ref Ptr to bandwidth wait *
  729. * *
  730. * WARNINGS: None *
  731. * *
  732. * HISTORY: *
  733. * 11/21/2001 3:00PM ST : Created *
  734. *=============================================================================================*/
  735. RefPtr<BandwidthDetectWait> BandwidthDetectWait::Create(void)
  736. {
  737. return (new BandwidthDetectWait());
  738. }
  739. /***********************************************************************************************
  740. * BandwidthDetectWait::BandwidthDetectWait -- BandwidthDetectWait constructor *
  741. * *
  742. * *
  743. * *
  744. * INPUT: Nothing *
  745. * *
  746. * OUTPUT: Nothing *
  747. * *
  748. * WARNINGS: None *
  749. * *
  750. * HISTORY: *
  751. * 11/21/2001 3:22PM ST : Created *
  752. *=============================================================================================*/
  753. BandwidthDetectWait::BandwidthDetectWait(void) :
  754. SingleWait(TRANSLATE (IDS_MENU_TESTING_BANDWIDTH), 60000),
  755. mEvent(NULL),
  756. mPingsRemaining(0xffffffff)
  757. {
  758. if (!cGameSpyAdmin::Is_Gamespy_Game()) {
  759. WOLSession = WWOnline::Session::GetInstance(false);
  760. assert(WOLSession.IsValid());
  761. }
  762. }
  763. /***********************************************************************************************
  764. * BandwidthDetectWait::~BandwidthDetectWait -- BandwidthDetectWait destructor *
  765. * *
  766. * *
  767. * *
  768. * INPUT: Nothing *
  769. * *
  770. * OUTPUT: Nothing *
  771. * *
  772. * WARNINGS: None *
  773. * *
  774. * HISTORY: *
  775. * 11/21/2001 3:22PM ST : Created *
  776. *=============================================================================================*/
  777. BandwidthDetectWait::~BandwidthDetectWait()
  778. {
  779. WWDEBUG_SAY(("BandwidthDetectWait: End - %S\n", mEndText));
  780. if (WOLSession.IsValid()) WOLSession->EnablePinging(true);
  781. if (mEvent) {
  782. CloseHandle(mEvent);
  783. }
  784. }
  785. /***********************************************************************************************
  786. * BandwidthDetectWait::WaitBeginning -- Called to init the wait *
  787. * *
  788. * *
  789. * *
  790. * INPUT: Nothing *
  791. * *
  792. * OUTPUT: Nothing *
  793. * *
  794. * WARNINGS: None *
  795. * *
  796. * HISTORY: *
  797. * 11/21/2001 3:22PM ST : Created *
  798. *=============================================================================================*/
  799. void BandwidthDetectWait::WaitBeginning(void)
  800. {
  801. WWDEBUG_SAY(("BandwidthDetectWait: Beginning\n"));
  802. mEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  803. if (mEvent == NULL) {
  804. WWDEBUG_SAY(("BandwidthDetectWait: Can't create event\n"));
  805. EndWait(Error, TRANSLATE (IDS_MENU_FAILED_TO_CREATE_BW_EVENT));
  806. } else {
  807. if (WOLSession.IsValid()) WOLSession->EnablePinging(false);
  808. mTimeout = 15000;
  809. }
  810. }
  811. /***********************************************************************************************
  812. * BandwidthDetectWait::GetResult -- See if there is a result for the wait condition *
  813. * *
  814. * *
  815. * *
  816. * INPUT: Nothing *
  817. * *
  818. * OUTPUT: Result code *
  819. * *
  820. * WARNINGS: None *
  821. * *
  822. * HISTORY: *
  823. * 11/21/2001 3:23PM ST : Created *
  824. *=============================================================================================*/
  825. WaitCondition::WaitResult BandwidthDetectWait::GetResult(void)
  826. {
  827. if (mEndResult == Waiting) {
  828. /*
  829. ** Wait for pings to finish first.
  830. */
  831. unsigned int pingsWaiting = 0;
  832. if (!cGameSpyAdmin::Is_Gamespy_Game()) {
  833. pingsWaiting = WOLSession->GetPendingPingCount();
  834. }
  835. if (mPingsRemaining != pingsWaiting) {
  836. mPingsRemaining = pingsWaiting;
  837. if (mPingsRemaining == 0) {
  838. mTimeout = 60000;
  839. BandwidthCheckerClass::Check_Now(mEvent);
  840. }
  841. }
  842. if (mPingsRemaining == 0) {
  843. DWORD result = WaitForSingleObject(mEvent, 0);
  844. if (result == WAIT_OBJECT_0) {
  845. WWDEBUG_SAY(("BandwidthDetectWait: ConditionMet\n"));
  846. EndWait(ConditionMet, TRANSLATE (IDS_MENU_BW_DETECTION_COMPLETE));
  847. } else {
  848. if (result == WAIT_FAILED) {
  849. WWDEBUG_SAY(("BandwidthDetectWait: WAIT_FAILED\n"));
  850. EndWait(Error, TRANSLATE (IDS_MENU_BW_DETECTION_FAILED));
  851. }
  852. }
  853. }
  854. }
  855. if (mEndResult != Waiting && WOLSession.IsValid()) {
  856. WOLSession->EnablePinging(true);
  857. }
  858. return(mEndResult);
  859. }