WOLLoginInfo.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  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. *
  20. * FILE
  21. * $Archive: /Commando/Code/WWOnline/WOLLoginInfo.cpp $
  22. *
  23. * DESCRIPTION
  24. * LoginInfo encapsulates a user's persona login information.
  25. * LoginInfo handles the storage/retrival of nicknames/passwords also.
  26. *
  27. * PROGRAMMER
  28. * $Author: Denzil_l $
  29. *
  30. * VERSION INFO
  31. * $Revision: 15 $
  32. * $Modtime: 1/18/02 11:50p $
  33. *
  34. ******************************************************************************/
  35. #include <atlbase.h>
  36. #include "WOLLoginInfo.h"
  37. #include "WOLSession.h"
  38. #include <WWLib\WWString.h>
  39. #include <WWDebug\WWDebug.h>
  40. namespace WOL
  41. {
  42. #include <WOLAPI\wolapi.h>
  43. }
  44. namespace WWOnline {
  45. #define MAX_NICKNAMES 32
  46. LoginInfoList LoginInfo::_mLoginList;
  47. /******************************************************************************
  48. *
  49. * NAME
  50. * LoginInfo::GetList
  51. *
  52. * DESCRIPTION
  53. * Get a list of all the cached WWOnline logins.
  54. *
  55. * INPUTS
  56. * NONE
  57. *
  58. * RESULT
  59. * LoginList - List to populate with WWOnline logins.
  60. *
  61. ******************************************************************************/
  62. const LoginInfoList& LoginInfo::GetList(void)
  63. {
  64. if (_mLoginList.empty())
  65. {
  66. RefPtr<Session> session = Session::GetInstance(false);
  67. if (session.IsValid() && session->IsStoreLoginAllowed())
  68. {
  69. // Four logins allowed per user
  70. _mLoginList.reserve(4);
  71. const CComPtr<WOL::IChat>& chat = session->GetChatObject();
  72. for (int index = 1; index <= MAX_NICKNAMES; ++index)
  73. {
  74. const char* nickname = NULL;
  75. const char* password = NULL;
  76. chat->GetNick(index, &nickname, &password);
  77. if (nickname && (strlen(nickname) > 0))
  78. {
  79. RefPtr<LoginInfo> login = Create(nickname, password, true);
  80. if (login.IsValid())
  81. {
  82. WOL::Locale locale = WOL::LOC_UNKNOWN;
  83. chat->GetNickLocale(index, &locale);
  84. login->SetLocale(locale);
  85. login->mIsStored = true;
  86. _mLoginList.push_back(login);
  87. }
  88. }
  89. }
  90. }
  91. }
  92. return _mLoginList;
  93. }
  94. /******************************************************************************
  95. *
  96. * NAME
  97. * LoginInfo::ClearList
  98. *
  99. * DESCRIPTION
  100. *
  101. * INPUTS
  102. * NONE
  103. *
  104. * RESULT
  105. * NONE
  106. *
  107. ******************************************************************************/
  108. void LoginInfo::ClearList(void)
  109. {
  110. _mLoginList.clear();
  111. }
  112. /******************************************************************************
  113. *
  114. * NAME
  115. * LoginInfo::Find
  116. *
  117. * DESCRIPTION
  118. * Search for a login with a specified nickname.
  119. *
  120. * INPUTS
  121. * Nickname - Nickname of login to search for.
  122. *
  123. * RESULT
  124. * Login - Login matching specified name; if available.
  125. *
  126. ******************************************************************************/
  127. RefPtr<LoginInfo> LoginInfo::Find(const wchar_t* name)
  128. {
  129. if (name)
  130. {
  131. const LoginInfoList& list = GetList();
  132. const unsigned int count = list.size();
  133. for (unsigned int index = 0; index < count; ++index)
  134. {
  135. RefPtr<LoginInfo> login = list[index];
  136. WWASSERT(login.IsValid());
  137. const WideStringClass& nickname = login->GetNickname();
  138. if (nickname.Compare_No_Case(name) == 0)
  139. {
  140. return login;
  141. }
  142. }
  143. }
  144. return NULL;
  145. }
  146. RefPtr<LoginInfo> LoginInfo::Find(const char* nickname)
  147. {
  148. WideStringClass wideNickname(0, true);
  149. wideNickname = nickname;
  150. return Find(wideNickname);
  151. }
  152. /******************************************************************************
  153. *
  154. * NAME
  155. * LoginInfo::Create
  156. *
  157. * DESCRIPTION
  158. * Create a login info instance
  159. *
  160. * INPUTS
  161. * Nickname - Login username
  162. * Password - Login password
  163. * IsEncrypted - True if the password is encrypted.
  164. *
  165. * RESULT
  166. * LoginInfo - Instance of newly created login information.
  167. *
  168. ******************************************************************************/
  169. RefPtr<LoginInfo> LoginInfo::Create(const wchar_t* nickname, const wchar_t* password, bool isEncrypted)
  170. {
  171. if (nickname && (wcslen(nickname) > 0))
  172. {
  173. return new LoginInfo(nickname, password, isEncrypted);
  174. }
  175. return NULL;
  176. }
  177. RefPtr<LoginInfo> LoginInfo::Create(const char* nickname, const char* password, bool isEncrypted)
  178. {
  179. if (nickname && (strlen(nickname) > 0))
  180. {
  181. WideStringClass name(0, true);
  182. name = nickname;
  183. WideStringClass pass(0, true);
  184. pass = password;
  185. return new LoginInfo(name, pass, isEncrypted);
  186. }
  187. return NULL;
  188. }
  189. /******************************************************************************
  190. *
  191. * NAME
  192. * LoginInfo::LoginInfo
  193. *
  194. * DESCRIPTION
  195. * Constructor
  196. *
  197. * INPUTS
  198. * Nickname - Login username
  199. * Password - Login password
  200. * IsEncrypted - True if the password is encrypted.
  201. *
  202. * RESULT
  203. * NONE
  204. *
  205. ******************************************************************************/
  206. LoginInfo::LoginInfo(const wchar_t* nickname, const wchar_t* password, bool isEncrypted) :
  207. mNickname(nickname),
  208. mPassword(password),
  209. mLocale(WOL::LOC_UNKNOWN),
  210. mIsPasswordEncrypted(isEncrypted),
  211. mIsStored(false)
  212. {
  213. WWDEBUG_SAY(("WOL: Instantiating LoginInfo %S\n", (const WCHAR*)mNickname));
  214. if (mNickname.Get_Length() > 9)
  215. {
  216. mNickname[9] = 0;
  217. }
  218. }
  219. /******************************************************************************
  220. *
  221. * NAME
  222. * LoginInfo::~LoginInfo
  223. *
  224. * DESCRIPTION
  225. * Destructor
  226. *
  227. * INPUTS
  228. *
  229. * RESULT
  230. *
  231. ******************************************************************************/
  232. LoginInfo::~LoginInfo()
  233. {
  234. WWDEBUG_SAY(("WOL: Destructing LoginInfo %S\n", (const WCHAR*)mNickname));
  235. }
  236. /******************************************************************************
  237. *
  238. * NAME
  239. * LoginInfo::SetPassword
  240. *
  241. * DESCRIPTION
  242. * Set the password for this login.
  243. *
  244. * INPUTS
  245. * Password - New password
  246. * Encrypted - True if password is encrypted.
  247. *
  248. * RESULT
  249. * NONE
  250. *
  251. ******************************************************************************/
  252. void LoginInfo::SetPassword(const wchar_t* password, bool isEncrypted)
  253. {
  254. if (password != NULL)
  255. {
  256. mPassword = password;
  257. mIsPasswordEncrypted = isEncrypted;
  258. }
  259. else
  260. {
  261. mPassword = L"";
  262. mIsPasswordEncrypted = false;
  263. }
  264. }
  265. /******************************************************************************
  266. *
  267. * NAME
  268. * LoginInfo::SetLocale
  269. *
  270. * DESCRIPTION
  271. * Set the locale for this login.
  272. *
  273. * INPUTS
  274. * Locale - New locale.
  275. *
  276. * RESULT
  277. * NONE
  278. *
  279. ******************************************************************************/
  280. void LoginInfo::SetLocale(WOL::Locale locale)
  281. {
  282. mLocale = locale;
  283. int index = IndexOf();
  284. if (index != 0)
  285. {
  286. RefPtr<Session> session = Session::GetInstance(false);
  287. if (session.IsValid() && session->IsStoreLoginAllowed())
  288. {
  289. const CComPtr<WOL::IChat>& chat = session->GetChatObject();
  290. WWASSERT(chat);
  291. chat->SetNickLocale(index, locale);
  292. }
  293. }
  294. }
  295. /******************************************************************************
  296. *
  297. * NAME
  298. * LoginInfo::GetLocale
  299. *
  300. * DESCRIPTION
  301. * Returns the current locale for this login.
  302. *
  303. * INPUTS
  304. * NONE
  305. *
  306. * RESULT
  307. * Locale - Locale for this login.
  308. *
  309. ******************************************************************************/
  310. WOL::Locale LoginInfo::GetLocale(void)
  311. {
  312. if (mLocale == WOL::LOC_UNKNOWN)
  313. {
  314. int index = IndexOf();
  315. if (index != 0)
  316. {
  317. RefPtr<Session> session = Session::GetInstance(false);
  318. if (session.IsValid())
  319. {
  320. const CComPtr<WOL::IChat>& chat = session->GetChatObject();
  321. WWASSERT(chat);
  322. chat->GetNickLocale(index, &mLocale);
  323. }
  324. }
  325. }
  326. return mLocale;
  327. }
  328. /******************************************************************************
  329. *
  330. * NAME
  331. * LoginInfo::Remember
  332. *
  333. * DESCRIPTION
  334. * Remember this login. If the store flag is true then the login is written
  335. * to disk for retrieval in later sessions.
  336. *
  337. * INPUTS
  338. * Store - True to store this login to the disk.
  339. *
  340. * RESULT
  341. * NONE
  342. *
  343. ******************************************************************************/
  344. void LoginInfo::Remember(bool store)
  345. {
  346. if (store)
  347. {
  348. mIsStored = true;
  349. int index = IndexOf();
  350. if (index == 0)
  351. {
  352. StringClass name(64, true);
  353. mNickname.Convert_To(name);
  354. StringClass pass(64, true);
  355. mPassword.Convert_To(pass);
  356. // Store login information into the registry
  357. StoreLogin(name.Peek_Buffer(), pass.Peek_Buffer(), mIsPasswordEncrypted, mLocale);
  358. }
  359. }
  360. // If the login is not in the list then add it now.
  361. bool found = false;
  362. LoginInfoList::iterator iter = _mLoginList.begin();
  363. while (iter != _mLoginList.end())
  364. {
  365. if (iter->ReferencedObject() == this)
  366. {
  367. found = true;
  368. break;
  369. }
  370. iter++;
  371. }
  372. if (!found)
  373. {
  374. _mLoginList.push_back(this);
  375. }
  376. }
  377. /******************************************************************************
  378. *
  379. * NAME
  380. * LoginInfo::Forget
  381. *
  382. * DESCRIPTION
  383. * Forget about this login. If the purge flag is true then the login
  384. * is deleted from disk.
  385. *
  386. * INPUTS
  387. * Purge - True to purge this login from the disk.
  388. *
  389. * RESULT
  390. * NONE
  391. *
  392. ******************************************************************************/
  393. void LoginInfo::Forget(bool purge)
  394. {
  395. if (purge)
  396. {
  397. mIsStored = false;
  398. // Remove login for the persist cache
  399. RefPtr<Session> session = Session::GetInstance(false);
  400. if (session.IsValid() && session->IsStoreLoginAllowed())
  401. {
  402. int index = IndexOf();
  403. if (index != 0)
  404. {
  405. const CComPtr<WOL::IChat>& chat = session->GetChatObject();
  406. chat->SetNick(index, "", "", false);
  407. chat->SetNickLocale(index, WOL::LOC_UNKNOWN);
  408. }
  409. }
  410. }
  411. // Remove login from the list
  412. LoginInfoList::iterator iter = _mLoginList.begin();
  413. while (iter != _mLoginList.end())
  414. {
  415. if (iter->ReferencedObject() == this)
  416. {
  417. _mLoginList.erase(iter);
  418. break;
  419. }
  420. iter++;
  421. }
  422. }
  423. /******************************************************************************
  424. *
  425. * NAME
  426. * LoginInfo::IndexOf
  427. *
  428. * DESCRIPTION
  429. *
  430. * INPUTS
  431. *
  432. * RESULT
  433. *
  434. ******************************************************************************/
  435. int LoginInfo::IndexOf(const wchar_t* nick)
  436. {
  437. RefPtr<Session> session = Session::GetInstance(false);
  438. if (session.IsValid())
  439. {
  440. char username[64];
  441. wcstombs(username, nick, sizeof(username));
  442. const CComPtr<WOL::IChat>& chat = session->GetChatObject();
  443. for (int index = 1; index <= MAX_NICKNAMES; ++index)
  444. {
  445. const char* nickname = NULL;
  446. const char* password = NULL;
  447. HRESULT result = chat->GetNick(index, &nickname, &password);
  448. if (SUCCEEDED(result))
  449. {
  450. if (nickname && (strlen(nickname) > 0) && (stricmp(username, nickname) == 0))
  451. {
  452. return index;
  453. }
  454. }
  455. }
  456. }
  457. return 0;
  458. }
  459. /******************************************************************************
  460. *
  461. * NAME
  462. * LoginInfo::IndexOf
  463. *
  464. * DESCRIPTION
  465. *
  466. * INPUTS
  467. * NONE
  468. *
  469. * RESULT
  470. * Index -
  471. *
  472. ******************************************************************************/
  473. int LoginInfo::IndexOf(void) const
  474. {
  475. return IndexOf(mNickname);
  476. }
  477. /******************************************************************************
  478. *
  479. * NAME
  480. * LoginInfo::StoreLogin
  481. *
  482. * DESCRIPTION
  483. * Store login information.
  484. *
  485. * INPUTS
  486. * Nickname - Login nickname
  487. * Password - Login password
  488. * IsPassEncrytped - True if the password is already encrypted.
  489. *
  490. * RESULT
  491. * NONE
  492. *
  493. ******************************************************************************/
  494. void LoginInfo::StoreLogin(const char* nickname, const char* password,
  495. bool isPasswordEncrypted, WOL::Locale locale)
  496. {
  497. RefPtr<Session> session = Session::GetInstance(false);
  498. if (session.IsValid() && session->IsStoreLoginAllowed())
  499. {
  500. const CComPtr<WOL::IChat>& chat = session->GetChatObject();
  501. // Find the next empty slot
  502. for (int index = 1; index <= MAX_NICKNAMES; ++index)
  503. {
  504. const char* slotNick = NULL;
  505. const char* slotPass = NULL;
  506. chat->GetNick(index, &slotNick, &slotPass);
  507. if ((slotNick == NULL) || strlen(slotNick) == 0)
  508. {
  509. break;
  510. }
  511. }
  512. if (index > MAX_NICKNAMES)
  513. {
  514. // All slots taken! Kill the last one
  515. index = MAX_NICKNAMES;
  516. }
  517. chat->SetNick(index, nickname, password, !isPasswordEncrypted);
  518. chat->SetNickLocale(index, locale);
  519. }
  520. }
  521. } // namespace WWOnline