UserPreferences.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /*
  2. ** Command & Conquer Generals(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. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. ///////////////////////////////////////////////////////////////////////////////////////
  24. // FILE: UserPreferences.cpp
  25. // Author: Matthew D. Campbell, April 2002
  26. // Description: Saving/Loading of user preferences
  27. ///////////////////////////////////////////////////////////////////////////////////////
  28. //-----------------------------------------------------------------------------
  29. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  30. //-----------------------------------------------------------------------------
  31. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  32. //-----------------------------------------------------------------------------
  33. // USER INCLUDES //////////////////////////////////////////////////////////////
  34. //-----------------------------------------------------------------------------
  35. #include "Common/GameSpyMiscPreferences.h"
  36. #include "Common/UserPreferences.h"
  37. #include "Common/LadderPreferences.h"
  38. #include "Common/Player.h"
  39. #include "Common/PlayerTemplate.h"
  40. #include "Common/Registry.h"
  41. #include "Common/QuickmatchPreferences.h"
  42. #include "Common/CustomMatchPreferences.h"
  43. #include "Common/IgnorePreferences.h"
  44. #include "Common/QuotedPrintable.h"
  45. #include "Common/MultiplayerSettings.h"
  46. #include "GameClient/MapUtil.h"
  47. #include "GameNetwork/GameSpy/PeerDefs.h"
  48. #ifdef _INTERNAL
  49. // for occasional debugging...
  50. //#pragma optimize("", off)
  51. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  52. #endif
  53. //-----------------------------------------------------------------------------
  54. // DEFINES ////////////////////////////////////////////////////////////////////
  55. //-----------------------------------------------------------------------------
  56. //-----------------------------------------------------------------------------
  57. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  58. //-----------------------------------------------------------------------------
  59. //-----------------------------------------------------------------------------
  60. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  61. //-----------------------------------------------------------------------------
  62. //-----------------------------------------------------------------------------
  63. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  64. //-----------------------------------------------------------------------------
  65. //-----------------------------------------------------------------------------
  66. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  67. //-----------------------------------------------------------------------------
  68. //-----------------------------------------------------------------------------
  69. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  70. //-----------------------------------------------------------------------------
  71. static AsciiString intAsStr(Int val)
  72. {
  73. AsciiString ret;
  74. ret.format("%d", val);
  75. return ret;
  76. }
  77. static AsciiString boolAsStr(Bool val)
  78. {
  79. AsciiString ret;
  80. ret.format("%d", val);
  81. return ret;
  82. }
  83. static AsciiString realAsStr(Real val)
  84. {
  85. AsciiString ret;
  86. ret.format("%g", val);
  87. return ret;
  88. }
  89. //-----------------------------------------------------------------------------
  90. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  91. //-----------------------------------------------------------------------------
  92. //-----------------------------------------------------------------------------
  93. // UserPreferences Class
  94. //-----------------------------------------------------------------------------
  95. UserPreferences::UserPreferences( void )
  96. {
  97. }
  98. UserPreferences::~UserPreferences( void )
  99. {
  100. }
  101. #define LINE_LEN 2048
  102. Bool UserPreferences::load(AsciiString fname)
  103. {
  104. // if (strstr(fname.str(), "\\"))
  105. // throw INI_INVALID_DATA; // must be a leaf name
  106. m_filename = TheGlobalData->getPath_UserData();
  107. m_filename.concat(fname);
  108. FILE *fp = fopen(m_filename.str(), "r");
  109. if (fp)
  110. {
  111. char buf[LINE_LEN];
  112. while( fgets( buf, LINE_LEN, fp ) != NULL )
  113. {
  114. AsciiString line = buf;
  115. line.trim();
  116. AsciiString key, val;
  117. line.nextToken(&key, "=");
  118. val = line.str() + 1;
  119. key.trim();
  120. val.trim();
  121. if (key.isEmpty() || val.isEmpty())
  122. continue;
  123. (*this)[key] = val;
  124. } // end while
  125. fclose(fp);
  126. return true;
  127. }
  128. return false;
  129. }
  130. Bool UserPreferences::write( void )
  131. {
  132. if (m_filename.isEmpty())
  133. return false;
  134. FILE *fp = fopen(m_filename.str(), "w");
  135. if (fp)
  136. {
  137. PreferenceMap::const_iterator it = begin();
  138. while (it != end())
  139. {
  140. fprintf(fp, "%s = %s\n", it->first.str(), it->second.str());
  141. ++it;
  142. }
  143. fclose(fp);
  144. return true;
  145. }
  146. return false;
  147. }
  148. Bool UserPreferences::getBool(AsciiString key, Bool defaultValue) const
  149. {
  150. AsciiString val = getAsciiString(key, AsciiString::TheEmptyString);
  151. if (val.isEmpty())
  152. {
  153. return defaultValue;
  154. }
  155. val.toLower();
  156. return (val == "1" || val == "t" || val == "true" || val == "y" || val == "yes" || val == "ok");
  157. }
  158. Real UserPreferences::getReal(AsciiString key, Real defaultValue) const
  159. {
  160. AsciiString val = getAsciiString(key, AsciiString::TheEmptyString);
  161. if (val.isEmpty())
  162. {
  163. return defaultValue;
  164. }
  165. return (Real)atof(val.str());
  166. }
  167. Int UserPreferences::getInt(AsciiString key, Int defaultValue) const
  168. {
  169. AsciiString val = getAsciiString(key, AsciiString::TheEmptyString);
  170. if (val.isEmpty())
  171. {
  172. return defaultValue;
  173. }
  174. return atoi(val.str());
  175. }
  176. AsciiString UserPreferences::getAsciiString(AsciiString key, AsciiString defaultValue) const
  177. {
  178. UserPreferences::const_iterator it = find(key);
  179. if (it == end())
  180. {
  181. return defaultValue;
  182. }
  183. return it->second;
  184. }
  185. void UserPreferences::setBool(AsciiString key, Bool val)
  186. {
  187. (*this)[key] = boolAsStr(val);
  188. }
  189. void UserPreferences::setReal(AsciiString key, Real val)
  190. {
  191. (*this)[key] = realAsStr(val);
  192. }
  193. void UserPreferences::setInt(AsciiString key, Int val)
  194. {
  195. (*this)[key] = intAsStr(val);
  196. }
  197. void UserPreferences::setAsciiString(AsciiString key, AsciiString val)
  198. {
  199. (*this)[key] = val;
  200. }
  201. //-----------------------------------------------------------------------------
  202. // QuickMatchPreferences base class
  203. //-----------------------------------------------------------------------------
  204. QuickMatchPreferences::QuickMatchPreferences()
  205. {
  206. AsciiString userPrefFilename;
  207. Int localProfile = TheGameSpyInfo->getLocalProfileID();
  208. userPrefFilename.format("GeneralsOnline\\QMPref%d.ini", localProfile);
  209. load(userPrefFilename);
  210. }
  211. QuickMatchPreferences::~QuickMatchPreferences()
  212. {
  213. }
  214. void QuickMatchPreferences::setMapSelected(const AsciiString& mapName, Bool selected)
  215. {
  216. (*this)[AsciiStringToQuotedPrintable(mapName)] = (selected)?"1":"0";
  217. }
  218. Bool QuickMatchPreferences::isMapSelected(const AsciiString& mapName)
  219. {
  220. Int ret;
  221. QuickMatchPreferences::const_iterator it = find(AsciiStringToQuotedPrintable(mapName));
  222. if (it == end())
  223. {
  224. return TRUE;
  225. }
  226. ret = atoi(it->second.str());
  227. return (ret != 0);
  228. }
  229. void QuickMatchPreferences::setLastLadder(const AsciiString& addr, UnsignedShort port)
  230. {
  231. AsciiString strVal;
  232. strVal.format("%d", port);
  233. (*this)["LastLadderAddr"] = addr;
  234. (*this)["LastLadderPort"] = strVal;
  235. }
  236. AsciiString QuickMatchPreferences::getLastLadderAddr( void )
  237. {
  238. QuickMatchPreferences::const_iterator it = find("LastLadderAddr");
  239. if (it == end())
  240. {
  241. return AsciiString::TheEmptyString;
  242. }
  243. return it->second;
  244. }
  245. UnsignedShort QuickMatchPreferences::getLastLadderPort( void )
  246. {
  247. QuickMatchPreferences::const_iterator it = find("LastLadderPort");
  248. if (it == end())
  249. {
  250. return 0;
  251. }
  252. return atoi(it->second.str());
  253. }
  254. void QuickMatchPreferences::setMaxDisconnects(Int val)
  255. {
  256. AsciiString strVal;
  257. strVal.format("%d", val);
  258. (*this)["MaxDisconnects"] = strVal;
  259. }
  260. Int QuickMatchPreferences::getMaxDisconnects( void )
  261. {
  262. QuickMatchPreferences::const_iterator it = find("MaxDisconnects");
  263. if (it == end())
  264. {
  265. return 0;
  266. }
  267. return atoi(it->second.str());
  268. }
  269. void QuickMatchPreferences::setMaxPoints(Int val)
  270. {
  271. AsciiString strVal;
  272. strVal.format("%d", val);
  273. (*this)["MaxPoints"] = strVal;
  274. }
  275. Int QuickMatchPreferences::getMaxPoints( void )
  276. {
  277. QuickMatchPreferences::const_iterator it = find("MaxPoints");
  278. if (it == end())
  279. {
  280. return 1000;
  281. }
  282. return atoi(it->second.str());
  283. }
  284. void QuickMatchPreferences::setMinPoints(Int val)
  285. {
  286. AsciiString strVal;
  287. strVal.format("%d", val);
  288. (*this)["MinPoints"] = strVal;
  289. }
  290. Int QuickMatchPreferences::getMinPoints( void )
  291. {
  292. QuickMatchPreferences::const_iterator it = find("MinPoints");
  293. if (it == end())
  294. {
  295. return 0;
  296. }
  297. return atoi(it->second.str());
  298. }
  299. void QuickMatchPreferences::setWaitTime(Int val)
  300. {
  301. AsciiString strVal;
  302. strVal.format("%d", val);
  303. (*this)["WaitTime"] = strVal;
  304. }
  305. Int QuickMatchPreferences::getWaitTime( void )
  306. {
  307. QuickMatchPreferences::const_iterator it = find("WaitTime");
  308. if (it == end())
  309. {
  310. return 0;
  311. }
  312. return atoi(it->second.str());
  313. }
  314. void QuickMatchPreferences::setNumPlayers(Int val)
  315. {
  316. AsciiString strVal;
  317. strVal.format("%d", val);
  318. (*this)["NumPlayers"] = strVal;
  319. }
  320. Int QuickMatchPreferences::getNumPlayers( void )
  321. {
  322. QuickMatchPreferences::const_iterator it = find("NumPlayers");
  323. if (it == end())
  324. {
  325. return 0; // first in list, 1v1
  326. }
  327. return atoi(it->second.str());
  328. }
  329. void QuickMatchPreferences::setMaxPing(Int val)
  330. {
  331. AsciiString strVal;
  332. strVal.format("%d", val);
  333. (*this)["MaxPing"] = strVal;
  334. }
  335. Int QuickMatchPreferences::getMaxPing( void )
  336. {
  337. QuickMatchPreferences::const_iterator it = find("MaxPing");
  338. if (it == end())
  339. {
  340. return 5;
  341. }
  342. return atoi(it->second.str());
  343. }
  344. void QuickMatchPreferences::setColor( Int val )
  345. {
  346. setInt("Color", val);
  347. }
  348. Int QuickMatchPreferences::getColor( void )
  349. {
  350. return getInt("Color", 0);
  351. }
  352. void QuickMatchPreferences::setSide( Int val )
  353. {
  354. setInt("Side", val);
  355. }
  356. Int QuickMatchPreferences::getSide( void )
  357. {
  358. return getInt("Side", 0);
  359. }
  360. //-----------------------------------------------------------------------------
  361. // CustomMatchPreferences base class
  362. //-----------------------------------------------------------------------------
  363. CustomMatchPreferences::CustomMatchPreferences()
  364. {
  365. AsciiString userPrefFilename;
  366. Int localProfile = TheGameSpyInfo->getLocalProfileID();
  367. userPrefFilename.format("GeneralsOnline\\CustomPref%d.ini", localProfile);
  368. load(userPrefFilename);
  369. }
  370. CustomMatchPreferences::~CustomMatchPreferences()
  371. {
  372. }
  373. void CustomMatchPreferences::setLastLadder(const AsciiString& addr, UnsignedShort port)
  374. {
  375. AsciiString strVal;
  376. strVal.format("%d", port);
  377. (*this)["LastLadderAddr"] = addr;
  378. (*this)["LastLadderPort"] = strVal;
  379. }
  380. AsciiString CustomMatchPreferences::getLastLadderAddr( void )
  381. {
  382. QuickMatchPreferences::const_iterator it = find("LastLadderAddr");
  383. if (it == end())
  384. {
  385. return AsciiString::TheEmptyString;
  386. }
  387. return it->second;
  388. }
  389. UnsignedShort CustomMatchPreferences::getLastLadderPort( void )
  390. {
  391. QuickMatchPreferences::const_iterator it = find("LastLadderPort");
  392. if (it == end())
  393. {
  394. return 0;
  395. }
  396. return atoi(it->second.str());
  397. }
  398. Int CustomMatchPreferences::getPreferredColor(void)
  399. {
  400. Int ret;
  401. CustomMatchPreferences::const_iterator it = find("Color");
  402. if (it == end())
  403. {
  404. return -1;
  405. }
  406. ret = atoi(it->second.str());
  407. if (ret < -1 || ret >= TheMultiplayerSettings->getNumColors())
  408. ret = -1;
  409. return ret;
  410. }
  411. void CustomMatchPreferences::setPreferredColor(Int val)
  412. {
  413. AsciiString s;
  414. s.format("%d", val);
  415. (*this)["Color"] = s;
  416. }
  417. Int CustomMatchPreferences::getChatSizeSlider(void)
  418. {
  419. Int ret;
  420. CustomMatchPreferences::const_iterator it = find("ChatSlider");
  421. if (it == end())
  422. {
  423. return 45;
  424. }
  425. ret = atoi(it->second.str());
  426. if (ret < 0 || ret > 100)
  427. ret = 45;
  428. return ret;
  429. }
  430. void CustomMatchPreferences::setChatSizeSlider(Int val)
  431. {
  432. AsciiString s;
  433. s.format("%d", val);
  434. (*this)["ChatSlider"] = s;
  435. }
  436. Int CustomMatchPreferences::getPreferredFaction(void)
  437. {
  438. Int ret;
  439. CustomMatchPreferences::const_iterator it = find("PlayerTemplate");
  440. if (it == end())
  441. {
  442. return PLAYERTEMPLATE_RANDOM;
  443. }
  444. ret = atoi(it->second.str());
  445. if (ret == PLAYERTEMPLATE_OBSERVER || ret < PLAYERTEMPLATE_MIN || ret >= ThePlayerTemplateStore->getPlayerTemplateCount())
  446. ret = PLAYERTEMPLATE_RANDOM;
  447. if (ret >= 0)
  448. {
  449. const PlayerTemplate *fac = ThePlayerTemplateStore->getNthPlayerTemplate(ret);
  450. if (!fac)
  451. ret = PLAYERTEMPLATE_RANDOM;
  452. else if (fac->getStartingBuilding().isEmpty())
  453. ret = PLAYERTEMPLATE_RANDOM;
  454. }
  455. return ret;
  456. }
  457. void CustomMatchPreferences::setPreferredFaction(Int val)
  458. {
  459. AsciiString s;
  460. s.format("%d", val);
  461. (*this)["PlayerTemplate"] = s;
  462. }
  463. Bool CustomMatchPreferences::usesSystemMapDir(void)
  464. {
  465. CustomMatchPreferences::const_iterator it = find("UseSystemMapDir");
  466. if (it == end())
  467. return TRUE;
  468. if (stricmp(it->second.str(), "1") == 0) {
  469. return TRUE;
  470. }
  471. return FALSE;
  472. }
  473. void CustomMatchPreferences::setUsesSystemMapDir(Bool val)
  474. {
  475. AsciiString s;
  476. s.format("%d", val);
  477. (*this)["UseSystemMapDir"] = s;
  478. }
  479. Bool CustomMatchPreferences::usesLongGameList(void)
  480. {
  481. return TRUE;
  482. CustomMatchPreferences::const_iterator it = find("UseLongGameList");
  483. if (it == end())
  484. return FALSE;
  485. if (stricmp(it->second.str(), "1") == 0) {
  486. return TRUE;
  487. }
  488. return FALSE;
  489. }
  490. void CustomMatchPreferences::setUsesLongGameList(Bool val)
  491. {
  492. AsciiString s;
  493. s.format("%d", val);
  494. (*this)["UseLongGameList"] = s;
  495. }
  496. Bool CustomMatchPreferences::allowsObservers(void)
  497. {
  498. CustomMatchPreferences::const_iterator it = find("AllowObservers");
  499. if (it == end())
  500. return TRUE;
  501. if (stricmp(it->second.str(), "1") == 0) {
  502. return TRUE;
  503. }
  504. return FALSE;
  505. }
  506. void CustomMatchPreferences::setAllowsObserver(Bool val)
  507. {
  508. AsciiString s;
  509. s.format("%d", val);
  510. (*this)["AllowObservers"] = s;
  511. }
  512. Bool CustomMatchPreferences::getDisallowAsianText( void )
  513. {
  514. CustomMatchPreferences::const_iterator it = find("DisallowAsianText");
  515. if (it == end())
  516. {
  517. // since English Win98 machines don't have a Unicode font installed by default,
  518. // we're forced to disable asian chat by default for English builds.
  519. if (GetRegistryLanguage().compareNoCase("chinese") == 0 || GetRegistryLanguage().compareNoCase("korean") == 0 )
  520. return FALSE;
  521. else
  522. return TRUE;
  523. }
  524. if (stricmp(it->second.str(), "1") == 0) {
  525. return TRUE;
  526. }
  527. return FALSE;
  528. }
  529. void CustomMatchPreferences::setDisallowAsianText(Bool val)
  530. {
  531. AsciiString s;
  532. s.format("%d", val);
  533. (*this)["DisallowAsianText"] = s;
  534. }
  535. Bool CustomMatchPreferences::getDisallowNonAsianText( void )
  536. {
  537. CustomMatchPreferences::const_iterator it = find("DisallowNonAsianText");
  538. if (it == end())
  539. return FALSE;
  540. if (stricmp(it->second.str(), "1") == 0) {
  541. return TRUE;
  542. }
  543. return FALSE;
  544. }
  545. void CustomMatchPreferences::setDisallowNonAsianText( Bool val )
  546. {
  547. AsciiString s;
  548. s.format("%d", val);
  549. (*this)["DisallowNonAsianText"] = s;
  550. }
  551. AsciiString CustomMatchPreferences::getPreferredMap(void)
  552. {
  553. AsciiString ret;
  554. CustomMatchPreferences::const_iterator it = find("Map");
  555. if (it == end())
  556. {
  557. ret = getDefaultMap(TRUE);
  558. return ret;
  559. }
  560. ret = QuotedPrintableToAsciiString(it->second);
  561. ret.trim();
  562. if (ret.isEmpty() || !isValidMap(ret, TRUE))
  563. {
  564. ret = getDefaultMap(TRUE);
  565. return ret;
  566. }
  567. return ret;
  568. }
  569. void CustomMatchPreferences::setPreferredMap(AsciiString val)
  570. {
  571. (*this)["Map"] = AsciiStringToQuotedPrintable(val);
  572. }
  573. //-----------------------------------------------------------------------------
  574. // GameSpyMiscPreferences base class
  575. //-----------------------------------------------------------------------------
  576. GameSpyMiscPreferences::GameSpyMiscPreferences()
  577. {
  578. AsciiString userPrefFilename;
  579. Int localProfile = TheGameSpyInfo->getLocalProfileID();
  580. userPrefFilename.format("GeneralsOnline\\GSMiscPref%d.ini", localProfile);
  581. load(userPrefFilename);
  582. }
  583. GameSpyMiscPreferences::~GameSpyMiscPreferences()
  584. {
  585. }
  586. Int GameSpyMiscPreferences::getLocale( void )
  587. {
  588. return getInt("Locale", 0);
  589. }
  590. void GameSpyMiscPreferences::setLocale( Int val )
  591. {
  592. setInt("Locale", val);
  593. }
  594. AsciiString GameSpyMiscPreferences::getCachedStats( void )
  595. {
  596. return getAsciiString("CachedStats", AsciiString::TheEmptyString);
  597. }
  598. void GameSpyMiscPreferences::setCachedStats( AsciiString val )
  599. {
  600. setAsciiString("CachedStats", val);
  601. }
  602. Bool GameSpyMiscPreferences::getQuickMatchResLocked( void )
  603. {
  604. return getBool("QMResLock", FALSE);
  605. }
  606. Int GameSpyMiscPreferences::getMaxMessagesPerUpdate( void )
  607. {
  608. return getInt("MaxMessagesPerUpdate", 100);
  609. }
  610. //-----------------------------------------------------------------------------
  611. // IgnorePreferences base class
  612. //-----------------------------------------------------------------------------
  613. IgnorePreferences::IgnorePreferences()
  614. {
  615. AsciiString userPrefFilename;
  616. // if(!TheGameSpyInfo)
  617. Int localProfile = TheGameSpyInfo->getLocalProfileID();
  618. userPrefFilename.format("GeneralsOnline\\IgnorePref%d.ini", localProfile);
  619. load(userPrefFilename);
  620. }
  621. IgnorePreferences::~IgnorePreferences()
  622. {
  623. }
  624. void IgnorePreferences::setIgnore(const AsciiString& userName, Int profileID, Bool ignore)
  625. {
  626. AsciiString strVal;
  627. strVal.format("%d", profileID);
  628. if (ignore)
  629. {
  630. (*this)[strVal] = userName;
  631. }
  632. else
  633. {
  634. erase(strVal);
  635. }
  636. }
  637. IgnorePrefMap IgnorePreferences::getIgnores(void)
  638. {
  639. IgnorePrefMap ignores;
  640. IgnorePreferences::iterator it;
  641. for (it = begin(); it != end(); ++it)
  642. {
  643. AsciiString profileStr = it->first;
  644. AsciiString lastLoginStr = it->second;
  645. Int profileID = atoi(profileStr.str());
  646. ignores[profileID] = lastLoginStr;
  647. }
  648. return ignores;
  649. }
  650. //-----------------------------------------------------------------------------
  651. // LadderPreferences base class
  652. //-----------------------------------------------------------------------------
  653. LadderPreferences::LadderPreferences()
  654. {
  655. }
  656. LadderPreferences::~LadderPreferences()
  657. {
  658. }
  659. Bool LadderPreferences::loadProfile( Int profileID )
  660. {
  661. clear();
  662. m_ladders.clear();
  663. AsciiString userPrefFilename;
  664. userPrefFilename.format("GeneralsOnline\\Ladders%d.ini", profileID);
  665. Bool success = load(userPrefFilename);
  666. if (!success)
  667. return success;
  668. // parse out our ladders
  669. for (LadderPreferences::iterator it = begin(); it != end(); ++it)
  670. {
  671. LadderPref p;
  672. AsciiString ladName = it->first;
  673. AsciiString ladData = it->second;
  674. DEBUG_LOG(("Looking at [%s] = [%s]\n", ladName.str(), ladData.str()));
  675. const char *ptr = ladName.reverseFind(':');
  676. DEBUG_ASSERTCRASH(ptr, ("Did not find ':' in ladder name - skipping"));
  677. if (!ptr)
  678. continue;
  679. p.port = atoi( ptr + 1 );
  680. for (Int i=0; i<strlen(ptr); ++i)
  681. {
  682. ladName.removeLastChar();
  683. }
  684. p.address = QuotedPrintableToAsciiString(ladName);
  685. ptr = ladData.reverseFind(':');
  686. DEBUG_ASSERTCRASH(ptr, ("Did not find ':' in ladder data - skipping"));
  687. if (!ptr)
  688. continue;
  689. p.lastPlayDate = atoi( ptr + 1 );
  690. for (i=0; i<strlen(ptr); ++i)
  691. {
  692. ladData.removeLastChar();
  693. }
  694. p.name = QuotedPrintableToUnicodeString(ladData);
  695. m_ladders[p.lastPlayDate] = p;
  696. }
  697. return true;
  698. }
  699. bool LadderPreferences::write( void )
  700. {
  701. clear();
  702. LadderPrefMap::iterator lpIt;
  703. static const Int MAX_LADDERS = 5;
  704. Int count;
  705. for (lpIt = m_ladders.begin(), count=0; lpIt != m_ladders.end() && count<MAX_LADDERS; ++lpIt, ++count)
  706. {
  707. LadderPref p = lpIt->second;
  708. AsciiString ladName;
  709. AsciiString ladData;
  710. ladName.format("%s:%d", AsciiStringToQuotedPrintable(p.address).str(), p.port);
  711. ladData.format("%s:%d", UnicodeStringToQuotedPrintable(p.name).str(), p.lastPlayDate);
  712. (*this)[ladName] = ladData;
  713. }
  714. return UserPreferences::write();
  715. }
  716. const LadderPrefMap& LadderPreferences::getRecentLadders( void )
  717. {
  718. return m_ladders;
  719. }
  720. void LadderPreferences::addRecentLadder( LadderPref ladder )
  721. {
  722. for (LadderPrefMap::iterator it = m_ladders.begin(); it != m_ladders.end(); ++it)
  723. {
  724. if (it->second == ladder)
  725. {
  726. m_ladders.erase(it);
  727. break;
  728. }
  729. }
  730. m_ladders[ladder.lastPlayDate] = ladder;
  731. }