AutoStart.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  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. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/AutoStart.cpp $*
  25. * *
  26. * $Author:: Steve_t $*
  27. * *
  28. * $Modtime:: 8/13/02 4:58p $*
  29. * *
  30. * $Revision:: 24 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "always.h"
  36. #include "autostart.h"
  37. //#include "dlgmplangametype.h"
  38. #include "gameinitmgr.h"
  39. #include "registry.h"
  40. #include "_globals.h"
  41. #include "gamedata.h"
  42. #include "gameinitmgr.h"
  43. #include "campaign.h"
  44. #include "win.h"
  45. #include "except.h"
  46. #include "listctrl.h"
  47. #include "dlgwolautostart.h"
  48. #include "dlgdownload.h"
  49. #include "translatedb.h"
  50. #include "string_ids.h"
  51. #include "slavemaster.h"
  52. #include "gamesideservercontrol.h"
  53. #include "gamedata.h"
  54. #include "nat.h"
  55. #include "consolemode.h"
  56. #include "wwonline\wolserver.h"
  57. #include "notify.h"
  58. #include "serversettings.h"
  59. #include "wolbuddymgr.h"
  60. #include "bandwidthcheck.h"
  61. #include "bandwidth.h"
  62. #include "gamespyadmin.h"
  63. #include "specialbuilds.h"
  64. /*
  65. ** Single instance of restart class.
  66. */
  67. AutoRestartClass AutoRestart;
  68. /*
  69. ** Registry entries.
  70. */
  71. const char *AutoRestartClass::REG_VALUE_AUTO_RESTART_FLAG = "AutoRestartFlag";
  72. const char *AutoRestartClass::REG_VALUE_AUTO_RESTART_TYPE = "AutoRestartType";
  73. static const char *WINDOWS_SUB_KEY_RUN_ONCE = "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\";
  74. static const char *WINDOWS_SUB_KEY_RUN_ONCE_APP = "Renegade";
  75. /*
  76. ** Stupid extern for main loop exit.
  77. */
  78. extern void Stop_Main_Loop (int exitCode);
  79. AutoRestartProgressDialogClass *AutoRestartProgressDialogClass::Instance;
  80. /***********************************************************************************************
  81. * AutoRestartClass::AutoRestartClass -- Class constructor *
  82. * *
  83. * *
  84. * *
  85. * INPUT: Nothing *
  86. * *
  87. * OUTPUT: Nothing *
  88. * *
  89. * WARNINGS: None *
  90. * *
  91. * HISTORY: *
  92. * 11/5/2001 3:21PM ST : Created *
  93. *=============================================================================================*/
  94. AutoRestartClass::AutoRestartClass(void)
  95. {
  96. RestartState = STATE_DONE;
  97. CancelRequest = false;
  98. GameMode = 0;
  99. NumChannelCreateTries = 0;
  100. }
  101. /***********************************************************************************************
  102. * AutoRestartClass::Restart_Game -- Initiate the restart process *
  103. * *
  104. * *
  105. * *
  106. * INPUT: Nothing *
  107. * *
  108. * OUTPUT: Nothing *
  109. * *
  110. * WARNINGS: None *
  111. * *
  112. * HISTORY: *
  113. * 11/5/2001 3:22PM ST : Created *
  114. *=============================================================================================*/
  115. void AutoRestartClass::Restart_Game(void)
  116. {
  117. if (RestartState == STATE_DONE) {
  118. RestartState = STATE_FIRST;
  119. CancelRequest = false;
  120. RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
  121. if (registry.Is_Valid()) {
  122. GameMode = registry.Get_Int(REG_VALUE_AUTO_RESTART_TYPE, GameMode);
  123. }
  124. Set_Restart_Flag(false);
  125. }
  126. }
  127. /***********************************************************************************************
  128. * AutoRestartClass::Cancel -- Cancel game restart *
  129. * *
  130. * *
  131. * *
  132. * INPUT: Nothing *
  133. * *
  134. * OUTPUT: Nothing *
  135. * *
  136. * WARNINGS: None *
  137. * *
  138. * HISTORY: *
  139. * 11/5/2001 9:42PM ST : Created *
  140. *=============================================================================================*/
  141. void AutoRestartClass::Cancel(void)
  142. {
  143. CancelRequest = true;
  144. }
  145. /***********************************************************************************************
  146. * AutoRestartClass::Think -- Class service function *
  147. * *
  148. * *
  149. * *
  150. * INPUT: Nothing *
  151. * *
  152. * OUTPUT: Nothing *
  153. * *
  154. * WARNINGS: None *
  155. * *
  156. * HISTORY: *
  157. * 11/5/2001 3:22PM ST : Created *
  158. *=============================================================================================*/
  159. void AutoRestartClass::Think(void)
  160. {
  161. static unsigned long time;
  162. bool can_render = ConsoleBox.Is_Exclusive() ? false : true;
  163. switch (RestartState) {
  164. /*
  165. ** Idle, not doing anything.
  166. */
  167. case STATE_DONE:
  168. break;
  169. /*
  170. ** This is the first restart state. Initialise WOL and login.
  171. */
  172. case STATE_FIRST:
  173. if (CancelRequest) {
  174. RestartState = STATE_CANCELLED;
  175. }
  176. /*
  177. ** Create the progress dialog.
  178. */
  179. if (can_render) {
  180. START_DIALOG(AutoRestartProgressDialogClass);
  181. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Auto starting game. Type 'quit' at the console window to abort");
  182. }
  183. ConsoleBox.Print("*** Auto starting game. Type 'quit' to abort ***\n");
  184. /*
  185. ** Start listening for server control messages.
  186. */
  187. GameSideServerControlClass::Init();
  188. /*
  189. ** Initialise WOL or LAN mode.
  190. */
  191. if (!GameMode) {
  192. if (can_render) {
  193. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Initializing LAN Mode");
  194. }
  195. if (cGameSpyAdmin::Get_Is_Server_Gamespy_Listed()) {
  196. ConsoleBox.Print("Initializing GameSpy Mode\n");
  197. } else {
  198. ConsoleBox.Print("Initializing LAN Mode\n");
  199. }
  200. GameInitMgrClass::Initialize_LAN();
  201. RestartState = STATE_GAME_MODE_WAIT;
  202. } else {
  203. if (can_render) {
  204. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Initializing Westwood Online");
  205. }
  206. ConsoleBox.Print("Initializing Westwood Online Mode\n");
  207. GameInitMgrClass::Initialize_WOL();
  208. RestartState = STATE_GAME_MODE_WAIT;
  209. /*
  210. ** Force a new server list update. This will cause a complete WOLAPI reset too btw.
  211. */
  212. RefPtr<WWOnline::Session> wol_session = WWOnline::Session::GetInstance(false);
  213. wol_session->Reset();
  214. /*
  215. ** Hide the page dialog - we don't want that sucker popping up when there's no-one around.
  216. */
  217. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  218. if (buddy) {
  219. buddy->HidePagedDialog();
  220. buddy->Release_Ref();
  221. }
  222. }
  223. break;
  224. case STATE_GAME_MODE_WAIT:
  225. if (cGameData::Is_Manual_Exit()) {
  226. /*
  227. ** Allow the page dialog to display again.
  228. */
  229. if (GameMode) {
  230. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  231. if (buddy) {
  232. buddy->ShowPagedDialog();
  233. buddy->Release_Ref();
  234. }
  235. }
  236. RestartState = STATE_DONE;
  237. Stop_Main_Loop (EXIT_SUCCESS);
  238. break;
  239. } else {
  240. if (!GameMode) {
  241. GameModeClass *game_mode = GameModeManager::Find("LAN");
  242. if (game_mode && game_mode->Is_Active()) {
  243. RestartState = STATE_CREATE_GAME;
  244. break;
  245. }
  246. /*
  247. ** It won't have initialzed above if a shutdown was already pending. Maybe we need to try again.
  248. */
  249. if (game_mode && game_mode->Is_Inactive()) {
  250. GameInitMgrClass::Initialize_LAN();
  251. break;
  252. }
  253. } else {
  254. GameModeClass *game_mode = GameModeManager::Find("WOL");
  255. if (game_mode && game_mode->Is_Active()) {
  256. /*
  257. ** Logon to WOL.
  258. */
  259. if (can_render) {
  260. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Logging on");
  261. }
  262. LogonAction = (WOLLogonAction) -1;
  263. WOLLogonMgr::Set_Quiet_Mode(true);
  264. RefPtr<WWOnline::Session> WOLSession = WWOnline::Session::GetInstance(false);
  265. Observer<WWOnline::ServerError>::NotifyMe(*WOLSession);
  266. WOLLogonMgr::Logon(this);
  267. RestartState = STATE_LOGIN;
  268. break;
  269. }
  270. /*
  271. ** It won't have initialzed above if a shutdown was already pending. Maybe we need to try again.
  272. */
  273. if (game_mode && game_mode->Is_Inactive()) {
  274. GameInitMgrClass::Initialize_WOL();
  275. break;
  276. }
  277. }
  278. }
  279. break;
  280. /*
  281. ** Wait for the login process to complete.
  282. */
  283. case STATE_LOGIN:
  284. if (cGameData::Is_Manual_Exit()) {
  285. /*
  286. ** Allow the page dialog to display again.
  287. */
  288. if (GameMode) {
  289. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  290. if (buddy) {
  291. buddy->ShowPagedDialog();
  292. buddy->Release_Ref();
  293. }
  294. }
  295. Observer<WWOnline::ServerError>::StopObserving();
  296. RestartState = STATE_DONE;
  297. Stop_Main_Loop (EXIT_SUCCESS);
  298. break;
  299. }
  300. switch (LogonAction) {
  301. /*
  302. ** Login failed. Might be that the user is still logged in from last time so retry.
  303. */
  304. case WOLLOGON_FAILED:
  305. if (CancelRequest) {
  306. Observer<WWOnline::ServerError>::StopObserving();
  307. RestartState = STATE_CANCELLED;
  308. break;
  309. }
  310. if (can_render) {
  311. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Failed, retrying");
  312. }
  313. ConsoleBox.Print("Failed to log in, retrying\n");
  314. LogonAction = (WOLLogonAction) -1;
  315. if (can_render) {
  316. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Logging on");
  317. }
  318. ConsoleBox.Print("Logging on....\n");
  319. WOLLogonMgr::Logon(this);
  320. break;
  321. /*
  322. ** Logged in OK. Move onto the next step.
  323. */
  324. case WOLLOGON_SUCCESS:
  325. if (CancelRequest) {
  326. Observer<WWOnline::ServerError>::StopObserving();
  327. WOLLogonMgr::Logoff();
  328. RestartState = STATE_CANCELLED;
  329. break;
  330. }
  331. if (can_render) {
  332. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Logged on OK");
  333. }
  334. ConsoleBox.Print("Logged on OK\n");
  335. WOLLogonMgr::Set_Quiet_Mode(false);
  336. RestartState = STATE_CREATE_GAME;
  337. time = TIMEGETTIME();
  338. Observer<WWOnline::ServerError>::StopObserving();
  339. break;
  340. /*
  341. ** Patch available. At this point we want to
  342. **
  343. ** 1. Download the patch.
  344. ** 2. Quit to apply the patch.
  345. ** 3. Reload the level after the restart.
  346. **
  347. */
  348. case WOLLOGON_PATCHREQUIRED:
  349. {
  350. RefPtr<WWOnline::Session> wol_session = WWOnline::Session::GetInstance(false);
  351. ConsoleBox.Print("Downloading patch\n");
  352. DlgDownload::DoDialog(TRANSLATE(IDS_WOL_DOWNLOAD), wol_session->GetPatchDownloadList(), true);
  353. Set_Restart_Flag(true);
  354. RestartState = STATE_DONE;
  355. Observer<WWOnline::ServerError>::StopObserving();
  356. break;
  357. }
  358. /*
  359. ** Fatal error. Abort restart process.
  360. */
  361. case WOLLOGON_CANCEL:
  362. WOLLogonMgr::Set_Quiet_Mode(false);
  363. RestartState = STATE_CANCELLED;
  364. Observer<WWOnline::ServerError>::StopObserving();
  365. break;
  366. }
  367. break;
  368. /*
  369. ** Create the game object and initialise it with the settings from the last game.
  370. */
  371. case STATE_CREATE_GAME:
  372. {
  373. if (cGameData::Is_Manual_Exit()) {
  374. /*
  375. ** Allow the page dialog to display again.
  376. */
  377. if (GameMode) {
  378. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  379. if (buddy) {
  380. buddy->ShowPagedDialog();
  381. buddy->Release_Ref();
  382. }
  383. }
  384. RestartState = STATE_DONE;
  385. Stop_Main_Loop (EXIT_SUCCESS);
  386. break;
  387. }
  388. if (CancelRequest) {
  389. if (GameMode) {
  390. WOLLogonMgr::Logoff();
  391. }
  392. RestartState = STATE_CANCELLED;
  393. break;
  394. }
  395. /*
  396. ** We have to wait for the firewall thread to discover the local IP before we can build the game.
  397. */
  398. if (GameMode) {
  399. if (FirewallHelper.Get_Local_Address() == 0) {
  400. if (TIMEGETTIME() - time < 1000 * 6) {
  401. break;
  402. }
  403. }
  404. }
  405. /*
  406. ** Work out what type of game to create.
  407. */
  408. if (can_render) {
  409. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Building game info");
  410. }
  411. /*
  412. int last_game_type = 0;
  413. RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
  414. if (registry.Is_Valid ()) {
  415. last_game_type = registry.Get_Int(REG_VALUE_LAST_GAME_TYPE, last_game_type);
  416. }
  417. last_game_type = min(last_game_type, NUM_GAME_TYPE_MENU_ENTRIES-1);
  418. last_game_type = max(last_game_type, 0);
  419. int game_type = MPLanGameTypeMenuClass::GameTypeList[last_game_type].GameType;
  420. */
  421. int game_type = cGameData::GAME_TYPE_CNC;
  422. /*
  423. ** Create the new game data.
  424. */
  425. PTheGameData = cGameData::Create_Game_Of_Type((cGameData::GameTypeEnum)game_type);
  426. WWASSERT(PTheGameData != NULL);
  427. /*
  428. ** Apply command line/ini settings.
  429. */
  430. if (ServerSettingsClass::Parse(true) == false) {
  431. /*
  432. ** Allow the page dialog to display again.
  433. */
  434. if (GameMode) {
  435. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  436. if (buddy) {
  437. buddy->ShowPagedDialog();
  438. buddy->Release_Ref();
  439. }
  440. }
  441. RestartState = STATE_DONE;
  442. Stop_Main_Loop (EXIT_SUCCESS);
  443. break;
  444. }
  445. /*
  446. ** Start listening for server control messages.
  447. */
  448. //GameSideServerControlClass::Init();
  449. /*
  450. ** Load alternate server settings if required.
  451. */
  452. if (SlaveMaster.Am_I_Slave()) {
  453. RegistryClass reg(APPLICATION_SUB_KEY_NAME_OPTIONS);
  454. char file_name[MAX_PATH];
  455. reg.Get_String("MultiplayerSettings", file_name, sizeof(file_name), "");
  456. if (strlen(file_name)) {
  457. WWDEBUG_SAY(("Loading multiplayer settings from file %s\n", file_name));
  458. The_Game()->Set_Ini_Filename(file_name);
  459. }
  460. }
  461. /*
  462. ** Load the game settings.
  463. */
  464. The_Game()->Load_From_Server_Config();
  465. /*
  466. ** Set MaxPlayers based on Bandwidth test results if MaxPlayers is
  467. ** set to 0 in the INI file.
  468. */
  469. if (ServerSettingsClass::Get_Game_Mode() == ServerSettingsClass::MODE_WOL &&
  470. The_Game()->Get_Max_Players() == 0 && BandwidthCheckerClass::Got_Bandwidth()) {
  471. int max_players = (cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_AUTO) / 250000) * 4;
  472. if (max_players < 2) {
  473. if (cBandwidth::Get_Bandwidth_Bps_From_Type(BANDWIDTH_AUTO) > 100000) {
  474. max_players = 4;
  475. } else {
  476. max_players = 2;
  477. }
  478. } else if (max_players > 32) {
  479. max_players = 32;
  480. }
  481. The_Game()->Set_Max_Players(max_players);
  482. }
  483. /*
  484. ** Override gama settings in command line mode.
  485. */
  486. if (ServerSettingsClass::Is_Command_Line_Mode()) {
  487. The_Game()->IsAutoRestart.Set(true);
  488. The_Game()->IsDedicated.Set(true);
  489. }
  490. StringClass inifile = The_Game()->Get_Ini_Filename();
  491. StringClass nick(32, true);
  492. cNetInterface::Get_Nickname().Convert_To(nick);
  493. ConsoleBox.Set_Title(nick.Peek_Buffer(), inifile.Peek_Buffer());
  494. if (GameMode) {
  495. NumChannelCreateTries = 0;
  496. RestartState = STATE_CREATE_CHANNEL;
  497. } else {
  498. RestartState = STATE_START_GAME;
  499. }
  500. break;
  501. }
  502. /*
  503. ** Create the game channel on the chat server.
  504. */
  505. case STATE_CREATE_CHANNEL:
  506. {
  507. if (cGameData::Is_Manual_Exit()) {
  508. /*
  509. ** Allow the page dialog to display again.
  510. */
  511. if (GameMode) {
  512. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  513. if (buddy) {
  514. buddy->ShowPagedDialog();
  515. buddy->Release_Ref();
  516. }
  517. /*
  518. ** Log off.
  519. */
  520. WOLLogonMgr::Logoff();
  521. }
  522. RestartState = STATE_DONE;
  523. Stop_Main_Loop (EXIT_SUCCESS);
  524. break;
  525. }
  526. if (CancelRequest) {
  527. WOLLogonMgr::Logoff();
  528. RestartState = STATE_CANCELLED;
  529. break;
  530. }
  531. if (can_render) {
  532. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Creating game channel....");
  533. }
  534. ConsoleBox.Print("Creating game channel...\n");
  535. /*
  536. ** Create the game channel.
  537. */
  538. GameModeClass *game_mode = GameModeManager::Find("WOL");
  539. LastChannelCreateTime = TIMEGETTIME();
  540. if (game_mode && game_mode->Is_Active()) {
  541. WolGameModeClass* wol_game = (WolGameModeClass*) game_mode;
  542. WWASSERT(wol_game);
  543. wol_game->Set_Quiet_Mode(true);
  544. wol_game->SignalMe(*this);
  545. WWASSERT(PTheGameData != NULL);
  546. NumChannelCreateTries++;
  547. wol_game->Create_Game(The_Game());
  548. RestartState = STATE_WAIT_CHANNEL_CREATE;
  549. } else {
  550. RestartState = STATE_START_GAME;
  551. }
  552. break;
  553. }
  554. /*
  555. ** Wait for the game channel creation result.
  556. */
  557. case STATE_WAIT_CHANNEL_CREATE:
  558. if (cGameData::Is_Manual_Exit()) {
  559. /*
  560. ** Allow the page dialog to display again.
  561. */
  562. if (GameMode) {
  563. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  564. if (buddy) {
  565. buddy->ShowPagedDialog();
  566. buddy->Release_Ref();
  567. }
  568. /*
  569. ** Log off.
  570. */
  571. WOLLogonMgr::Logoff();
  572. }
  573. RestartState = STATE_DONE;
  574. Stop_Main_Loop (EXIT_SUCCESS);
  575. }
  576. if (CancelRequest) {
  577. WOLLogonMgr::Logoff();
  578. RestartState = STATE_CANCELLED;
  579. break;
  580. }
  581. break;
  582. /*
  583. ** Waiting to retry channel create.
  584. */
  585. case STATE_WAIT_CHANNEL_CREATE_RETRY:
  586. if (cGameData::Is_Manual_Exit()) {
  587. /*
  588. ** Allow the page dialog to display again.
  589. */
  590. if (GameMode) {
  591. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  592. if (buddy) {
  593. buddy->ShowPagedDialog();
  594. buddy->Release_Ref();
  595. }
  596. /*
  597. ** Log off.
  598. */
  599. WOLLogonMgr::Logoff();
  600. }
  601. RestartState = STATE_DONE;
  602. Stop_Main_Loop (EXIT_SUCCESS);
  603. break;
  604. }
  605. if (CancelRequest) {
  606. WOLLogonMgr::Logoff();
  607. RestartState = STATE_CANCELLED;
  608. break;
  609. }
  610. /*
  611. ** Give up and restart if we fail enough times when trying to create a channel.
  612. */
  613. if (NumChannelCreateTries > 10) {
  614. Set_Exit_On_Exception(true);
  615. cGameData::Set_Manual_Exit(true);
  616. }
  617. if (TIMEGETTIME() - LastChannelCreateTime > 5*1000) {
  618. ConsoleBox.Print("Retrying channel create\n");
  619. RestartState = STATE_CREATE_CHANNEL;
  620. }
  621. break;
  622. /*
  623. ** Load the game.
  624. */
  625. case STATE_START_GAME:
  626. {
  627. if (cGameData::Is_Manual_Exit()) {
  628. /*
  629. ** Allow the page dialog to display again.
  630. */
  631. if (GameMode) {
  632. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  633. if (buddy) {
  634. buddy->ShowPagedDialog();
  635. buddy->Release_Ref();
  636. }
  637. /*
  638. ** Log off.
  639. */
  640. WOLLogonMgr::Logoff();
  641. }
  642. RestartState = STATE_DONE;
  643. Stop_Main_Loop (EXIT_SUCCESS);
  644. break;
  645. }
  646. if (can_render) {
  647. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Channel created OK");
  648. }
  649. ConsoleBox.Print("Channel created OK\n");
  650. SlaveMaster.Startup_Slaves();
  651. GameModeClass *game_mode = GameModeManager::Find("WOL");
  652. if (game_mode && game_mode->Is_Active()) {
  653. WolGameModeClass* wol_game = (WolGameModeClass*) game_mode;
  654. WWASSERT(wol_game);
  655. wol_game->Set_Quiet_Mode(false);
  656. }
  657. //ConsoleBox.Print("Loading level...\n");
  658. WWASSERT(PTheGameData != NULL);
  659. CampaignManager::Select_Backdrop_Number_By_MP_Type(The_Game()->Get_Game_Type());
  660. GameInitMgrClass::Set_Is_Client_Required(false);
  661. GameInitMgrClass::Set_Is_Server_Required(true);
  662. if (can_render) {
  663. AutoRestartProgressDialogClass::Get_Instance()->End_Dialog();
  664. }
  665. GameInitMgrClass::Start_Game(The_Game()->Get_Map_Name(), -1, 0);
  666. //ConsoleBox.Print("Level loaded OK\n");
  667. RestartState = STATE_DONE;
  668. /*
  669. ** Allow the page dialog to display again (it can't really anyway since it's disabled when the game is in progress.
  670. */
  671. if (GameMode) {
  672. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  673. if (buddy) {
  674. buddy->ShowPagedDialog();
  675. buddy->Release_Ref();
  676. }
  677. }
  678. break;
  679. }
  680. /*
  681. ** User cancelled.
  682. */
  683. case STATE_CANCELLED:
  684. RestartState = STATE_DONE;
  685. /*
  686. ** Allow the page dialog to display again.
  687. */
  688. WOLBuddyMgr* buddy = WOLBuddyMgr::GetInstance(false);
  689. if (buddy) {
  690. buddy->ShowPagedDialog();
  691. buddy->Release_Ref();
  692. }
  693. if (can_render) {
  694. AutoRestartProgressDialogClass::Get_Instance()->End_Dialog();
  695. }
  696. if (SlaveMaster.Am_I_Slave()) {
  697. if (GameMode) {
  698. WOLLogonMgr::Logoff();
  699. }
  700. RestartState = STATE_DONE;
  701. Stop_Main_Loop (EXIT_SUCCESS);
  702. } else {
  703. RenegadeDialogMgrClass::Goto_Location (RenegadeDialogMgrClass::LOC_MAIN_MENU);
  704. }
  705. break;
  706. }
  707. }
  708. /***********************************************************************************************
  709. * AutoRestartClass::HandleNotification -- Notification callback for WOL login *
  710. * *
  711. * *
  712. * *
  713. * INPUT: Success code *
  714. * *
  715. * OUTPUT: Nothing *
  716. * *
  717. * WARNINGS: None *
  718. * *
  719. * HISTORY: *
  720. * 11/5/2001 3:23PM ST : Created *
  721. *=============================================================================================*/
  722. void AutoRestartClass::HandleNotification(WOLLogonAction& action)
  723. {
  724. LogonAction = action;
  725. }
  726. /***********************************************************************************************
  727. * WolGameModeClass::HandleNotification -- Handle server error notifications *
  728. * *
  729. * *
  730. * *
  731. * INPUT: Server error tyoe *
  732. * *
  733. * OUTPUT: Nothing *
  734. * *
  735. * WARNINGS: None *
  736. * *
  737. * HISTORY: *
  738. * 11/8/2001 10:21PM ST : Created *
  739. *=============================================================================================*/
  740. void AutoRestartClass::HandleNotification(WWOnline::ServerError& server_error)
  741. {
  742. ConsoleBox.Print("Error - %S\n", server_error.GetDescription());
  743. }
  744. /***********************************************************************************************
  745. * AutoRestartClass::ReceiveSignal -- Channel creation signal handler *
  746. * *
  747. * *
  748. * *
  749. * INPUT: Game mode *
  750. * *
  751. * OUTPUT: Nothing *
  752. * *
  753. * WARNINGS: None *
  754. * *
  755. * HISTORY: *
  756. * 11/5/2001 3:23PM ST : Created *
  757. *=============================================================================================*/
  758. void AutoRestartClass::ReceiveSignal(WolGameModeClass &game_mode)
  759. {
  760. if (RestartState == STATE_WAIT_CHANNEL_CREATE) {
  761. if (game_mode.Channel_Create_OK()) {
  762. RestartState = STATE_START_GAME;
  763. } else {
  764. bool can_render = ConsoleBox.Is_Exclusive() ? false : true;
  765. if (can_render) {
  766. AutoRestartProgressDialogClass::Get_Instance()->Add_Text(L"Failed, retrying");
  767. }
  768. ConsoleBox.Print("Failed to create channel\n");
  769. RestartState = STATE_WAIT_CHANNEL_CREATE_RETRY;
  770. }
  771. }
  772. }
  773. /***********************************************************************************************
  774. * AutoRestartClass::Set_Restart_Flag -- Set state of auto restart mode *
  775. * *
  776. * *
  777. * *
  778. * INPUT: New state *
  779. * *
  780. * OUTPUT: Nothing *
  781. * *
  782. * WARNINGS: None *
  783. * *
  784. * HISTORY: *
  785. * 11/5/2001 3:32PM ST : Created *
  786. *=============================================================================================*/
  787. void AutoRestartClass::Set_Restart_Flag(bool enable)
  788. {
  789. RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
  790. if (registry.Is_Valid ()) {
  791. registry.Set_Int(REG_VALUE_AUTO_RESTART_FLAG, enable ? 1 : 0);
  792. GameModeClass *game_mode = GameModeManager::Find("WOL");
  793. if (game_mode && game_mode->Is_Active()) {
  794. GameMode = 1;
  795. } else {
  796. GameModeClass *game_mode = GameModeManager::Find("LAN");
  797. if (game_mode && game_mode->Is_Active()) {
  798. GameMode = 0;
  799. }
  800. }
  801. if (enable) {
  802. registry.Set_Int(REG_VALUE_AUTO_RESTART_TYPE, GameMode);
  803. Set_Exit_On_Exception(true);
  804. } else {
  805. Set_Exit_On_Exception(false);
  806. }
  807. RegistryClass registry_too(WINDOWS_SUB_KEY_RUN_ONCE);
  808. if (registry_too.Is_Valid()) {
  809. if (enable) {
  810. /*
  811. ** The the current path and build a path/file combo that points to the launcher.
  812. */
  813. char path_to_exe[256];
  814. char drive[_MAX_DRIVE];
  815. char dir[_MAX_DIR];
  816. char path[_MAX_PATH];
  817. GetModuleFileName(ProgramInstance, path_to_exe, sizeof(path_to_exe));
  818. _splitpath(path_to_exe, drive, dir, NULL, NULL);
  819. #ifdef FREEDEDICATEDSERVER
  820. _makepath(path, drive, dir, "renegadeserver", "exe");
  821. #else //FREEDEDICATEDSERVER
  822. _makepath(path, drive, dir, "renegade", "exe");
  823. char options[256];
  824. options[0] = 0;
  825. if (ServerSettingsClass::Is_Active()) {
  826. sprintf(options, " /startserver=%s", ServerSettingsClass::Get_Settings_File_Name());
  827. }
  828. if (ConsoleBox.Is_Exclusive()) {
  829. strcat(options, " /nodx");
  830. }
  831. strcat(path, options);
  832. #endif //FREEDEDICATEDSERVER
  833. WWDEBUG_SAY(("Writing %s to RunOnce key\n", path));
  834. registry_too.Set_String(WINDOWS_SUB_KEY_RUN_ONCE_APP, path);
  835. } else {
  836. WWDEBUG_SAY(("Removing RunOnce key\n"));
  837. registry_too.Delete_Value(WINDOWS_SUB_KEY_RUN_ONCE_APP);
  838. }
  839. }
  840. }
  841. }
  842. /***********************************************************************************************
  843. * AutoRestartClass::Get_Restart_Flag -- Is a restart indicated by the registry? *
  844. * *
  845. * *
  846. * *
  847. * INPUT: New state *
  848. * *
  849. * OUTPUT: Nothing *
  850. * *
  851. * WARNINGS: None *
  852. * *
  853. * HISTORY: *
  854. * 11/5/2001 3:32PM ST : Created *
  855. *=============================================================================================*/
  856. bool AutoRestartClass::Get_Restart_Flag(void)
  857. {
  858. bool flag = false;
  859. RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS);
  860. if (registry.Is_Valid()) {
  861. int restart = registry.Get_Int(REG_VALUE_AUTO_RESTART_FLAG, 0);
  862. flag = restart ? true : false;
  863. }
  864. return(flag);
  865. }