Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

999 lines
27 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Serves as the base panel for the entire matchmaking UI
  4. //
  5. //=============================================================================//
  6. #include "matchmakingbasepanel.h"
  7. #include "welcomedialog.h"
  8. #include "pausedialog.h"
  9. #include "leaderboarddialog.h"
  10. #include "achievementsdialog.h"
  11. #include "sessionoptionsdialog.h"
  12. #include "sessionlobbydialog.h"
  13. #include "sessionbrowserdialog.h"
  14. #include "vgui_controls/Label.h"
  15. #include "vgui_controls/MessageDialog.h"
  16. #include "vgui/ISurface.h"
  17. #include "EngineInterface.h"
  18. #include "game/client/IGameClientExports.h"
  19. #include "GameUI_Interface.h"
  20. #include "engine/imatchmaking.h"
  21. #include "KeyValues.h"
  22. #include "vstdlib/jobthread.h"
  23. #include "BasePanel.h"
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include "tier0/memdbgon.h"
  26. //--------------------------------
  27. // CMatchmakingBasePanel
  28. //--------------------------------
  29. CMatchmakingBasePanel::CMatchmakingBasePanel( vgui::Panel *pParent ) : BaseClass( pParent, "MatchmakingBasePanel" )
  30. {
  31. SetDeleteSelfOnClose( true );
  32. SetPaintBackgroundEnabled( false );
  33. vgui::scheme()->LoadSchemeFromFile( "Resource/ClientScheme.res", "ClientScheme" );
  34. SetScheme( "ClientScheme" );
  35. m_pFooter = new CFooterPanel( this, "MatchmakingFooterPanel" );
  36. m_nGameType = GAMETYPE_STANDARD_MATCH;
  37. }
  38. CMatchmakingBasePanel::~CMatchmakingBasePanel()
  39. {
  40. if ( m_pFooter )
  41. {
  42. delete m_pFooter;
  43. m_pFooter = NULL;
  44. }
  45. }
  46. void CMatchmakingBasePanel::SetFooterButtons( CBaseDialog *pOwner, KeyValues *pKeyValues, int nButtonGap /* = -1 */ )
  47. {
  48. // Don't lay out the buttons if the dialog is not at the top of the stack
  49. if ( m_DialogStack.Count() )
  50. {
  51. CBaseDialog *pDlg = m_DialogStack.Top();
  52. if ( pDlg != pOwner )
  53. return;
  54. }
  55. if ( m_pFooter )
  56. {
  57. m_pFooter->ClearButtons();
  58. if ( pKeyValues )
  59. {
  60. for ( KeyValues *pButton = pKeyValues->GetFirstSubKey(); pButton != NULL; pButton = pButton->GetNextKey() )
  61. {
  62. if ( !Q_stricmp( pButton->GetName(), "button" ) )
  63. {
  64. // Add a button to the footer
  65. const char *pText = pButton->GetString( "text", NULL );
  66. const char *pIcon = pButton->GetString( "icon", NULL );
  67. if ( pText && pIcon )
  68. {
  69. m_pFooter->AddNewButtonLabel( pText, pIcon );
  70. }
  71. }
  72. }
  73. }
  74. else
  75. {
  76. // no data was passed so just setup the standard footer buttons
  77. m_pFooter->SetStandardDialogButtons();
  78. }
  79. if ( nButtonGap > 0 )
  80. {
  81. m_pFooter->SetButtonGap( nButtonGap );
  82. }
  83. else
  84. {
  85. m_pFooter->UseDefaultButtonGap();
  86. }
  87. }
  88. }
  89. void CMatchmakingBasePanel::ShowFooter( bool bShown )
  90. {
  91. m_pFooter->SetVisible( bShown );
  92. }
  93. void CMatchmakingBasePanel::SetFooterButtonVisible( const char *pszText, bool bVisible )
  94. {
  95. if ( m_pFooter )
  96. {
  97. m_pFooter->ShowButtonLabel( pszText, bVisible );
  98. }
  99. }
  100. void CMatchmakingBasePanel::Activate( void )
  101. {
  102. BaseClass::Activate();
  103. // Close animation may have set this to zero
  104. SetAlpha( 255 );
  105. if ( !GameUI().IsInLevel() )
  106. {
  107. OnOpenWelcomeDialog();
  108. }
  109. else
  110. {
  111. OnOpenPauseDialog();
  112. }
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose: Handle commands from all matchmaking dialogs
  116. //-----------------------------------------------------------------------------
  117. void CMatchmakingBasePanel::OnCommand( const char *pCommand )
  118. {
  119. if ( !Q_stricmp( "OpenWelcomeDialog", pCommand ) )
  120. {
  121. OnOpenWelcomeDialog();
  122. }
  123. if ( !Q_stricmp( "OpenPauseDialog", pCommand ) )
  124. {
  125. OnOpenPauseDialog();
  126. }
  127. if ( !Q_stricmp( "OpenRankingsDialog", pCommand ) )
  128. {
  129. OnOpenRankingsDialog();
  130. }
  131. else if ( !Q_stricmp( "OpenSystemLinkDialog", pCommand ) )
  132. {
  133. OnOpenSystemLinkDialog();
  134. }
  135. else if ( !Q_stricmp( "OpenPlayerMatchDialog", pCommand ) )
  136. {
  137. OnOpenPlayerMatchDialog();
  138. }
  139. else if ( !Q_stricmp( "OpenRankedMatchDialog", pCommand ) )
  140. {
  141. OnOpenRankedMatchDialog();
  142. }
  143. else if ( !Q_stricmp( "OpenAchievementsDialog", pCommand ) )
  144. {
  145. OnOpenAchievementsDialog();
  146. }
  147. //=============================================================================
  148. // HPE_BEGIN:
  149. // [dwenger] Specific code for CS Achievements Display
  150. //=============================================================================
  151. else if ( !Q_stricmp( "OpenCSAchievementsDialog", pCommand ) )
  152. {
  153. OnOpenCSAchievementsDialog();
  154. }
  155. //=============================================================================
  156. // HPE_END
  157. //=============================================================================
  158. else if ( !Q_stricmp( "LevelLoadingStarted", pCommand ) )
  159. {
  160. OnLevelLoadingStarted();
  161. }
  162. else if ( !Q_stricmp( "LevelLoadingFinished", pCommand ) )
  163. {
  164. OnLevelLoadingFinished();
  165. }
  166. else if ( !Q_stricmp( "SessionOptions_Modify", pCommand ) )
  167. {
  168. OnOpenSessionOptionsDialog( pCommand );
  169. }
  170. else if ( !Q_stricmp( "ModifySession", pCommand ) )
  171. {
  172. matchmaking->ModifySession();
  173. }
  174. else if ( !Q_stricmp( "ChangeClass", pCommand ) )
  175. {
  176. engine->ClientCmd_Unrestricted( "changeclass" );
  177. OnCommand( "ResumeGame" );
  178. }
  179. else if ( !Q_stricmp( "ChangeTeam", pCommand ) )
  180. {
  181. engine->ClientCmd_Unrestricted( "changeteam" );
  182. OnCommand( "ResumeGame" );
  183. }
  184. else if ( !Q_stricmp( "ShowMapInfo", pCommand ) )
  185. {
  186. engine->ClientCmd_Unrestricted( "showmapinfo" );
  187. OnCommand( "ResumeGame" );
  188. }
  189. else if ( !Q_stricmp( "StartHost", pCommand ) )
  190. {
  191. // Show progress dialog
  192. GameUI().ShowMessageDialog( MD_CREATING_GAME, this );
  193. // Send the host start command
  194. matchmaking->StartHost();
  195. }
  196. else if ( !Q_stricmp( "StartSystemLinkHost", pCommand ) )
  197. {
  198. // Show progress dialog
  199. GameUI().ShowMessageDialog( MD_CREATING_GAME, this );
  200. m_nGameType = GAMETYPE_SYSTEMLINK_MATCH;
  201. matchmaking->StartHost( true );
  202. }
  203. else if ( !Q_stricmp( "StartClient", pCommand ) )
  204. {
  205. // Show progress dialog
  206. GameUI().ShowMessageDialog( MD_SEARCHING_FOR_GAMES, this );
  207. // Tell matchmaking to start a client and search for games
  208. matchmaking->StartClient( false );
  209. }
  210. else if ( !Q_stricmp( "StartSystemLinkClient", pCommand ) )
  211. {
  212. // Show progress dialog
  213. GameUI().ShowMessageDialog( MD_SEARCHING_FOR_GAMES, this );
  214. // Set the system link flag
  215. matchmaking->AddSessionProperty( SESSION_FLAG, "SESSION_CREATE_SYSTEMLINK", NULL, NULL );
  216. // Tell matchmaking to start a client and search for games
  217. m_nGameType = GAMETYPE_SYSTEMLINK_MATCH;
  218. matchmaking->StartClient( true );
  219. }
  220. else if ( Q_stristr( pCommand, "StartQuickMatchClient_" ) )
  221. {
  222. // Show progress dialog
  223. GameUI().ShowMessageDialog( MD_SEARCHING_FOR_GAMES, this );
  224. if ( Q_stristr( pCommand, "_Ranked" ) )
  225. {
  226. // Set the basic flags
  227. matchmaking->AddSessionProperty( SESSION_CONTEXT, "CONTEXT_GAME_MODE", "CONTEXT_GAME_MODE_MULTIPLAYER", NULL );
  228. matchmaking->AddSessionProperty( SESSION_CONTEXT, "CONTEXT_GAME_TYPE", "CONTEXT_GAME_TYPE_RANKED", NULL );
  229. matchmaking->AddSessionProperty( SESSION_FLAG, "SESSION_CREATE_LIVE_MULTIPLAYER_RANKED", NULL, NULL );
  230. m_nGameType = GAMETYPE_RANKED_MATCH;
  231. }
  232. else
  233. {
  234. // Set the standard match flag
  235. matchmaking->AddSessionProperty( SESSION_CONTEXT, "CONTEXT_GAME_MODE", "CONTEXT_GAME_MODE_MULTIPLAYER", NULL );
  236. matchmaking->AddSessionProperty( SESSION_CONTEXT, "CONTEXT_GAME_TYPE", "CONTEXT_GAME_TYPE_STANDARD", NULL );
  237. matchmaking->AddSessionProperty( SESSION_FLAG, "SESSION_CREATE_LIVE_MULTIPLAYER_STANDARD", NULL, NULL );
  238. m_nGameType = GAMETYPE_STANDARD_MATCH;
  239. }
  240. // Tell matchmaking to start a client and search for games
  241. matchmaking->StartClient( false );
  242. }
  243. else if ( !Q_stricmp( "StartGame", pCommand ) )
  244. {
  245. // Tell matchmaking the host wants to start the game
  246. matchmaking->StartGame();
  247. }
  248. else if ( Q_stristr( pCommand, "LeaderboardDialog_" ) )
  249. {
  250. // This covers LeaderboardDialog_[Ranked|Stats]
  251. OnOpenLeaderboardDialog( pCommand );
  252. }
  253. else if ( Q_stristr( pCommand, "SessionOptions_" ) )
  254. {
  255. // This covers six command strings: *_Host[Standard|Ranked|Systemlink], *_Client[Standard|Ranked|Systemlink]
  256. // Each command has a unique options menu - the command string is used as the name of the .res file.
  257. OnOpenSessionOptionsDialog( pCommand );
  258. }
  259. else if ( !Q_stricmp( pCommand, "DialogClosing" ) )
  260. {
  261. PopDialog();
  262. }
  263. else if ( !Q_stricmp( pCommand, "AchievementsDialogClosing" ) )
  264. {
  265. PopDialog();
  266. }
  267. else if ( !Q_stricmp( pCommand, "show_achievements_dialog" ) )
  268. {
  269. OnOpenAchievementsDialog();
  270. }
  271. //=============================================================================
  272. // HPE_BEGIN:
  273. // [dwenger] Specific code for CS Achievements Display
  274. //=============================================================================
  275. else if ( !Q_stricmp( pCommand, "show_csachievements_dialog" ) )
  276. {
  277. OnOpenCSAchievementsDialog();
  278. }
  279. //=============================================================================
  280. // HPE_END
  281. //=============================================================================
  282. else if ( !Q_stricmp( pCommand, "ShowSessionOptionsDialog" ) )
  283. {
  284. // Need to close the client options dialog and open the host options equivalent
  285. PopDialog();
  286. switch( m_nGameType )
  287. {
  288. case GAMETYPE_STANDARD_MATCH:
  289. OnOpenSessionOptionsDialog( "SessionOptions_HostStandard" );
  290. break;
  291. case GAMETYPE_RANKED_MATCH:
  292. OnOpenSessionOptionsDialog( "SessionOptions_HostRanked" );
  293. break;
  294. case GAMETYPE_SYSTEMLINK_MATCH:
  295. OnOpenSessionOptionsDialog( "SessionOptions_SystemLink" );
  296. break;
  297. }
  298. }
  299. else if ( !Q_stricmp( pCommand, "ReturnToMainMenu" ) )
  300. {
  301. CloseAllDialogs();
  302. Activate();
  303. }
  304. else if ( !Q_stricmp( pCommand, "CancelOperation" ) )
  305. {
  306. GameUI().CloseMessageDialog();
  307. PopDialog();
  308. matchmaking->CancelCurrentOperation();
  309. }
  310. else if ( !Q_stricmp( pCommand, "StorageDeviceDenied" ) )
  311. {
  312. // Set us as declined
  313. XBX_SetStorageDeviceId( XBX_STORAGE_DECLINED );
  314. }
  315. else
  316. {
  317. if ( !Q_stricmp( "ResumeGame", pCommand ) )
  318. {
  319. CloseAllDialogs();
  320. }
  321. CallParentFunction( new KeyValues( "Command", "command", pCommand ) );
  322. }
  323. // We should handle the case when user launched the game via invite,
  324. // was prompted for a storage device and cancelled the picker.
  325. // In this case whenever any command gets selected from the main menu
  326. // we should cancel the wait for storage device selection.
  327. BasePanel()->ValidateStorageDevice( NULL );
  328. }
  329. //-----------------------------------------------------------------------------
  330. // Purpose: Handle notifications from matchmaking in the engine.
  331. //-----------------------------------------------------------------------------
  332. void CMatchmakingBasePanel::SessionNotification( const int notification, const int param )
  333. {
  334. switch( notification )
  335. {
  336. case SESSION_NOTIFY_FAIL_SEARCH:
  337. GameUI().CloseMessageDialog();
  338. GameUI().ShowMessageDialog( MD_SESSION_SEARCH_FAILED, this );
  339. break;
  340. case SESSION_NOTIFY_CONNECT_NOTAVAILABLE:
  341. CloseAllDialogs();
  342. GameUI().ShowMessageDialog( MD_SESSION_CONNECT_NOTAVAILABLE, this );
  343. break;
  344. case SESSION_NOTIFY_CONNECT_SESSIONFULL:
  345. CloseAllDialogs();
  346. GameUI().ShowMessageDialog( MD_SESSION_CONNECT_SESSIONFULL, this );
  347. break;
  348. case SESSION_NOTIFY_CONNECT_FAILED:
  349. CloseAllDialogs();
  350. GameUI().ShowMessageDialog( MD_SESSION_CONNECT_FAILED, this );
  351. break;
  352. case SESSION_NOTIFY_FAIL_CREATE:
  353. CloseAllDialogs();
  354. GameUI().ShowMessageDialog( MD_SESSION_CREATE_FAILED, this );
  355. break;
  356. case SESSION_NOTIFY_CLIENT_KICKED:
  357. CloseAllDialogs();
  358. GameUI().ShowMessageDialog( MD_CLIENT_KICKED, this );
  359. break;
  360. case SESSION_NOTIFY_LOST_HOST:
  361. CloseBaseDialogs();
  362. GameUI().ShowMessageDialog( MD_LOST_HOST, this );
  363. break;
  364. case SESSION_NOTIFY_LOST_SERVER:
  365. CloseBaseDialogs();
  366. GameUI().ShowMessageDialog( MD_LOST_SERVER, this );
  367. break;
  368. case SESSION_NOFIFY_MODIFYING_SESSION:
  369. GameUI().ShowMessageDialog( MD_MODIFYING_SESSION, this );
  370. break;
  371. case SESSION_NOTIFY_SEARCH_COMPLETED:
  372. GameUI().CloseMessageDialog();
  373. LoadSessionProperties();
  374. // Switch to the session browser
  375. switch( m_nGameType )
  376. {
  377. case GAMETYPE_STANDARD_MATCH:
  378. case GAMETYPE_RANKED_MATCH:
  379. OnOpenSessionBrowserDialog( "SessionBrowser_Live" );
  380. break;
  381. case GAMETYPE_SYSTEMLINK_MATCH:
  382. OnOpenSessionBrowserDialog( "SessionBrowser_SystemLink" );
  383. break;
  384. }
  385. break;
  386. case SESSION_NOTIFY_CREATED_HOST:
  387. case SESSION_NOTIFY_MODIFYING_COMPLETED_HOST:
  388. GameUI().CloseMessageDialog();
  389. LoadSessionProperties();
  390. // Switch to the Lobby
  391. switch( m_nGameType )
  392. {
  393. case GAMETYPE_STANDARD_MATCH:
  394. case GAMETYPE_RANKED_MATCH:
  395. case GAMETYPE_SYSTEMLINK_MATCH:
  396. OnOpenSessionLobbyDialog( "SessionLobby_Host" );
  397. break;
  398. }
  399. break;
  400. case SESSION_NOTIFY_CREATED_CLIENT:
  401. GameUI().ShowMessageDialog( MD_SESSION_CONNECTING, this );
  402. break;
  403. case SESSION_NOTIFY_CONNECTED_TOSESSION:
  404. case SESSION_NOTIFY_MODIFYING_COMPLETED_CLIENT:
  405. GameUI().CloseMessageDialog();
  406. LoadSessionProperties();
  407. // Switch to the Lobby
  408. switch( m_nGameType )
  409. {
  410. case GAMETYPE_STANDARD_MATCH:
  411. case GAMETYPE_RANKED_MATCH:
  412. case GAMETYPE_SYSTEMLINK_MATCH:
  413. OnOpenSessionLobbyDialog( "SessionLobby_Client" );
  414. break;
  415. }
  416. break;
  417. case SESSION_NOTIFY_CONNECTED_TOSERVER:
  418. CloseAllDialogs( false );
  419. break;
  420. case SESSION_NOTIFY_ENDGAME_RANKED:
  421. // Return to the main menu
  422. CloseAllDialogs();
  423. break;
  424. case SESSION_NOTIFY_ENDGAME_HOST:
  425. CloseBaseDialogs();
  426. OnOpenSessionLobbyDialog( "SessionLobby_Host" );
  427. break;
  428. case SESSION_NOTIFY_ENDGAME_CLIENT:
  429. CloseBaseDialogs();
  430. OnOpenSessionLobbyDialog( "SessionLobby_Client" );
  431. break;
  432. case SESSION_NOTIFY_COUNTDOWN:
  433. {
  434. CSessionLobbyDialog *pDlg = (CSessionLobbyDialog*)m_hSessionLobbyDialog.Get();
  435. if ( pDlg )
  436. {
  437. pDlg->UpdateCountdown( param );
  438. }
  439. if ( param == 0 )
  440. {
  441. BasePanel()->RunAnimationWithCallback( this, "CloseMatchmakingUI", new KeyValues( "LoadMap" ) );
  442. }
  443. }
  444. break;
  445. case SESSION_NOTIFY_DUMPSTATS:
  446. Msg( "[MM] %d open dialogs\n", m_DialogStack.Count() );
  447. for ( int i = 0; i < m_DialogStack.Count(); ++i )
  448. {
  449. const char *pString = "NULL";
  450. bool bVisible = false;
  451. float fAlpha = 0.f;
  452. CBaseDialog *pDlg = m_DialogStack[i];
  453. if ( pDlg )
  454. {
  455. pString = pDlg->GetName();
  456. bVisible = pDlg->IsVisible();
  457. fAlpha = pDlg->GetAlpha();
  458. }
  459. const char *pVisible = bVisible ? "YES" : "NO";
  460. Msg( "[MM] Dialog %d: %s, Visible %s, Alpha %f\n", i, pString, pVisible, fAlpha );
  461. }
  462. break;
  463. case SESSION_NOTIFY_WELCOME:
  464. CloseGameDialogs( false );
  465. Activate();
  466. break;
  467. }
  468. }
  469. //-----------------------------------------------------------------------------
  470. // Purpose: System Notification
  471. //-----------------------------------------------------------------------------
  472. void CMatchmakingBasePanel::SystemNotification( const int notification )
  473. {
  474. switch( notification )
  475. {
  476. case SYSTEMNOTIFY_USER_SIGNEDOUT:
  477. // See if this was us
  478. #if defined( _X360 )
  479. uint state = XUserGetSigninState( XBX_GetPrimaryUserId() );
  480. if ( state == eXUserSigninState_NotSignedIn )
  481. {
  482. matchmaking->KickPlayerFromSession( 0 );
  483. CloseAllDialogs();
  484. }
  485. else if ( state != eXUserSigninState_SignedInToLive )
  486. {
  487. // User was signed out of live
  488. if ( m_bPlayingOnline )
  489. {
  490. matchmaking->KickPlayerFromSession( 0 );
  491. CloseAllDialogs();
  492. }
  493. }
  494. #endif
  495. break;
  496. }
  497. }
  498. //-----------------------------------------------------------------------------
  499. // Purpose: Check whether a player meets the signin requirements for a multiplayer game
  500. //-----------------------------------------------------------------------------
  501. bool CMatchmakingBasePanel::ValidateSigninAndStorage( bool bOnlineRequired, const char *pIssuingCommand )
  502. {
  503. // Check the signin state of the primary user
  504. bool bSignedIn = false;
  505. bool bOnlineEnabled = false;
  506. bool bOnlineSignedIn = false;
  507. #if defined( _X360 )
  508. int userIdx = XBX_GetPrimaryUserId();
  509. if ( userIdx != INVALID_USER_ID )
  510. {
  511. XUSER_SIGNIN_INFO info;
  512. uint ret = XUserGetSigninInfo( userIdx, 0, &info );
  513. if ( ret == ERROR_SUCCESS )
  514. {
  515. bSignedIn = true;
  516. if ( info.dwInfoFlags & XUSER_INFO_FLAG_LIVE_ENABLED )
  517. {
  518. bOnlineEnabled = true;
  519. uint state = XUserGetSigninState( XBX_GetPrimaryUserId() );
  520. if ( state == eXUserSigninState_SignedInToLive )
  521. {
  522. bOnlineSignedIn = true;
  523. // Check privileges
  524. BOOL bPrivCheck = false;
  525. DWORD dwPrivCheck = XUserCheckPrivilege( userIdx, XPRIVILEGE_MULTIPLAYER_SESSIONS, &bPrivCheck );
  526. if ( ERROR_SUCCESS != dwPrivCheck ||
  527. !bPrivCheck )
  528. {
  529. bOnlineEnabled = false;
  530. }
  531. }
  532. }
  533. }
  534. }
  535. #endif
  536. if ( bOnlineRequired && !bOnlineEnabled )
  537. {
  538. // Player must sign in an online account
  539. GameUI().ShowMessageDialog( MD_NOT_ONLINE_ENABLED );
  540. return false;
  541. }
  542. else if ( bOnlineRequired && !bOnlineSignedIn )
  543. {
  544. // Player's live account isn't signed in to live
  545. GameUI().ShowMessageDialog( MD_NOT_ONLINE_SIGNEDIN );
  546. return false;
  547. }
  548. else if ( !bSignedIn )
  549. {
  550. // Eat the input and make the user sign in
  551. xboxsystem->ShowSigninUI( 1, 0 ); // One user, no special flags
  552. return false;
  553. }
  554. // Handle the storage device selection
  555. if ( !BasePanel()->HandleStorageDeviceRequest( pIssuingCommand ) )
  556. return false;
  557. // If we succeeded, clear the command out
  558. BasePanel()->ClearPostPromptCommand( pIssuingCommand );
  559. return true;
  560. }
  561. //-----------------------------------------------------------------------------
  562. // Purpose: Update player information in the lobby
  563. //-----------------------------------------------------------------------------
  564. void CMatchmakingBasePanel::UpdatePlayerInfo( uint64 nPlayerId, const char *pName, int nTeam, byte cVoiceState, int nPlayersNeeded, bool bHost )
  565. {
  566. CSessionLobbyDialog *pLobby = dynamic_cast< CSessionLobbyDialog* >( m_hSessionLobbyDialog.Get() );
  567. if ( pLobby )
  568. {
  569. pLobby->UpdatePlayerInfo( nPlayerId, pName, nTeam, cVoiceState, nPlayersNeeded, bHost );
  570. }
  571. }
  572. //-----------------------------------------------------------------------------
  573. // Purpose: Add a search result to the browser dialog
  574. //-----------------------------------------------------------------------------
  575. void CMatchmakingBasePanel::SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping )
  576. {
  577. CSessionBrowserDialog *pBrowser = dynamic_cast< CSessionBrowserDialog* >( m_hSessionBrowserDialog.Get() );
  578. if ( pBrowser )
  579. {
  580. pBrowser->SessionSearchResult( searchIdx, pHostData, pResult, ping );
  581. }
  582. }
  583. //-----------------------------------------------------------------------------
  584. // Purpose: Pre level load ops
  585. //-----------------------------------------------------------------------------
  586. void CMatchmakingBasePanel::OnLevelLoadingStarted()
  587. {
  588. }
  589. //-----------------------------------------------------------------------------
  590. // Purpose: Post level load ops
  591. //-----------------------------------------------------------------------------
  592. void CMatchmakingBasePanel::OnLevelLoadingFinished()
  593. {
  594. }
  595. //-----------------------------------------------------------------------------
  596. // Purpose: Hide the current dialog, add a new one to the stack and activate it.
  597. //-----------------------------------------------------------------------------
  598. void CMatchmakingBasePanel::PushDialog( vgui::DHANDLE< CBaseDialog > &hDialog )
  599. {
  600. if ( m_DialogStack.Count() )
  601. {
  602. if ( m_DialogStack.Top() )
  603. {
  604. m_DialogStack.Top()->Close();
  605. }
  606. else
  607. {
  608. m_DialogStack.Pop();
  609. }
  610. }
  611. hDialog->Activate();
  612. m_DialogStack.Push( hDialog );
  613. }
  614. //-----------------------------------------------------------------------------
  615. // Purpose: Close the current dialog, pop it from the top of the stack, and activate the next one.
  616. //-----------------------------------------------------------------------------
  617. void CMatchmakingBasePanel::PopDialog( bool bActivateNext )
  618. {
  619. if ( m_DialogStack.Count() > 1 )
  620. {
  621. if ( m_DialogStack.Top() )
  622. {
  623. m_DialogStack.Top()->SetDeleteSelfOnClose( true );
  624. m_DialogStack.Top()->Close();
  625. m_DialogStack.Pop();
  626. }
  627. // Drop down to the next available dialog
  628. while ( m_DialogStack.Count() && !m_DialogStack.Top() )
  629. {
  630. m_DialogStack.Pop();
  631. }
  632. if ( bActivateNext && m_DialogStack.Count() && m_DialogStack.Top() )
  633. {
  634. m_DialogStack.Top()->Activate();
  635. }
  636. }
  637. if ( m_DialogStack.Count() <= 1 )
  638. {
  639. // Back at the welcome menu
  640. m_bPlayingOnline = false;
  641. }
  642. }
  643. //-----------------------------------------------------------------------------
  644. // Purpose: Close all open dialogs down to the main menu
  645. //-----------------------------------------------------------------------------
  646. void CMatchmakingBasePanel::CloseGameDialogs( bool bActivateNext )
  647. {
  648. CloseBaseDialogs();
  649. while ( m_DialogStack.Count() > 1 )
  650. {
  651. PopDialog( bActivateNext );
  652. }
  653. }
  654. //-----------------------------------------------------------------------------
  655. // Purpose: Close all open dialogs down to the main menu
  656. //-----------------------------------------------------------------------------
  657. void CMatchmakingBasePanel::CloseAllDialogs( bool bActivateNext )
  658. {
  659. GameUI().CloseMessageDialog();
  660. CloseGameDialogs( bActivateNext );
  661. }
  662. //-----------------------------------------------------------------------------
  663. // Purpose:
  664. //-----------------------------------------------------------------------------
  665. void CMatchmakingBasePanel::CloseBaseDialogs( void )
  666. {
  667. if ( BasePanel() )
  668. {
  669. BasePanel()->CloseBaseDialogs();
  670. }
  671. }
  672. //-----------------------------------------------------------------------------
  673. // Purpose: Get session property keyvalues from base panel and matchmaking
  674. //-----------------------------------------------------------------------------
  675. void CMatchmakingBasePanel::LoadSessionProperties()
  676. {
  677. // Grab the session property keys from XboxDialogs.res and from matchmaking
  678. m_pSessionKeys = BasePanel()->GetConsoleControlSettings()->FindKey( "PropertyDisplayKeys" );
  679. if ( m_pSessionKeys )
  680. {
  681. m_pSessionKeys->ChainKeyValue( matchmaking->GetSessionProperties() );
  682. }
  683. // Cache off the map name
  684. const char *pDiskName = NULL;
  685. KeyValues *pName = m_pSessionKeys->FindKey( "MapDiskNames" );
  686. if ( pName )
  687. {
  688. KeyValues *pScenario = m_pSessionKeys->FindKey( "CONTEXT_SCENARIO" );
  689. if ( pScenario )
  690. {
  691. pDiskName = pName->GetString( pScenario->GetString( "displaystring" ), NULL );
  692. }
  693. }
  694. if ( pDiskName )
  695. {
  696. Q_strncpy( m_szMapLoadName, pDiskName, sizeof( m_szMapLoadName ) );
  697. Msg( "Storing mapname %s\n", m_szMapLoadName );
  698. if ( Q_strlen( m_szMapLoadName ) < 5 )
  699. {
  700. Warning( "Bad map name!\n" );
  701. }
  702. }
  703. else
  704. {
  705. // X360TBD: Generate a create error
  706. }
  707. }
  708. //-----------------------------------------------------------------------------
  709. // Purpose: Open dialog functions.
  710. //-----------------------------------------------------------------------------
  711. void CMatchmakingBasePanel::OnOpenWelcomeDialog()
  712. {
  713. if ( !m_hWelcomeDialog.Get() )
  714. {
  715. m_hWelcomeDialog = new CWelcomeDialog( this );
  716. m_DialogStack.Push( m_hWelcomeDialog );
  717. }
  718. m_hWelcomeDialog->Activate();
  719. m_bPlayingOnline = false;
  720. }
  721. void CMatchmakingBasePanel::OnOpenPauseDialog()
  722. {
  723. if ( !m_hPauseDialog.Get() )
  724. {
  725. m_hPauseDialog = new CPauseDialog( this );
  726. }
  727. PushDialog( m_hPauseDialog );
  728. }
  729. void CMatchmakingBasePanel::OnOpenRankingsDialog()
  730. {
  731. if ( !ValidateSigninAndStorage( true, "OpenRankingDialog" ) )
  732. return;
  733. if ( !m_hRankingsDialog.Get() )
  734. {
  735. m_hRankingsDialog = new CBaseDialog( this, "RankingsDialog" );
  736. }
  737. PushDialog( m_hRankingsDialog );
  738. }
  739. void CMatchmakingBasePanel::OnOpenSystemLinkDialog()
  740. {
  741. if ( !ValidateSigninAndStorage( false, "OpenSystemLinkDialog" ) )
  742. return;
  743. if ( !m_hSystemLinkDialog.Get() )
  744. {
  745. m_hSystemLinkDialog = new CBaseDialog( this, "SystemLinkDialog" );
  746. }
  747. PushDialog( m_hSystemLinkDialog );
  748. }
  749. void CMatchmakingBasePanel::OnOpenPlayerMatchDialog()
  750. {
  751. if ( !ValidateSigninAndStorage( true, "OpenPlayerMatchDialog" ) )
  752. return;
  753. if ( !m_hPlayerMatchDialog.Get() )
  754. {
  755. m_hPlayerMatchDialog = new CBaseDialog( this, "PlayerMatchDialog" );
  756. }
  757. PushDialog( m_hPlayerMatchDialog );
  758. m_bPlayingOnline = true;
  759. }
  760. void CMatchmakingBasePanel::OnOpenRankedMatchDialog()
  761. {
  762. if ( !ValidateSigninAndStorage( true, "OpenRankedMatchDialog" ) )
  763. return;
  764. if ( !m_hRankedMatchDialog.Get() )
  765. {
  766. m_hRankedMatchDialog = new CBaseDialog( this, "RankedMatchDialog" );
  767. }
  768. PushDialog( m_hRankedMatchDialog );
  769. m_bPlayingOnline = true;
  770. }
  771. void CMatchmakingBasePanel::OnOpenAchievementsDialog()
  772. {
  773. if ( !ValidateSigninAndStorage( false, "OpenAchievementsDialog" ) )
  774. return;
  775. if ( !m_hAchievementsDialog.Get() )
  776. {
  777. m_hAchievementsDialog = new CAchievementsDialog_XBox( this );
  778. }
  779. PushDialog( m_hAchievementsDialog );
  780. }
  781. //=============================================================================
  782. // HPE_BEGIN:
  783. // [dwenger] Specific code for CS Achievements Display
  784. //=============================================================================
  785. void CMatchmakingBasePanel::OnOpenCSAchievementsDialog()
  786. {
  787. if ( !ValidateSigninAndStorage( false, "OpenCSAchievementsDialog" ) )
  788. return;
  789. if ( !m_hAchievementsDialog.Get() )
  790. {
  791. // $TODO(HPE): m_hAchievementsDialog = new CAchievementsDialog_XBox( this );
  792. }
  793. PushDialog( m_hAchievementsDialog );
  794. }
  795. //=============================================================================
  796. // HPE_END
  797. //=============================================================================
  798. void CMatchmakingBasePanel::OnOpenSessionOptionsDialog( const char *pResourceName )
  799. {
  800. if ( !m_hSessionOptionsDialog.Get() )
  801. {
  802. m_hSessionOptionsDialog = new CSessionOptionsDialog( this );
  803. }
  804. if ( Q_stristr( pResourceName, "Ranked" ) )
  805. {
  806. m_nGameType = GAMETYPE_RANKED_MATCH;
  807. }
  808. else if ( Q_stristr( pResourceName, "Standard" ) )
  809. {
  810. m_nGameType = GAMETYPE_STANDARD_MATCH;
  811. }
  812. else if ( Q_stristr( pResourceName, "SystemLink" ) )
  813. {
  814. m_nGameType = GAMETYPE_SYSTEMLINK_MATCH;
  815. }
  816. LoadSessionProperties();
  817. CSessionOptionsDialog* pDlg = ((CSessionOptionsDialog*)m_hSessionOptionsDialog.Get());
  818. pDlg->SetGameType( pResourceName );
  819. pDlg->SetDialogKeys( m_pSessionKeys );
  820. PushDialog( m_hSessionOptionsDialog );
  821. }
  822. void CMatchmakingBasePanel::OnOpenSessionLobbyDialog( const char *pResourceName )
  823. {
  824. if ( !m_hSessionLobbyDialog.Get() )
  825. {
  826. m_hSessionLobbyDialog = new CSessionLobbyDialog( this );
  827. }
  828. CSessionLobbyDialog *pDlg = (CSessionLobbyDialog*)m_hSessionLobbyDialog.Get();
  829. pDlg->SetDialogKeys( m_pSessionKeys );
  830. m_hSessionLobbyDialog->SetName( pResourceName );
  831. PushDialog( m_hSessionLobbyDialog );
  832. }
  833. void CMatchmakingBasePanel::OnOpenSessionBrowserDialog( const char *pResourceName )
  834. {
  835. if ( !m_hSessionBrowserDialog.Get() )
  836. {
  837. m_hSessionBrowserDialog = new CSessionBrowserDialog( this, m_pSessionKeys );
  838. m_hSessionBrowserDialog->SetName( pResourceName );
  839. // Matchmaking will start adding results immediately, so prepare the dialog
  840. SETUP_PANEL( m_hSessionBrowserDialog.Get() );
  841. }
  842. PushDialog( m_hSessionBrowserDialog );
  843. }
  844. void CMatchmakingBasePanel::OnOpenLeaderboardDialog( const char *pResourceName )
  845. {
  846. if ( !m_hLeaderboardDialog.Get() )
  847. {
  848. m_hLeaderboardDialog = new CLeaderboardDialog( this );
  849. m_hLeaderboardDialog->SetName( pResourceName );
  850. SETUP_PANEL( m_hLeaderboardDialog.Get() );
  851. }
  852. PushDialog( m_hLeaderboardDialog );
  853. m_hLeaderboardDialog->OnCommand( "CenterOnPlayer" );
  854. }
  855. //-----------------------------------------------------------------------------
  856. // Purpose: Callback function to start map load after ui fades out.
  857. //-----------------------------------------------------------------------------
  858. void CMatchmakingBasePanel::LoadMap( const char *mapname )
  859. {
  860. CloseAllDialogs( false );
  861. char cmd[MAX_PATH];
  862. Q_snprintf( cmd, sizeof( cmd ), "map %s", m_szMapLoadName );
  863. BasePanel()->FadeToBlackAndRunEngineCommand( cmd );
  864. }
  865. //-------------------------------------------------------
  866. // Keyboard input
  867. //-------------------------------------------------------
  868. void CMatchmakingBasePanel::OnKeyCodePressed( vgui::KeyCode code )
  869. {
  870. switch( code )
  871. {
  872. case KEY_XBUTTON_B:
  873. // Can't close the matchmaking base panel
  874. break;
  875. default:
  876. BaseClass::OnKeyCodePressed( code );
  877. break;
  878. }
  879. }