Counter Strike : Global Offensive Source Code
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.

319 lines
9.3 KiB

  1. //========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "pch_serverbrowser.h"
  8. using namespace vgui;
  9. // How often to re-sort the server list
  10. const float MINIMUM_SORT_TIME = 1.5f;
  11. //-----------------------------------------------------------------------------
  12. // Purpose: Constructor
  13. // NOTE: m_Servers can not use more than 96 sockets, else it will
  14. // cause internet explorer to Stop working under win98 SE!
  15. //-----------------------------------------------------------------------------
  16. CInternetGames::CInternetGames(vgui::Panel *parent, const char *panelName, EPageType eType ) :
  17. CBaseGamesPage(parent, panelName, eType )
  18. {
  19. m_fLastSort = 0.0f;
  20. m_bDirty = false;
  21. m_bRequireUpdate = true;
  22. m_bOfflineMode = !IsSteamGameServerBrowsingEnabled();
  23. m_bAnyServersRetrievedFromMaster = false;
  24. m_bNoServersListedOnMaster = false;
  25. m_bAnyServersRespondedToQuery = false;
  26. m_pLocationFilter->DeleteAllItems();
  27. KeyValues *kv = new KeyValues("Regions");
  28. if (kv->LoadFromFile( g_pFullFileSystem, "servers/Regions.vdf", NULL))
  29. {
  30. // iterate the list loading all the servers
  31. for (KeyValues *srv = kv->GetFirstSubKey(); srv != NULL; srv = srv->GetNextKey())
  32. {
  33. struct regions_s region;
  34. region.name = srv->GetString("text");
  35. region.code = srv->GetInt("code");
  36. KeyValues *regionKV = new KeyValues("region", "code", region.code);
  37. m_pLocationFilter->AddItem( region.name.String(), regionKV );
  38. regionKV->deleteThis();
  39. m_Regions.AddToTail(region);
  40. }
  41. }
  42. else
  43. {
  44. Assert(!("Could not load file servers/Regions.vdf; server browser will not function."));
  45. }
  46. kv->deleteThis();
  47. LoadFilterSettings();
  48. ivgui()->AddTickSignal( GetVPanel(), 250 );
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Destructor
  52. //-----------------------------------------------------------------------------
  53. CInternetGames::~CInternetGames()
  54. {
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose:
  58. //-----------------------------------------------------------------------------
  59. void CInternetGames::PerformLayout()
  60. {
  61. if ( !m_bOfflineMode && m_bRequireUpdate && ServerBrowserDialog().IsVisible() )
  62. {
  63. PostMessage( this, new KeyValues( "GetNewServerList" ), 0.1f );
  64. m_bRequireUpdate = false;
  65. }
  66. if ( m_bOfflineMode )
  67. {
  68. m_pGameList->SetEmptyListText("#ServerBrowser_OfflineMode");
  69. m_pConnect->SetEnabled( false );
  70. m_pRefreshAll->SetEnabled( false );
  71. m_pRefreshQuick->SetEnabled( false );
  72. m_pAddServer->SetEnabled( false );
  73. m_pFilter->SetEnabled( false );
  74. }
  75. BaseClass::PerformLayout();
  76. m_pLocationFilter->SetEnabled(true);
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Purpose: Activates the page, starts refresh if needed
  80. //-----------------------------------------------------------------------------
  81. void CInternetGames::OnPageShow()
  82. {
  83. if ( m_pGameList->GetItemCount() == 0 && ServerBrowserDialog().IsVisible() )
  84. BaseClass::OnPageShow();
  85. // the "internet games" tab (unlike the other browser tabs)
  86. // does not automatically start a query when the user
  87. // navigates to this tab unless they have no servers listed.
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose: Called every frame, maintains sockets and runs refreshes
  91. //-----------------------------------------------------------------------------
  92. void CInternetGames::OnTick()
  93. {
  94. if ( m_bOfflineMode )
  95. {
  96. BaseClass::OnTick();
  97. return;
  98. }
  99. BaseClass::OnTick();
  100. CheckRedoSort();
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Purpose: Handles incoming server refresh data
  104. // updates the server browser with the refreshed information from the server itself
  105. //-----------------------------------------------------------------------------
  106. void CInternetGames::ServerResponded( HServerListRequest hReq, int iServer )
  107. {
  108. m_bDirty = true;
  109. BaseClass::ServerResponded( hReq, iServer );
  110. m_bAnyServersRespondedToQuery = true;
  111. m_bAnyServersRetrievedFromMaster = true;
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Purpose:
  115. //-----------------------------------------------------------------------------
  116. void CInternetGames::ServerFailedToRespond( HServerListRequest hReq, int iServer )
  117. {
  118. m_bDirty = true;
  119. gameserveritem_t *pServer = steamapicontext->SteamMatchmakingServers()->GetServerDetails( hReq, iServer );
  120. Assert( pServer );
  121. if ( pServer->m_bHadSuccessfulResponse )
  122. {
  123. // if it's had a successful response in the past, leave it on
  124. ServerResponded( hReq, iServer );
  125. }
  126. else
  127. {
  128. int iServerMap = m_mapServers.Find( iServer );
  129. if ( iServerMap != m_mapServers.InvalidIndex() )
  130. RemoveServer( m_mapServers[ iServerMap ] );
  131. // we've never had a good response from this server, remove it from the list
  132. m_iServerRefreshCount++;
  133. }
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Purpose: Called when server refresh has been completed
  137. //-----------------------------------------------------------------------------
  138. void CInternetGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response )
  139. {
  140. SetRefreshing(false);
  141. UpdateFilterSettings();
  142. if ( response != eServerFailedToRespond )
  143. {
  144. if ( m_bAnyServersRespondedToQuery )
  145. {
  146. m_pGameList->SetEmptyListText( GetStringNoUnfilteredServers() );
  147. }
  148. else if ( response == eNoServersListedOnMasterServer )
  149. {
  150. m_pGameList->SetEmptyListText( GetStringNoUnfilteredServersOnMaster() );
  151. }
  152. else
  153. {
  154. m_pGameList->SetEmptyListText( GetStringNoServersResponded() );
  155. }
  156. }
  157. else
  158. {
  159. m_pGameList->SetEmptyListText("#ServerBrowser_MasterServerNotResponsive");
  160. }
  161. // perform last sort
  162. m_bDirty = false;
  163. m_fLastSort = Plat_FloatTime();
  164. if (IsVisible())
  165. {
  166. m_pGameList->SortList();
  167. }
  168. UpdateStatus();
  169. BaseClass::RefreshComplete( hReq, response );
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Purpose:
  173. //-----------------------------------------------------------------------------
  174. void CInternetGames::GetNewServerList()
  175. {
  176. BaseClass::GetNewServerList();
  177. UpdateStatus();
  178. m_bRequireUpdate = false;
  179. m_bAnyServersRetrievedFromMaster = false;
  180. m_bAnyServersRespondedToQuery = false;
  181. m_pGameList->DeleteAllItems();
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose: returns true if the game list supports the specified ui elements
  185. //-----------------------------------------------------------------------------
  186. bool CInternetGames::SupportsItem(IGameList::InterfaceItem_e item)
  187. {
  188. switch (item)
  189. {
  190. case FILTERS:
  191. case GETNEWLIST:
  192. return true;
  193. default:
  194. return false;
  195. }
  196. }
  197. //-----------------------------------------------------------------------------
  198. // Purpose:
  199. //-----------------------------------------------------------------------------
  200. void CInternetGames::CheckRedoSort( void )
  201. {
  202. float fCurTime;
  203. // No changes detected
  204. if ( !m_bDirty )
  205. return;
  206. fCurTime = Plat_FloatTime();
  207. // Not time yet
  208. if ( fCurTime - m_fLastSort < MINIMUM_SORT_TIME)
  209. return;
  210. // postpone sort if mouse button is down
  211. if ( input()->IsMouseDown(MOUSE_LEFT) || input()->IsMouseDown(MOUSE_RIGHT) )
  212. {
  213. // don't sort for at least another second
  214. m_fLastSort = fCurTime - MINIMUM_SORT_TIME + 1.0f;
  215. return;
  216. }
  217. // Reset timer
  218. m_bDirty = false;
  219. m_fLastSort = fCurTime;
  220. // Force sort to occur now!
  221. m_pGameList->SortList();
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose: opens context menu (user right clicked on a server)
  225. //-----------------------------------------------------------------------------
  226. void CInternetGames::OnOpenContextMenu(int itemID)
  227. {
  228. // get the server
  229. int serverID = GetSelectedServerID();
  230. if ( serverID == -1 )
  231. return;
  232. // Activate context menu
  233. CServerContextMenu *menu = ServerBrowserDialog().GetContextMenu(GetActiveList());
  234. menu->ShowMenu(this, serverID, true, true, true, true);
  235. }
  236. //-----------------------------------------------------------------------------
  237. // Purpose: refreshes a single server
  238. //-----------------------------------------------------------------------------
  239. void CInternetGames::OnRefreshServer(int serverID)
  240. {
  241. BaseClass::OnRefreshServer( serverID );
  242. ServerBrowserDialog().UpdateStatusText("#ServerBrowser_GettingNewServerList");
  243. }
  244. //-----------------------------------------------------------------------------
  245. // Purpose: get the region code selected in the ui
  246. // Output: returns the region code the user wants to filter by
  247. //-----------------------------------------------------------------------------
  248. int CInternetGames::GetRegionCodeToFilter()
  249. {
  250. KeyValues *kv = m_pLocationFilter->GetActiveItemUserData();
  251. if ( kv )
  252. return kv->GetInt( "code" );
  253. else
  254. return 255;
  255. }
  256. //-----------------------------------------------------------------------------
  257. // Purpose:
  258. //-----------------------------------------------------------------------------
  259. bool CInternetGames::CheckTagFilter( gameserveritem_t &server )
  260. {
  261. // Servers without tags go in the official games, servers with tags go in custom games
  262. bool bOfficialServer = !( server.m_szGameTags && server.m_szGameTags[0] );
  263. if ( !bOfficialServer )
  264. return false;
  265. return true;
  266. }