WOL_LOGN.CPP 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. #ifdef WOLAPI_INTEGRATION
  15. // Wol_Logn.cpp - WW online name/password dialog.
  16. // ajw 07/16/98
  17. #include "function.h"
  18. #include "IconList.h"
  19. #include "WolapiOb.h"
  20. #include "PassEdit.h"
  21. #include "WolStrng.h"
  22. #include "BigCheck.h"
  23. bool ReadSavedNicks( WolapiObject* pWO, IconListClass& NickList, char* szNameBuffer, char* szPassBuffer );
  24. bool bSaveNick( WolapiObject* pWO, const char* szNickToSave, const char* szPassToSave, bool bPassIsMangled );
  25. void DeleteNick( WolapiObject* pWO, int iOneBasedEntryToDelete );
  26. //char* LoadShpFile( const char* szShpFile );
  27. void DebugChatDef( HRESULT hRes );
  28. extern bool bTabKeyPressedHack;
  29. //#include "WolDebug.h"
  30. //***********************************************************************************************
  31. int WOL_Login_Dialog( WolapiObject* pWO )
  32. {
  33. // Return values: 0 = user cancels, 1 = success, -1 = force game exit
  34. if( pWO->bLoggedIn() )
  35. {
  36. pWO->bReturningAfterGame = true; // Set trigger for chat dialog.
  37. return 1; // We are already logged in, and have just come back from a game.
  38. }
  39. /*
  40. ** Dialog & button dimensions
  41. */
  42. #ifdef FRENCH
  43. int d_dialog_w = 160 * RESFACTOR; // dialog width
  44. #else
  45. int d_dialog_w = 150 * RESFACTOR; // dialog width
  46. #endif
  47. int d_dialog_h = 85 * RESFACTOR; // dialog height
  48. int d_dialog_x = (((320 * RESFACTOR) - d_dialog_w) / 2);
  49. int d_dialog_y = (((255 * RESFACTOR) - d_dialog_h) / 2);
  50. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // coord of x-center
  51. int d_txt8_h = 11 * RESFACTOR; // ht of 8-pt text
  52. int d_margin = 7 * RESFACTOR; // margin width/height
  53. int x_margin = 16 * RESFACTOR; // margin width/height
  54. int top_margin = 0;
  55. int d_name_w = 66 * RESFACTOR;
  56. int d_name_h = 10 * RESFACTOR;
  57. #ifdef FRENCH
  58. int d_name_x = d_dialog_x + 25 * RESFACTOR;
  59. #else
  60. int d_name_x = d_dialog_x + 20 * RESFACTOR;
  61. #endif
  62. int d_name_y = d_dialog_y + top_margin + 25 * RESFACTOR;
  63. int d_pass_w = 36 * RESFACTOR;
  64. int d_pass_h = d_name_h;
  65. int d_pass_x = d_name_x + d_name_w + 6 * RESFACTOR;
  66. int d_pass_y = d_name_y;
  67. int d_list_w = d_name_w;
  68. int d_list_h = 20 * RESFACTOR;
  69. int d_list_x = d_name_x;
  70. int d_list_y = d_dialog_y + top_margin + 40 * RESFACTOR;
  71. // int d_save_w = d_pass_w;
  72. int d_save_h = 9 * RESFACTOR;
  73. int d_save_x = d_pass_x + ( d_pass_w / 2 ) - ( d_pass_w / 2 );
  74. int d_save_y = d_list_y; // + ( d_list_h / 2 ) - ( d_save_h / 2 );
  75. int d_delete_w = d_pass_w;
  76. int d_delete_h = 10 * RESFACTOR;
  77. int d_delete_x = d_save_x;
  78. int d_delete_y = d_list_y + d_list_h - d_delete_h;
  79. #ifdef FRENCH
  80. int d_connect_w = 45 * RESFACTOR;
  81. #else
  82. int d_connect_w = 40 * RESFACTOR;
  83. #endif
  84. int d_connect_h = 13 * RESFACTOR;
  85. int d_connect_x = d_name_x + d_name_w/2 - d_connect_w/2;
  86. int d_connect_y = d_dialog_y + top_margin + 65 * RESFACTOR; //d_dialog_y + d_dialog_h - d_connect_h - d_margin;
  87. #if defined(GERMAN) || defined(FRENCH)
  88. int d_cancel_w = 40 * RESFACTOR;//BG:40
  89. #else
  90. int d_cancel_w = 40 * RESFACTOR;
  91. #endif
  92. int d_cancel_h = 13 * RESFACTOR;
  93. int d_cancel_x = d_pass_x + d_pass_w/2 - d_cancel_w/2; //d_dialog_cx + d_margin;
  94. int d_cancel_y = d_connect_y;
  95. /*
  96. ** Button enumerations
  97. */
  98. enum {
  99. BUTTON_CONNECT = 100,
  100. BUTTON_CANCEL,
  101. LISTBOX_NICKS,
  102. EDITBOX_NAME,
  103. EDITBOX_PASS,
  104. BUTTON_SAVECHECK,
  105. BUTTON_DELETE,
  106. };
  107. /*
  108. ** Redraw values: in order from "top" to "bottom" layer of the dialog
  109. */
  110. typedef enum {
  111. REDRAW_NONE = 0,
  112. REDRAW_BUTTONS,
  113. REDRAW_BACKGROUND,
  114. REDRAW_ALL = REDRAW_BACKGROUND
  115. } RedrawType;
  116. /*
  117. ** Dialog variables
  118. */
  119. int iReturn = 1; // 0 = user cancels, 1 = success, -1 = force game exit
  120. /*
  121. ** Other Variables
  122. */
  123. char szNameBuffer[ WOL_NAME_LEN_MAX ] = {0}; // User name.
  124. char szPassBuffer[ WOL_PASSWORD_LEN ] = {0}; // User password.
  125. /*
  126. ** Buttons
  127. */
  128. ControlClass* commands = NULL; // the button list
  129. TextButtonClass ConnectBtn( BUTTON_CONNECT, TXT_WOL_CONNECT, TPF_BUTTON, d_connect_x, d_connect_y, d_connect_w );
  130. TextButtonClass CancelBtn( BUTTON_CANCEL, TXT_CANCEL, TPF_BUTTON, d_cancel_x, d_cancel_y, d_cancel_w );
  131. IconListClass NickList( LISTBOX_NICKS, d_list_x, d_list_y, d_list_w, d_list_h, TPF_6PT_GRAD | TPF_NOSHADOW,
  132. MFCD::Retrieve("BTN-UP.SHP"), MFCD::Retrieve("BTN-DN.SHP"), true, 1, 0 );
  133. WOLEditClass NameEdit( EDITBOX_NAME, szNameBuffer, sizeof(szNameBuffer), TPF_6PT_GRAD|TPF_NOSHADOW,
  134. d_name_x, d_name_y, d_name_w, -1, EditClass::ALPHANUMERIC );
  135. PassEditClass PassEdit( EDITBOX_PASS, szPassBuffer, sizeof(szPassBuffer), TPF_6PT_GRAD|TPF_NOSHADOW,
  136. d_pass_x, d_pass_y, d_pass_w, -1, EditClass::ALPHANUMERIC );
  137. // Just making sure globals are set right before String_Pixel_Width() call... sigh
  138. Fancy_Text_Print( TXT_NONE, 0, 0, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_6PT_GRAD | TPF_NOSHADOW );
  139. int iSaveTextWidth = String_Pixel_Width( TXT_WOL_SAVELOGIN ) + BIGCHECK_OFFSETX;
  140. BigCheckBoxClass SaveCheckBox( BUTTON_SAVECHECK, d_save_x, d_save_y, iSaveTextWidth, d_save_h,
  141. TXT_WOL_SAVELOGIN, TPF_6PT_GRAD | TPF_NOSHADOW, true );
  142. TextButtonClass DeleteBtn( BUTTON_DELETE, TXT_DELETE_BUTTON, TPF_BUTTON, d_delete_x, d_delete_y, d_delete_w );
  143. /*
  144. ** Initialize.
  145. */
  146. Set_Logic_Page(SeenBuff);
  147. // Get saved nickname/passwords from the registry.
  148. if( ReadSavedNicks( pWO, NickList, szNameBuffer, szPassBuffer ) )
  149. {
  150. PassEdit.bClearOnNextSetFocus = true;
  151. }
  152. else
  153. {
  154. // Offer user the chance to go to web site now to get a nick.
  155. if( pWO->DoWebRegistration() )
  156. {
  157. // User chose to go to web page. Leave function so that we'll re-read nicks when they return.
  158. return 0;
  159. }
  160. }
  161. /*
  162. ** Create the button list.
  163. */
  164. commands = &ConnectBtn;
  165. CancelBtn.Add_Tail(*commands);
  166. NickList.Add_Tail(*commands);
  167. NameEdit.Add_Tail(*commands);
  168. PassEdit.Add_Tail(*commands);
  169. SaveCheckBox.Add_Tail(*commands);
  170. DeleteBtn.Add_Tail(*commands);
  171. NameEdit.Set_Focus();
  172. if( NickList.Count() == 0 )
  173. DeleteBtn.Disable();
  174. /*
  175. ** Main Processing Loop.
  176. */
  177. Keyboard->Clear();
  178. bool firsttime = true;
  179. bool display = true;
  180. bool process = true;
  181. while (process) {
  182. /*
  183. ** Invoke game callback.
  184. */
  185. Call_Back();
  186. #ifdef WIN32
  187. /*
  188. ** If we have just received input focus again after running in the background then
  189. ** we need to redraw.
  190. */
  191. if (AllSurfaces.SurfacesRestored) {
  192. AllSurfaces.SurfacesRestored=FALSE;
  193. display = true;
  194. }
  195. #endif
  196. /*
  197. ** Refresh display if needed.
  198. */
  199. if (display) {
  200. //------------------------------------------------------------------------
  201. // Clear screen
  202. //------------------------------------------------------------------------
  203. Hide_Mouse();
  204. Load_Title_Page(true);
  205. // Show_Mouse();
  206. /*
  207. ** Display the dialog box.
  208. */
  209. // Hide_Mouse();
  210. if (display) {
  211. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  212. Draw_Caption(TXT_WOL_LOGINDIALOG, d_dialog_x, d_dialog_y, d_dialog_w);
  213. }
  214. /*
  215. ** Redraw the buttons.
  216. */
  217. if (display) {
  218. Fancy_Text_Print( TXT_WOL_NAME, d_name_x + ( d_name_w / 2 ), d_name_y - 14,
  219. GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT | TPF_CENTER );
  220. Fancy_Text_Print( TXT_WOL_PASSWORD, d_pass_x + ( d_pass_w / 2 ), d_pass_y - 14,
  221. GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT | TPF_CENTER );
  222. commands->Flag_List_To_Redraw();
  223. }
  224. Show_Mouse();
  225. display = false;
  226. }
  227. // Force mouse visible, as some beta testers report unexplicable disappearing cursors.
  228. while( Get_Mouse_State() )
  229. Show_Mouse();
  230. // Be nice to other apps.
  231. Sleep( 50 );
  232. /*
  233. ** Get user input.
  234. */
  235. bTabKeyPressedHack = false;
  236. KeyNumType input = commands->Input();
  237. /*
  238. ** The first time through the processing loop, set the edit
  239. ** gadget to have the focus. The
  240. ** focus must be set here since the gadget list has changed
  241. ** and this change will cause any previous focus setting to be
  242. ** cleared by the input processing routine.
  243. */
  244. if (firsttime ) {
  245. firsttime = false;
  246. NameEdit.Set_Focus();
  247. NameEdit.Flag_To_Redraw();
  248. }
  249. // /*
  250. // ** If the <RETURN> key was pressed, then default to the appropriate
  251. // ** action button according to the style of this dialog box.
  252. // */
  253. /* if (input == KN_RETURN || input == (BUTTON_CONNECT|KN_BUTTON)) {
  254. ToggleClass * toggle = NULL;
  255. input = (KeyNumType)(BUTTON_CONNECT|KN_BUTTON);
  256. CancelBtn.Turn_Off();
  257. toggle = (ToggleClass*)commands->Extract_Gadget(BUTTON_CONNECT);
  258. if (toggle != NULL) {
  259. toggle->Turn_On();
  260. toggle->IsPressed = true;
  261. }
  262. Hide_Mouse();
  263. commands->Draw_All(true);
  264. Show_Mouse();
  265. }
  266. */
  267. /*
  268. ** Process input.
  269. */
  270. // if( input )
  271. // debugprint( "input: %i\n", input );
  272. if( bTabKeyPressedHack )
  273. {
  274. if( NameEdit.Has_Focus() )
  275. PassEdit.Set_Focus();
  276. else
  277. NameEdit.Set_Focus();
  278. NameEdit.Flag_To_Redraw();
  279. PassEdit.Flag_To_Redraw();
  280. }
  281. switch( input )
  282. {
  283. /*
  284. ** ESC/Cancel: break
  285. */
  286. case ( KN_ESC ):
  287. case ( BUTTON_CANCEL | KN_BUTTON ):
  288. iReturn = 0;
  289. process = false;
  290. break;
  291. case KN_RETURN:
  292. case ( EDITBOX_NAME | KN_BUTTON ):
  293. case ( EDITBOX_PASS | KN_BUTTON ):
  294. case ( BUTTON_CONNECT | KN_BUTTON ):
  295. {
  296. if( !strlen( szNameBuffer ) )
  297. {
  298. WWMessageBox().Process( TXT_WOL_MISSINGNAME );
  299. firsttime = true; // Bloody hack.
  300. NameEdit.Set_Focus();
  301. Keyboard->Clear();
  302. display = true;
  303. break;
  304. }
  305. if( !strlen( szPassBuffer ) )
  306. {
  307. WWMessageBox().Process( TXT_WOL_MISSINGPASSWORD );
  308. firsttime = true; // Bloody hack.
  309. PassEdit.Set_Focus();
  310. Keyboard->Clear();
  311. display = true;
  312. break;
  313. }
  314. // If we have not done RequestServerList() yet, do it now.
  315. if( !pWO->pChatSink->pServer )
  316. {
  317. bool bBreak = false;
  318. HRESULT hRes = pWO->GetChatServer();
  319. switch( hRes )
  320. {
  321. case E_FAIL:
  322. bBreak = true;
  323. WWMessageBox().Process( TXT_WOL_CANTCONNECT );
  324. firsttime = true; // Bloody hack.
  325. NameEdit.Set_Focus();
  326. Keyboard->Clear();
  327. display = true;
  328. break;
  329. case USERCANCELLED:
  330. bBreak = true;
  331. WWMessageBox().Process( TXT_WOL_LOGINCANCEL );
  332. firsttime = true; // Bloody hack.
  333. NameEdit.Set_Focus();
  334. Keyboard->Clear();
  335. display = true;
  336. break;
  337. case PATCHAVOIDED:
  338. bBreak = true;
  339. firsttime = true; // Bloody hack.
  340. NameEdit.Set_Focus();
  341. Keyboard->Clear();
  342. display = true;
  343. break;
  344. case PATCHDOWNLOADED:
  345. bBreak = true;
  346. process = false;
  347. iReturn = -1;
  348. break;
  349. }
  350. if( bBreak )
  351. break;
  352. }
  353. // RequestConnection()...
  354. HRESULT hRes = pWO->AttemptLogin( szNameBuffer, szPassBuffer, PassEdit.bClearOnNextSetFocus );
  355. if( hRes == S_OK )
  356. {
  357. if( SaveCheckBox.IsOn && !bSaveNick( pWO, szNameBuffer, szPassBuffer, PassEdit.bClearOnNextSetFocus ) )
  358. {
  359. // Nick/pass save failed.
  360. WWMessageBox().Process( TXT_WOL_CANTSAVENICK );
  361. }
  362. process = false;
  363. }
  364. else
  365. {
  366. switch( hRes )
  367. {
  368. case USERCANCELLED:
  369. WWMessageBox().Process( TXT_WOL_LOGINCANCEL );
  370. break;
  371. case CHAT_E_TIMEOUT:
  372. WWMessageBox().Process( TXT_WOL_TIMEOUT );
  373. break;
  374. case CHAT_E_BADPASS:
  375. WWMessageBox().Process( TXT_WOL_BADPASS );
  376. break;
  377. case CHAT_E_NICKINUSE:
  378. WWMessageBox().Process( TXT_WOL_NICKINUSE );
  379. break;
  380. case CHAT_E_CON_ERROR:
  381. // This error value I pass back myself, when the emergency timeout is hit.
  382. WWMessageBox().Process( TXT_WOL_TIMEOUT );
  383. break;
  384. }
  385. firsttime = true; // Bloody hack.
  386. NameEdit.Set_Focus();
  387. Keyboard->Clear();
  388. display = true;
  389. }
  390. break;
  391. }
  392. /*
  393. case( EDITBOX_PASS | KN_BUTTON ):
  394. {
  395. // Message with delay so that user has time to read it...
  396. CDTimerClass<SystemTimerClass> timer;
  397. timer = TICKS_PER_SECOND*4;
  398. WWMessageBox().Process(TXT_WOL_DEBUG2, TXT_NONE);
  399. while (timer > 0) {
  400. Call_Back();
  401. }
  402. Keyboard->Clear();
  403. display = true;
  404. break;
  405. }
  406. */
  407. case ( LISTBOX_NICKS | KN_BUTTON ):
  408. strcpy( szNameBuffer, NickList.Get_Item( NickList.Current_Index() ) );
  409. strcpy( szPassBuffer, NickList.Get_Item_ExtraDataString( NickList.Current_Index() ) );
  410. NameEdit.Flag_To_Redraw();
  411. PassEdit.Flag_To_Redraw();
  412. // Because the password is mangled, if the user begins to edit it now, we clear it.
  413. // Otherwise we could get a half-mangled, half-unmangled password field.
  414. // PassEdit.bClearOnNextSetFocus also acts as a flag telling us whether or not the
  415. // password field is mangled or not.
  416. PassEdit.bClearOnNextSetFocus = true;
  417. // display = true;
  418. break;
  419. case ( BUTTON_SAVECHECK | KN_BUTTON ):
  420. break;
  421. case ( BUTTON_DELETE | KN_BUTTON ):
  422. if( NickList.Count() > 0 )
  423. {
  424. DeleteNick( pWO, NickList.Current_Index() + 1 );
  425. NickList.Remove_Item( NickList.Current_Index() );
  426. NickList.Flag_To_Redraw();
  427. if( NickList.Count() == 0 )
  428. {
  429. DeleteBtn.Disable();
  430. DeleteBtn.Flag_To_Redraw();
  431. }
  432. }
  433. break;
  434. default:
  435. break;
  436. }
  437. }
  438. return iReturn;
  439. }
  440. //***********************************************************************************************
  441. bool ReadSavedNicks( WolapiObject* pWO, IconListClass& NickList, char* szNameBuffer, char* szPassBuffer )
  442. {
  443. // Read saved nickname/passwords from the registry.
  444. // Set up the list of nick/passwords.
  445. // Copy the first nick into the nick/password edits.
  446. // Returns true if edits are set with a default nick/pass because a nick was found.
  447. LPCSTR szNick;
  448. LPCSTR szPass;
  449. bool bReturn = false;
  450. for( int i = 1; i != 3; i++ )
  451. {
  452. if( pWO->pChat->GetNick( i, &szNick, &szPass ) == S_OK )
  453. {
  454. if( *szNick )
  455. {
  456. NickList.Add_Item( szNick, NULL, NULL, ICON_SHAPE, szPass );
  457. if( i == 1 )
  458. {
  459. strcpy( szNameBuffer, szNick );
  460. strcpy( szPassBuffer, szPass );
  461. bReturn = true;
  462. }
  463. }
  464. }
  465. }
  466. return bReturn;
  467. }
  468. //***********************************************************************************************
  469. bool bSaveNick( WolapiObject* pWO, const char* szNickToSave, const char* szPassToSave, bool bPassIsMangled )
  470. {
  471. // Saves specified nick and password in the registry, using SetNick.
  472. // Returns false if nick can't be saved.
  473. // If slot 1 empty, use slot 1.
  474. // Else push nick 1 down to second slot and save new nick in slot 1, unless
  475. // nick 1 name matches new entry.
  476. LPCSTR szNick;
  477. LPCSTR szPass;
  478. bool bPushSlot1 = true;
  479. switch( pWO->pChat->GetNick( 1, &szNick, &szPass ) )
  480. {
  481. case E_FAIL:
  482. // Assume that this is because there is no registry entry. We can use this slot.
  483. bPushSlot1 = false;
  484. break;
  485. case S_OK:
  486. if( *szNick == 0 )
  487. bPushSlot1 = false; // We can use this blank slot.
  488. else
  489. if( strcmp( szNick, szNickToSave ) == 0 )
  490. bPushSlot1 = false; // We can use this slot as the name is the same.
  491. break;
  492. }
  493. if( bPushSlot1 )
  494. {
  495. // Move nick in slot 1 to slot 2.
  496. pWO->pChat->SetNick( 2, szNick, szPass, false ); // (Already mangled.)
  497. }
  498. // Save new nick in slot 1.
  499. return ( pWO->pChat->SetNick( 1, szNickToSave, szPassToSave, !bPassIsMangled ) == S_OK );
  500. /*
  501. int iSlot;
  502. bool bStop = false;
  503. for( iSlot = 1; iSlot != 3; iSlot++ )
  504. {
  505. switch( pWO->pChat->GetNick( iSlot, &szNick, &szPass ) )
  506. {
  507. case E_FAIL:
  508. // Assume that this is because there is no registry entry. We can use this slot.
  509. bStop = true;
  510. break;
  511. case S_OK:
  512. if( *szNick == 0 )
  513. bStop = true; // We can use this blank slot.
  514. else
  515. if( strcmp( szNick, szNickToSave ) == 0 )
  516. bStop = true; // We can use this slot as the name is the same.
  517. break;
  518. }
  519. if( bStop )
  520. break;
  521. }
  522. if( iSlot == 3 )
  523. {
  524. // No open slots were found.
  525. // Get nick 1.
  526. pWO->pChat->GetNick( 1, &szNick, &szPass );
  527. // Save as nick 2.
  528. pWO->pChat->SetNick( 2, szNick, szPass, false ); // (Already mangled.)
  529. // Save new nick 1.
  530. return ( pWO->pChat->SetNick( 1, szNickToSave, szPassToSave, !bPassIsMangled ) == S_OK );
  531. }
  532. else
  533. {
  534. // iSlot points to an open slot.
  535. return ( pWO->pChat->SetNick( iSlot, szNickToSave, szPassToSave, !bPassIsMangled ) == S_OK );
  536. }
  537. */
  538. }
  539. //***********************************************************************************************
  540. void DeleteNick( WolapiObject* pWO, int iOneBasedEntryToDelete )
  541. {
  542. // Delete a nick from the registry via wolapi SetNick.
  543. // If nick to delete is in position one, and there is a second nick, move the second nick into position one.
  544. if( iOneBasedEntryToDelete == 1 )
  545. {
  546. // Check for nick 2.
  547. LPCSTR szNick;
  548. LPCSTR szPass;
  549. if( pWO->pChat->GetNick( 2, &szNick, &szPass ) == S_OK && *szNick != 0 )
  550. {
  551. // Copy nick in slot 2 to slot 1.
  552. pWO->pChat->SetNick( 1, szNick, szPass, false ); // (Already mangled.)
  553. // Delete slot 2.
  554. HRESULT hRes = pWO->pChat->SetNick( 2, "", "", false );
  555. DebugChatDef( hRes );
  556. }
  557. else
  558. {
  559. // No second nick.
  560. HRESULT hRes = pWO->pChat->SetNick( 1, "", "", false );
  561. DebugChatDef( hRes );
  562. }
  563. }
  564. else
  565. {
  566. HRESULT hRes = pWO->pChat->SetNick( 2, "", "", false );
  567. DebugChatDef( hRes );
  568. }
  569. }
  570. /*
  571. //***********************************************************************************************
  572. char* LoadShpFile( const char* szShpFile )
  573. {
  574. // Returns pointer to shp data that has been new'ed (and must be delete[]d), or NULL if failure.
  575. // ajw: No longer needed - I used this before putting new resources into a mix file.
  576. HANDLE hFile;
  577. hFile = CreateFile( szShpFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  578. if( hFile == INVALID_HANDLE_VALUE )
  579. return NULL;
  580. DWORD dwFileSize = GetFileSize( hFile, NULL );
  581. char* pShp = new char[ dwFileSize ];
  582. DWORD dwBytesRead;
  583. ReadFile( hFile, pShp, dwFileSize, &dwBytesRead, NULL );
  584. // debugprint( "~~ LoadShpFile() - Read %i bytes out of %i from shp file.\n", dwBytesRead, dwFileSize );
  585. CloseHandle( hFile );
  586. return pShp;
  587. }
  588. */
  589. #endif