WOLBuddyMgr.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496
  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/Commando/WOLBuddyMgr.cpp $
  22. *
  23. * DESCRIPTION
  24. *
  25. * PROGRAMMER
  26. * Denzil E. Long, Jr.
  27. * $Author: Steve_t $
  28. *
  29. * VERSION INFO
  30. * $Revision: 40 $
  31. * $Modtime: 8/28/02 12:59p $
  32. *
  33. ******************************************************************************/
  34. #include "WOLBuddyMgr.h"
  35. #include "_globals.h"
  36. #include "GameInitMgr.h"
  37. #include "MPSettingsMgr.h"
  38. #include "DlgMPWolInvitation.h"
  39. #include "DlgMPWolPageReply.h"
  40. #include "DlgMessageBox.h"
  41. #include "DlgPasswordPrompt.h"
  42. #include "DlgMPWolChat.h"
  43. #include "WOLChatMgr.h"
  44. #include "WOLJoinGame.h"
  45. #include "WOLGameInfo.h"
  46. #include "consolemode.h"
  47. #include <WWOnline\WOLChannel.h>
  48. #include <WWOnline\WOLProduct.h>
  49. #include <WWLib\Registry.h>
  50. #include "String_IDs.h"
  51. #include <WWTranslateDB\TranslateDB.h>
  52. #include <WWDebug\WWDebug.h>
  53. using namespace WWOnline;
  54. static const int MAX_USERNAME_LEN = 64;
  55. static const WCHAR INVITE_CMD[] = L"<WWINVITE>";
  56. static const WCHAR DECLINE_CMD[] = L"<WWDECLINE>";
  57. static const unsigned long INVITE_CMD_LEN = ((sizeof(INVITE_CMD) / sizeof(WCHAR)) - 1);
  58. static const unsigned long DECLINE_CMD_LEN = ((sizeof(DECLINE_CMD) / sizeof(WCHAR)) - 1);
  59. WOLBuddyMgr* WOLBuddyMgr::_mInstance = NULL;
  60. /******************************************************************************
  61. *
  62. * NAME
  63. * WOLBuddyMgr::GetInstance
  64. *
  65. * DESCRIPTION
  66. * Obtain Buddy manager instance
  67. *
  68. * INPUTS
  69. * Create - Okay to create buddy manager if not already instantiated.
  70. *
  71. * RESULT
  72. * Instance -
  73. *
  74. ******************************************************************************/
  75. WOLBuddyMgr* WOLBuddyMgr::GetInstance(bool createOK)
  76. {
  77. if (_mInstance == NULL)
  78. {
  79. new WOLBuddyMgr;
  80. if (_mInstance)
  81. {
  82. if (_mInstance->FinalizeCreate() == false)
  83. {
  84. _mInstance->Release_Ref();
  85. }
  86. }
  87. }
  88. else
  89. {
  90. _mInstance->Add_Ref();
  91. }
  92. return _mInstance;
  93. }
  94. /******************************************************************************
  95. *
  96. * NAME
  97. * WOLBuddyMgr::WOLBuddyMgr
  98. *
  99. * DESCRIPTION
  100. * Constructor
  101. *
  102. * INPUTS
  103. * NONE
  104. *
  105. * RESULT
  106. * NONE
  107. *
  108. ******************************************************************************/
  109. WOLBuddyMgr::WOLBuddyMgr() :
  110. mHidePagedDialog(0)
  111. {
  112. WWDEBUG_SAY(("WOLBuddyMgr: Instantiated\n"));
  113. _mInstance = this;
  114. }
  115. /******************************************************************************
  116. *
  117. * NAME
  118. * WOLBuddyMgr::~WOLBuddyMgr
  119. *
  120. * DESCRIPTION
  121. * Destructor
  122. *
  123. * INPUTS
  124. * NONE
  125. *
  126. * RESULT
  127. * NONE
  128. *
  129. ******************************************************************************/
  130. WOLBuddyMgr::~WOLBuddyMgr()
  131. {
  132. WWDEBUG_SAY(("WOLBuddyMgr: Destroyed\n"));
  133. _mInstance = NULL;
  134. }
  135. /******************************************************************************
  136. *
  137. * NAME
  138. * WOLBuddyMgr::FinalizeCreate
  139. *
  140. * DESCRIPTION
  141. * Perform post creation initialization.
  142. *
  143. * INPUTS
  144. * NONE
  145. *
  146. * RESULT
  147. * True if successful
  148. *
  149. ******************************************************************************/
  150. bool WOLBuddyMgr::FinalizeCreate(void)
  151. {
  152. mWOLSession = Session::GetInstance(false);
  153. if (!mWOLSession.IsValid())
  154. {
  155. return false;
  156. }
  157. Observer<BuddyEvent>::NotifyMe(*mWOLSession);
  158. Observer<UserEvent>::NotifyMe(*mWOLSession);
  159. Observer<PageMessage>::NotifyMe(*mWOLSession);
  160. Observer<PageSendStatus>::NotifyMe(*mWOLSession);
  161. LoadIgnoreList();
  162. return true;
  163. }
  164. /******************************************************************************
  165. *
  166. * NAME
  167. * WOLBuddyMgr::LoadIgnoreList
  168. *
  169. * DESCRIPTION
  170. * Load the list of users to ignore.
  171. *
  172. * INPUTS
  173. * NONE
  174. *
  175. * RESULT
  176. * NONE
  177. *
  178. ******************************************************************************/
  179. void WOLBuddyMgr::LoadIgnoreList(void)
  180. {
  181. mIgnoreList.clear();
  182. HKEY hKey;
  183. LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, APPLICATION_SUB_KEY_NAME_IGNORE_LIST, 0, KEY_READ, &hKey);
  184. if (ERROR_SUCCESS == result)
  185. {
  186. // Build a list of users to ignore
  187. char valueName[128];
  188. unsigned long valueSize = sizeof(valueName);
  189. int index = 0;
  190. while (RegEnumValue(hKey, index, valueName, &valueSize, 0, NULL, NULL, NULL) == ERROR_SUCCESS)
  191. {
  192. DWORD type = 0;
  193. char name[MAX_USERNAME_LEN];
  194. DWORD nameSize = sizeof(name);
  195. result = RegQueryValueEx(hKey, valueName, NULL, &type, (LPBYTE)name, (DWORD*)&nameSize);
  196. if ((ERROR_SUCCESS == result) && (REG_SZ == type) && strlen(name))
  197. {
  198. // Add the name to the ignore list
  199. WideStringClass wideName(name);
  200. mIgnoreList.push_back(wideName);
  201. }
  202. index++;
  203. valueSize = sizeof(valueName);
  204. }
  205. RegCloseKey(hKey);
  206. }
  207. Add_Ref();
  208. WOLBuddyMgrEvent event(IGNORELIST_CHANGED, this);
  209. NotifyObservers(event);
  210. Release_Ref();
  211. }
  212. /******************************************************************************
  213. *
  214. * NAME
  215. * WOLBuddyMgr::SaveIgnoreList
  216. *
  217. * DESCRIPTION
  218. * Save the list of users to ignore.
  219. *
  220. * INPUTS
  221. * NONE
  222. *
  223. * RESULT
  224. * NONE
  225. *
  226. ******************************************************************************/
  227. void WOLBuddyMgr::SaveIgnoreList(void)
  228. {
  229. if (mWOLSession->IsStoreLoginAllowed())
  230. {
  231. RegistryClass reg(APPLICATION_SUB_KEY_NAME_IGNORE_LIST);
  232. if (reg.Is_Valid())
  233. {
  234. reg.Deleta_All_Values();
  235. for (unsigned int index = 0; index < mIgnoreList.size(); ++index)
  236. {
  237. char valueName[64];
  238. sprintf(valueName, "Ignore%d", (index + 1));
  239. const WideStringClass& buddy = mIgnoreList[index];
  240. char name[MAX_USERNAME_LEN];
  241. wcstombs(name, buddy, sizeof(name));
  242. reg.Set_String(valueName, (char*)name);
  243. }
  244. }
  245. }
  246. }
  247. /******************************************************************************
  248. *
  249. * NAME
  250. * WOLBuddyMgr::RefreshBuddyList
  251. *
  252. * DESCRIPTION
  253. * Request the buddy list for the current login.
  254. *
  255. * INPUTS
  256. * NONE
  257. *
  258. * RESULT
  259. * NONE
  260. *
  261. ******************************************************************************/
  262. void WOLBuddyMgr::RefreshBuddyList(void)
  263. {
  264. mWOLSession->RequestBuddyList();
  265. }
  266. /******************************************************************************
  267. *
  268. * NAME
  269. * WOLBuddyMgr::FindBuddy
  270. *
  271. * DESCRIPTION
  272. * Find a user in our buddy list.
  273. *
  274. * INPUTS
  275. * Name - Nickname of buddy to find.
  276. *
  277. * RESULT
  278. * NONE
  279. *
  280. ******************************************************************************/
  281. const RefPtr<WWOnline::UserData> WOLBuddyMgr::FindBuddy(const WCHAR* name) const
  282. {
  283. return mWOLSession->FindBuddy(name);
  284. }
  285. /******************************************************************************
  286. *
  287. * NAME
  288. * WOLBuddyMgr::AddBuddy
  289. *
  290. * DESCRIPTION
  291. * Add a user to our buddy list.
  292. *
  293. * INPUTS
  294. * Name - Nickname of user to add.
  295. *
  296. * RESULT
  297. * NONE
  298. *
  299. ******************************************************************************/
  300. void WOLBuddyMgr::AddBuddy(const WCHAR* name)
  301. {
  302. if (IsBuddy(name) == false)
  303. {
  304. mWOLSession->AddBuddy(name);
  305. }
  306. }
  307. /******************************************************************************
  308. *
  309. * NAME
  310. * WOLBuddyMgr::RemoveBuddy
  311. *
  312. * DESCRIPTION
  313. * Remove a user from our buddy list.
  314. *
  315. * INPUTS
  316. * Name - Nickname of user to remove.
  317. *
  318. * RESULT
  319. * NONE
  320. *
  321. ******************************************************************************/
  322. void WOLBuddyMgr::RemoveBuddy(const WCHAR* name)
  323. {
  324. mWOLSession->RemoveBuddy(name);
  325. }
  326. /******************************************************************************
  327. *
  328. * NAME
  329. * WOLBuddyMgr::IsBuddy
  330. *
  331. * DESCRIPTION
  332. * Check if a user is our buddy.
  333. *
  334. * INPUTS
  335. * Name - Nickname of user to check.
  336. *
  337. * RESULT
  338. * True if user is in our buddy list.
  339. *
  340. ******************************************************************************/
  341. bool WOLBuddyMgr::IsBuddy(const WCHAR* name) const
  342. {
  343. RefPtr<UserData> user = mWOLSession->FindBuddy(name);
  344. return user.IsValid();
  345. }
  346. /******************************************************************************
  347. *
  348. * NAME
  349. * WOLBuddyMgr::RefreshBuddyInfo
  350. *
  351. * DESCRIPTION
  352. * Update the locations / status of our buddies.
  353. *
  354. * INPUTS
  355. * NONE
  356. *
  357. * RESULT
  358. * NONE
  359. *
  360. ******************************************************************************/
  361. void WOLBuddyMgr::RefreshBuddyInfo(void)
  362. {
  363. const UserList& buddies = mWOLSession->GetBuddyList();
  364. const unsigned int count = buddies.size();
  365. for (unsigned int index = 0; index < count; ++index)
  366. {
  367. const RefPtr<UserData>& buddy = buddies[index];
  368. mWOLSession->RequestLocateUser(buddy);
  369. if (!buddy->GetTeamLadder().IsValid())
  370. {
  371. mWOLSession->RequestLadderInfo(buddy->GetName(), LadderType_Team);
  372. }
  373. RefPtr<SquadData> squad = buddy->GetSquad();
  374. if (squad.IsValid())
  375. {
  376. WideStringClass abbr(0, true);
  377. abbr = squad->GetAbbr();
  378. mWOLSession->RequestLadderInfo((const WCHAR*)abbr, LadderType_Clan);
  379. }
  380. }
  381. }
  382. /******************************************************************************
  383. *
  384. * NAME
  385. * WOLBuddyMgr::GetBuddyLocationDescription
  386. *
  387. * DESCRIPTION
  388. * Get a text description of where our buddy is located.
  389. *
  390. * INPUTS
  391. * User - User to get description for.
  392. * Description - String to receice description text.
  393. *
  394. * RESULT
  395. * NONE
  396. *
  397. ******************************************************************************/
  398. void WOLBuddyMgr::GetLocationDescription(const RefPtr<UserData>& user, WideStringClass& description)
  399. {
  400. description = TRANSLATE(IDS_MP_WOL_BUDDY_UNKNOWN);
  401. if (user.IsValid())
  402. {
  403. // Where is this user?
  404. switch (user->GetLocation())
  405. {
  406. default:
  407. case USERLOCATION_UNKNOWN:
  408. description = TRANSLATE(IDS_MP_WOL_BUDDY_UNKNOWN);
  409. break;
  410. case USERLOCATION_OFFLINE:
  411. description = TRANSLATE(IDS_MP_WOL_BUDDY_OFFLINE);
  412. break;
  413. case USERLOCATION_HIDING:
  414. description = TRANSLATE(IDS_MP_WOL_BUDDY_HIDING);
  415. break;
  416. case USERLOCATION_NO_CHANNEL:
  417. description = TRANSLATE(IDS_MP_WOL_BUDDY_NO_CHANNEL);
  418. break;
  419. case USERLOCATION_IN_CHANNEL:
  420. {
  421. const RefPtr<ChannelData>& channel = user->GetChannel();
  422. if (channel.IsValid())
  423. {
  424. WideStringClass format(0, true);
  425. WideStringClass channelName(0, true);
  426. // Check to see what type of channel this is, chat or game.
  427. if (channel->GetType() == 0)
  428. {
  429. format = TRANSLATE(IDS_MP_WOL_BUDDY_CHAT_ROOM);
  430. WOLChatMgr* chatMgr = WOLChatMgr::GetInstance(false);
  431. if (chatMgr)
  432. {
  433. chatMgr->GetLobbyDisplayName(channel, channelName);
  434. chatMgr->Release_Ref();
  435. }
  436. }
  437. else
  438. {
  439. format = TRANSLATE(IDS_MP_WOL_BUDDY_GAME);
  440. channelName = channel->GetName();
  441. }
  442. description.Format(format, channelName);
  443. }
  444. }
  445. break;
  446. }
  447. }
  448. }
  449. /******************************************************************************
  450. *
  451. * NAME
  452. * WOLBuddyMgr::AddIgnore
  453. *
  454. * DESCRIPTION
  455. * Add a user to our ignore list.
  456. *
  457. * INPUTS
  458. * Name - Nickname of user to ignore.
  459. *
  460. * RESULT
  461. * NONE
  462. *
  463. ******************************************************************************/
  464. void WOLBuddyMgr::AddIgnore(const WCHAR* name)
  465. {
  466. if (!IsIgnored(name))
  467. {
  468. WideStringClass ignore(0, true);
  469. ignore = name;
  470. ignore.Trim();
  471. if (ignore.Get_Length() > 0)
  472. {
  473. WWDEBUG_SAY(("WOLBuddyMgr: Adding '%S' to ignore list.", name));
  474. mIgnoreList.push_back(ignore);
  475. SaveIgnoreList();
  476. Add_Ref();
  477. WOLBuddyMgrEvent event(IGNORELIST_CHANGED, this);
  478. NotifyObservers(event);
  479. Release_Ref();
  480. }
  481. }
  482. }
  483. /******************************************************************************
  484. *
  485. * NAME
  486. * WOLBuddyMgr::RemoveIgnore
  487. *
  488. * DESCRIPTION
  489. * Remove a user from our ignore list.
  490. *
  491. * INPUTS
  492. * Name - Nickname of user to remove.
  493. *
  494. * RESULT
  495. * NONE
  496. *
  497. ******************************************************************************/
  498. void WOLBuddyMgr::RemoveIgnore(const WCHAR* name)
  499. {
  500. IgnoreList::iterator iter = mIgnoreList.begin();
  501. while (iter != mIgnoreList.end())
  502. {
  503. const WideStringClass& ignore = (*iter);
  504. if (ignore.Compare_No_Case(name) == 0)
  505. {
  506. WWDEBUG_SAY(("WOLBuddyMgr: Removing '%S' from ignore list.", (const WCHAR*)ignore));
  507. mIgnoreList.erase(iter);
  508. SaveIgnoreList();
  509. Add_Ref();
  510. WOLBuddyMgrEvent event(IGNORELIST_CHANGED, this);
  511. NotifyObservers(event);
  512. Release_Ref();
  513. break;
  514. }
  515. iter++;
  516. }
  517. }
  518. /******************************************************************************
  519. *
  520. * NAME
  521. * WOLBuddyMgr::IsIgnored
  522. *
  523. * DESCRIPTION
  524. * Check if a user is being ignored.
  525. *
  526. * INPUTS
  527. * Name - Nickname of user to check.
  528. *
  529. * RESULT
  530. * True if user is being ignored.
  531. *
  532. ******************************************************************************/
  533. bool WOLBuddyMgr::IsIgnored(const WCHAR* name) const
  534. {
  535. for (unsigned int index = 0; index < mIgnoreList.size(); index++)
  536. {
  537. const WideStringClass& ignore = mIgnoreList[index];
  538. if (ignore.Compare_No_Case(name) == 0)
  539. {
  540. return true;
  541. }
  542. }
  543. return false;
  544. }
  545. /******************************************************************************
  546. *
  547. * NAME
  548. * WOLBuddyMgr::PageUser
  549. *
  550. * DESCRIPTION
  551. * Page a user.
  552. *
  553. * INPUTS
  554. * Name - Nickname of user to page.
  555. * Message - Message to send.
  556. *
  557. * RESULT
  558. * NONE
  559. *
  560. ******************************************************************************/
  561. void WOLBuddyMgr::PageUser(const WCHAR* name, const WCHAR* message)
  562. {
  563. mWOLSession->PageUser(name, message);
  564. }
  565. /******************************************************************************
  566. *
  567. * NAME
  568. * WOLBuddyMgr::ShowPagedDialog
  569. *
  570. * DESCRIPTION
  571. *
  572. * INPUTS
  573. * NONE
  574. *
  575. * RESULT
  576. * NONE
  577. *
  578. ******************************************************************************/
  579. void WOLBuddyMgr::ShowPagedDialog(void)
  580. {
  581. WWASSERT(mHidePagedDialog > 0 && "ShowPagedDialog() mismatch");
  582. if (mHidePagedDialog > 0)
  583. {
  584. --mHidePagedDialog;
  585. }
  586. }
  587. /******************************************************************************
  588. *
  589. * NAME
  590. * WOLBuddyMgr::HidePagedDialog
  591. *
  592. * DESCRIPTION
  593. *
  594. * INPUTS
  595. * NONE
  596. *
  597. * RESULT
  598. * NONE
  599. *
  600. ******************************************************************************/
  601. void WOLBuddyMgr::HidePagedDialog(void)
  602. {
  603. ++mHidePagedDialog;
  604. }
  605. /******************************************************************************
  606. *
  607. * NAME
  608. * WOLBuddyMgr::ClearPageList
  609. *
  610. * DESCRIPTION
  611. * Clear user pages.
  612. *
  613. * INPUTS
  614. * NONE
  615. *
  616. * RESULT
  617. * NONE
  618. *
  619. ******************************************************************************/
  620. void WOLBuddyMgr::ClearPageList(void)
  621. {
  622. mPageList.clear();
  623. }
  624. /******************************************************************************
  625. *
  626. * NAME
  627. * WOLBuddyMgr::JoinUser
  628. *
  629. * DESCRIPTION
  630. * Join the user in a chat or game channel.
  631. *
  632. * INPUTS
  633. * Name - Nickname of user to join.
  634. *
  635. * RESULT
  636. * NONE
  637. *
  638. ******************************************************************************/
  639. void WOLBuddyMgr::JoinUser(const RefPtr<UserData>& user)
  640. {
  641. // Release any current join request.
  642. mPendingJoin.Release();
  643. if (user.IsValid())
  644. {
  645. // Before we can join a user we must first find out their location.
  646. // See UserEvent::Located in HandleNotification(UserEvent)
  647. mPendingJoin = user;
  648. mWOLSession->RequestLocateUser(user);
  649. }
  650. }
  651. /******************************************************************************
  652. *
  653. * NAME
  654. * WOLBuddyMgr::ProcessPendingJoin
  655. *
  656. * DESCRIPTION
  657. * Process the pending join request. Once we have the location of the user
  658. * we want to join we can then attempt to goto that location. If the user
  659. * is not in a channel then the join request is aborted.
  660. *
  661. * INPUTS
  662. * NONE
  663. *
  664. * RESULT
  665. * NONE
  666. *
  667. ******************************************************************************/
  668. void WOLBuddyMgr::ProcessPendingJoin(void)
  669. {
  670. if (mPendingJoin.IsValid())
  671. {
  672. // Is the user in a place where we can join them?
  673. if (mPendingJoin->GetLocation() == USERLOCATION_IN_CHANNEL)
  674. {
  675. const RefPtr<ChannelData>& channel = mPendingJoin->GetChannel();
  676. if (channel.IsValid())
  677. {
  678. // If the channel to join is passworded then prompt the user to enter
  679. // a password. The join will continue after the user enters a password.
  680. // NOTE: See ReceiveSignal()
  681. if ((channel->GetType() != 0) && channel->IsPassworded())
  682. {
  683. DlgPasswordPrompt::DoDialog(this);
  684. }
  685. else
  686. {
  687. // Go ahead and attempt to join the pending location.
  688. GotoPendingJoinLocation(NULL);
  689. }
  690. return;
  691. }
  692. }
  693. // If we got here then we cannot join the pending location. Abort the request
  694. // and notify the user.
  695. mPendingJoin.Release();
  696. DlgMsgBox::DoDialog(IDS_WOL_ERROR, IDS_BUDDY_CANNOTJOIN, DlgMsgBox::Okay, NULL);
  697. }
  698. }
  699. /******************************************************************************
  700. *
  701. * NAME
  702. * WOLBuddyMgr::GotoPendingLocation
  703. *
  704. * DESCRIPTION
  705. * Goto the pending chat lobby or game.
  706. *
  707. * INPUTS
  708. * Password - Password to use to join chat lobby or game. Can be NULL if
  709. * a password is not required.
  710. *
  711. * RESULT
  712. * NONE
  713. *
  714. ******************************************************************************/
  715. void WOLBuddyMgr::GotoPendingJoinLocation(const wchar_t* password)
  716. {
  717. const RefPtr<ChannelData>& channel = mPendingJoin->GetChannel();
  718. WWASSERT(channel.IsValid() && "Pending join channel invalid");
  719. if (GameInitMgrClass::Is_Game_In_Progress())
  720. {
  721. GameInitMgrClass::End_Game();
  722. }
  723. // Determine if we should jump to a chat channel or game channel
  724. if (channel->GetType() == 0)
  725. {
  726. MPWolChatMenuClass::DoDialog(channel);
  727. }
  728. else if (channel->GetType() == Product::Current()->GetGameCode())
  729. {
  730. GameInitMgrClass::Set_WOL_Return_Dialog(RenegadeDialogMgrClass::LOC_INTERNET_GAME_LIST);
  731. WOLJoinGame::JoinTheGame(channel->GetName(), password, true);
  732. }
  733. mPendingJoin.Release();
  734. }
  735. /******************************************************************************
  736. *
  737. * NAME
  738. * WOLBuddyMgr::ReceiveSignal(DlgPasswordPrompt)
  739. *
  740. * DESCRIPTION
  741. * Handle receipt of signal that the user has entered a password to join
  742. * the pending join channel.
  743. *
  744. * INPUTS
  745. * PasswordDialog - Reference to password prompt dialog.
  746. *
  747. * RESULT
  748. * NONE
  749. *
  750. ******************************************************************************/
  751. void WOLBuddyMgr::ReceiveSignal(DlgPasswordPrompt& passwordDialog)
  752. {
  753. GotoPendingJoinLocation(passwordDialog.GetPassword());
  754. }
  755. /******************************************************************************
  756. *
  757. * NAME
  758. * WOLBuddyMgr::CanInviteUsers
  759. *
  760. * DESCRIPTION
  761. * Check if we are in a position to invite users.
  762. *
  763. * INPUTS
  764. * NONE
  765. *
  766. * RESULT
  767. * NONE
  768. *
  769. ******************************************************************************/
  770. bool WOLBuddyMgr::CanInviteUsers(void) const
  771. {
  772. return (ChannelJoined == mWOLSession->GetChannelStatus());
  773. }
  774. /******************************************************************************
  775. *
  776. * NAME
  777. * WOLBuddyMgr::InviteUser
  778. *
  779. * DESCRIPTION
  780. * Invite a user to join our location (Chat or Game)
  781. *
  782. * INPUTS
  783. * Name - Nickname of user to invite.
  784. *
  785. * RESULT
  786. * NONE
  787. *
  788. ******************************************************************************/
  789. void WOLBuddyMgr::InviteUser(const WCHAR* username, const WCHAR* message)
  790. {
  791. WideStringClass name(0, true);
  792. name = username;
  793. name.Trim();
  794. if (name.Get_Length() > 0)
  795. {
  796. if (message && (wcslen(message) > 0))
  797. {
  798. WideStringClass invitation(0, true);
  799. invitation.Format(L"%s%s", INVITE_CMD, message);
  800. PageUser(name, invitation);
  801. }
  802. else
  803. {
  804. PageUser(name, INVITE_CMD);
  805. }
  806. }
  807. }
  808. /******************************************************************************
  809. *
  810. * NAME
  811. * WOLBuddyMgr::DeclineInvitation
  812. *
  813. * DESCRIPTION
  814. * Decline an invitation to join a user.
  815. *
  816. * INPUTS
  817. * Name - Nickname of user to decline.
  818. *
  819. * RESULT
  820. * NONE
  821. *
  822. ******************************************************************************/
  823. void WOLBuddyMgr::DeclineInvitation(const WCHAR* username, DECLINE_REASON reason)
  824. {
  825. if (username && (wcslen(username) > 0))
  826. {
  827. // Build a decline "page"
  828. WideStringClass response(0, true);
  829. response.Format(L"%s%d", DECLINE_CMD, reason);
  830. // Send the response
  831. PageUser(username, response);
  832. }
  833. }
  834. /******************************************************************************
  835. *
  836. * NAME
  837. * WOLBuddyMgr::IsCommand
  838. *
  839. * DESCRIPTION
  840. * Check if a message is a command.
  841. *
  842. * INPUTS
  843. * Message - Message to check.
  844. *
  845. * RESULT
  846. * True if message is a command
  847. *
  848. ******************************************************************************/
  849. bool WOLBuddyMgr::IsCommand(const WCHAR* message)
  850. {
  851. // All commands begin with "<WW"
  852. return (message && (wcsstr(message, L"<WW") == message));
  853. }
  854. /******************************************************************************
  855. *
  856. * NAME
  857. * WOLBuddyMgr::IsInvitation
  858. *
  859. * DESCRIPTION
  860. * Check if a message is an invitation.
  861. *
  862. * INPUTS
  863. * Message - Message to check.
  864. *
  865. * RESULT
  866. * True if message is an invitation.
  867. *
  868. ******************************************************************************/
  869. bool WOLBuddyMgr::IsInvitation(const WCHAR* message)
  870. {
  871. return (message && (wcslen(message) >= INVITE_CMD_LEN) &&
  872. (wcsncmp(message, INVITE_CMD, INVITE_CMD_LEN) == 0));
  873. }
  874. /******************************************************************************
  875. *
  876. * NAME
  877. * WOLBuddyMgr::InvitationReceived
  878. *
  879. * DESCRIPTION
  880. * Handle invitation page from another user.
  881. *
  882. * INPUTS
  883. * Page - Invitation page.
  884. *
  885. * RESULT
  886. * NONE
  887. *
  888. ******************************************************************************/
  889. void WOLBuddyMgr::InvitationReceived(PageMessage& page)
  890. {
  891. const WideStringClass& pagerName = page.GetPagersName();
  892. // Check if we already have an invitation request from this user.
  893. // If so then ignore any subsequent invitations from him.
  894. PageMessageList::iterator iter = mInvitations.begin();
  895. while (iter != mInvitations.end())
  896. {
  897. // If this is in response to a another users invitation to join
  898. // then display the invitation since we now know were they are.
  899. if (pagerName.Compare_No_Case((*iter).GetPagersName()) == 0)
  900. {
  901. return;
  902. }
  903. iter++;
  904. }
  905. // Before we can display the invitation we must first find out where the
  906. // invitor is located. Once we have his location we can prompt the user.
  907. // See UserEvent::Located handling in HandleNotification(UserEvent)
  908. mInvitations.push_back(page);
  909. mWOLSession->RequestLocateUser(pagerName);
  910. }
  911. /******************************************************************************
  912. *
  913. * NAME
  914. * WOLBuddyMgr::DisplayInvitation
  915. *
  916. * DESCRIPTION
  917. * Display an invitation from another user.
  918. *
  919. * INPUTS
  920. * User - User inviting us.
  921. *
  922. * RESULT
  923. * NONE
  924. *
  925. ******************************************************************************/
  926. void WOLBuddyMgr::DisplayInvitation(const RefPtr<UserData>& user, const WCHAR* message)
  927. {
  928. if (user->GetLocation() != USERLOCATION_IN_CHANNEL)
  929. {
  930. // Decline the invitation because the user is not in a channel.
  931. DeclineInvitation(user->GetName(), DECLINE_NOTAPPLICABLE);
  932. }
  933. else
  934. {
  935. //-------------------------------------------------------------------------
  936. // Compose the invitation message
  937. //-------------------------------------------------------------------------
  938. // Get the user's name
  939. const WideStringClass& name = user->GetName();
  940. // Build a textual description of the user's location
  941. WideStringClass location(0, true);
  942. GetLocationDescription(user, location);
  943. // Format the invitation message
  944. WideStringClass inviteMsg(0, true);
  945. inviteMsg.Format(TRANSLATE(IDS_MP_WOL_INVITATION_FORMAT), (const WCHAR*)name, (const WCHAR*)location);
  946. inviteMsg += L"\n";
  947. inviteMsg += message;
  948. if (!mHidePagedDialog)
  949. {
  950. // Display the invitation dialog
  951. MPWolInvitationPopupClass* dialog = new MPWolInvitationPopupClass(user, inviteMsg);
  952. WWASSERT(dialog && "Failed to create invitation dialog");
  953. if (dialog)
  954. {
  955. dialog->Start_Dialog();
  956. dialog->Release_Ref();
  957. }
  958. }
  959. Add_Ref();
  960. PageMessage invite(user->GetName(), inviteMsg);
  961. WOLPagedEvent event(INVITATION_RECEIVED, &invite);
  962. NotifyObservers(event);
  963. Release_Ref();
  964. }
  965. }
  966. /******************************************************************************
  967. *
  968. * NAME
  969. * WOLBuddyMgr::IsInvitationDeclined
  970. *
  971. * DESCRIPTION
  972. * Check if the invitation was declined.
  973. *
  974. * INPUTS
  975. * Message - Message to check.
  976. *
  977. * RESULT
  978. * True if nvitation was declined.
  979. *
  980. ******************************************************************************/
  981. bool WOLBuddyMgr::IsInvitationDeclined(const WCHAR *message)
  982. {
  983. return (message && (wcslen(message) >= DECLINE_CMD_LEN) &&
  984. (wcsncmp(message, DECLINE_CMD, DECLINE_CMD_LEN) == 0));
  985. }
  986. /******************************************************************************
  987. *
  988. * NAME
  989. * WOLBuddyMgr::InvitationDeclined
  990. *
  991. * DESCRIPTION
  992. * Handle declined invitation.
  993. *
  994. * INPUTS
  995. * Name - Nickname of user.
  996. * Reason - Reason for declining.
  997. *
  998. * RESULT
  999. * NONE
  1000. *
  1001. ******************************************************************************/
  1002. void WOLBuddyMgr::InvitationDeclined(const WCHAR* username, DECLINE_REASON reason)
  1003. {
  1004. WideStringClass message(0, true);
  1005. // Build an appropriate message based on the reason
  1006. switch (reason)
  1007. {
  1008. default:
  1009. case DECLINE_BYUSER:
  1010. message = TRANSLATE(IDS_INVITE_DECLINE_BYUSER);
  1011. break;
  1012. case DECLINE_NOTBUDDY:
  1013. message.Format(TRANSLATE(IDS_INVITE_DECLINE_NOTBUDDY), username);
  1014. break;
  1015. case DECLINE_NOTAPPLICABLE:
  1016. message = TRANSLATE(IDS_INVITE_DECLINE_NOTAPPLICABLE);
  1017. break;
  1018. case DECLINE_BUSY:
  1019. message.Format(TRANSLATE(IDS_INVITE_DECLINE_BUSY), username);
  1020. break;
  1021. }
  1022. if (!mHidePagedDialog)
  1023. {
  1024. // Let the user know they've been declined
  1025. DlgMsgBox::DoDialog(NULL, message, DlgMsgBox::Okay, NULL);
  1026. }
  1027. Add_Ref();
  1028. PageMessage decline(username, message);
  1029. WOLPagedEvent event(INVITATION_DECLINED, &decline);
  1030. NotifyObservers(event);
  1031. Release_Ref();
  1032. }
  1033. /******************************************************************************
  1034. *
  1035. * NAME
  1036. * WOLBuddyMgr::HandleNotification(BuddyEvent)
  1037. *
  1038. * DESCRIPTION
  1039. * Handle buddy event notifications. (List, Add, Remove)
  1040. *
  1041. * INPUTS
  1042. * Event
  1043. *
  1044. * RESULT
  1045. * NONE
  1046. *
  1047. ******************************************************************************/
  1048. void WOLBuddyMgr::HandleNotification(BuddyEvent& event)
  1049. {
  1050. bool listChanged = false;
  1051. if ((event.GetEvent() == BuddyEvent::NewList) || (event.GetEvent() == BuddyEvent::Added))
  1052. {
  1053. const UserList& buddies = event.Subject();
  1054. unsigned int count = buddies.size();
  1055. for (unsigned int index = 0; index < count; ++index)
  1056. {
  1057. const RefPtr<UserData>& buddy = buddies[index];
  1058. // Request details about the buddy
  1059. if (buddy.IsValid())
  1060. {
  1061. mWOLSession->RequestLocateUser(buddy);
  1062. // Request squad affliation for this user.
  1063. if (!buddy->GetSquad().IsValid())
  1064. {
  1065. mWOLSession->RequestSquadInfoByMemberName(buddy->GetName());
  1066. }
  1067. // Request ranking information for this user.
  1068. if (!buddy->GetTeamLadder().IsValid())
  1069. {
  1070. mWOLSession->RequestLadderInfo(buddy->GetName(), LadderType_Team);
  1071. }
  1072. }
  1073. }
  1074. listChanged = true;
  1075. }
  1076. else if (event.GetEvent() == BuddyEvent::Deleted)
  1077. {
  1078. listChanged = true;
  1079. }
  1080. if (listChanged)
  1081. {
  1082. Add_Ref();
  1083. WOLBuddyMgrEvent event(BUDDYLIST_CHANGED, this);
  1084. NotifyObservers(event);
  1085. Release_Ref();
  1086. }
  1087. }
  1088. /******************************************************************************
  1089. *
  1090. * NAME
  1091. * WOLBuddyMgr::HandleNotification(UserEvent)
  1092. *
  1093. * DESCRIPTION
  1094. *
  1095. * INPUTS
  1096. *
  1097. * RESULT
  1098. * NONE
  1099. *
  1100. ******************************************************************************/
  1101. void WOLBuddyMgr::HandleNotification(UserEvent& event)
  1102. {
  1103. switch (event.GetEvent())
  1104. {
  1105. // Users location status obtained.
  1106. case UserEvent::Located:
  1107. {
  1108. const RefPtr<UserData>& user = event.Subject();
  1109. const WideStringClass& username = user->GetName();
  1110. // Try to find an invitation from this user.
  1111. bool foundInvitation = false;
  1112. PageMessageList::iterator iter = mInvitations.begin();
  1113. while (iter != mInvitations.end())
  1114. {
  1115. // If this is in response to a another users invitation to join them
  1116. // then display the invitation since we now know were they are.
  1117. if (username.Compare_No_Case((*iter).GetPagersName()) == 0)
  1118. {
  1119. const WCHAR* invite = (*iter).GetPageMessage();
  1120. DisplayInvitation(user, &invite[INVITE_CMD_LEN]);
  1121. mInvitations.erase(iter);
  1122. foundInvitation = true;
  1123. break;
  1124. }
  1125. iter++;
  1126. }
  1127. // Check if we requested to join a user.
  1128. if ((foundInvitation == false) && mPendingJoin.IsValid())
  1129. {
  1130. // If this is the user we requested to join then goto their
  1131. // location.
  1132. if (username.Compare_No_Case(mPendingJoin->GetName()) == 0)
  1133. {
  1134. ProcessPendingJoin();
  1135. return;
  1136. }
  1137. }
  1138. // Report buddy locations
  1139. if (IsBuddy(username))
  1140. {
  1141. Add_Ref();
  1142. WOLBuddyMgrEvent event(BUDDYINFO_CHANGED, this);
  1143. NotifyObservers(event);
  1144. Release_Ref();
  1145. }
  1146. }
  1147. break;
  1148. case UserEvent::SquadInfo:
  1149. case UserEvent::LadderInfo:
  1150. if (IsBuddy(event.Subject()->GetName()))
  1151. {
  1152. Add_Ref();
  1153. WOLBuddyMgrEvent event(BUDDYINFO_CHANGED, this);
  1154. NotifyObservers(event);
  1155. Release_Ref();
  1156. }
  1157. break;
  1158. default:
  1159. break;
  1160. }
  1161. }
  1162. /******************************************************************************
  1163. *
  1164. * NAME
  1165. * WOLBuddyMgr::HandleNotification(PageMessage)
  1166. *
  1167. * DESCRIPTION
  1168. * Handle pages from other users.
  1169. *
  1170. * INPUTS
  1171. * Page - Page message to process.
  1172. *
  1173. * RESULT
  1174. * NONE
  1175. *
  1176. ******************************************************************************/
  1177. void WOLBuddyMgr::HandleNotification(PageMessage& page)
  1178. {
  1179. // Only accept pages from users we are not ignoring.
  1180. if (IsIgnored(page.GetPagersName()) == false)
  1181. {
  1182. const WideStringClass& pager = page.GetPagersName();
  1183. const WideStringClass& message = page.GetPageMessage();
  1184. mLastPagersName = pager;
  1185. if (ConsoleBox.Is_Exclusive()) {
  1186. if (((WideStringClass*)&message)->Is_ANSI()) {
  1187. WideStringClass temp(L"[Page] ", true);
  1188. temp += pager;
  1189. temp += L": ";
  1190. temp += message;
  1191. temp += L"\n";
  1192. Vector3 text_color(0.0f, 1.0f, 0.0f);
  1193. ConsoleBox.Add_Message(&temp, &text_color, true);
  1194. }
  1195. } else {
  1196. // If this page is not a command then show it to the user.
  1197. if (!IsCommand(message))
  1198. {
  1199. bool allowPages = MPSettingsMgrClass::Get_Option_Flag(MPSettingsMgrClass::OPTION_ALLOW_PAGES);
  1200. if (allowPages)
  1201. {
  1202. // Popup a page reply dialog for the player to respond to.
  1203. if (!mHidePagedDialog)
  1204. {
  1205. DlgWOLPageReply::DoDialog();
  1206. }
  1207. // Notify that there are new page.
  1208. Add_Ref();
  1209. WOLPagedEvent event(PAGE_RECEIVED, &page);
  1210. NotifyObservers(event);
  1211. Release_Ref();
  1212. }
  1213. }
  1214. else if (IsInvitation(message))
  1215. {
  1216. // A user has sent us an invitation
  1217. InvitationReceived(page);
  1218. }
  1219. else if (IsInvitationDeclined(message))
  1220. {
  1221. // A user declined our invitation.
  1222. DECLINE_REASON reason = DECLINE_BYUSER;
  1223. // Grab the reason code
  1224. const WCHAR* codeString = message + DECLINE_CMD_LEN;
  1225. int code = _wtoi(codeString);
  1226. if (code > DECLINE_MIN && code < DECLINE_MAX)
  1227. {
  1228. reason = (DECLINE_REASON)code;
  1229. }
  1230. // The user we invited has declined our invitation.
  1231. InvitationDeclined(pager, reason);
  1232. }
  1233. }
  1234. }
  1235. }
  1236. /******************************************************************************
  1237. *
  1238. * NAME
  1239. * WOLBuddyMgr::HandleNotification(PageSendStatus)
  1240. *
  1241. * DESCRIPTION
  1242. *
  1243. * INPUTS
  1244. * Status
  1245. *
  1246. * RESULT
  1247. * NONE
  1248. *
  1249. ******************************************************************************/
  1250. void WOLBuddyMgr::HandleNotification(PageSendStatus& pageStatus)
  1251. {
  1252. WOLPagedAction action = PAGE_ERROR;
  1253. uint32 msgID = 0;
  1254. switch (pageStatus)
  1255. {
  1256. case PAGESEND_ERROR:
  1257. action = PAGE_ERROR;
  1258. msgID = IDS_PAGESEND_ERROR;
  1259. break;
  1260. case PAGESEND_OFFLINE:
  1261. action = PAGE_NOT_THERE;
  1262. msgID = IDS_PAGESEND_OFFLINE;
  1263. break;
  1264. case PAGESEND_HIDING:
  1265. action = PAGE_TURNED_OFF;
  1266. msgID = IDS_PAGESEND_HIDING;
  1267. break;
  1268. case PAGESEND_SENT:
  1269. default:
  1270. return;
  1271. }
  1272. // If the page was undeliverable then tell the user why.
  1273. if (!mHidePagedDialog && !DlgWOLPageReply::IsOpen())
  1274. {
  1275. DlgMsgBox::DoDialog(IDS_WOL_PAGEUSERERROR, msgID);
  1276. }
  1277. Add_Ref();
  1278. PageMessage page(NULL, TRANSLATE(msgID));
  1279. WOLPagedEvent event(action, &page);
  1280. NotifyObservers(event);
  1281. Release_Ref();
  1282. }