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.

366 lines
13 KiB

  1. //========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "pch_serverbrowser.h"
  8. #include "vstdlib/vstrtools.h"
  9. using namespace vgui;
  10. //-----------------------------------------------------------------------------
  11. // Purpose: Constructor
  12. // Input : *gameList - game list to add specified server to
  13. //-----------------------------------------------------------------------------
  14. CDialogAddServer::CDialogAddServer(vgui::Panel *parent, IGameList *gameList) : Frame(parent, "DialogAddServer")
  15. {
  16. SetDeleteSelfOnClose(true);
  17. m_pGameList = gameList;
  18. SetTitle("#ServerBrowser_AddServersTitle", true);
  19. SetSizeable( false );
  20. m_pTabPanel = new PropertySheet(this, "GameTabs");
  21. m_pTabPanel->SetTabWidth(72);
  22. m_pDiscoveredGames = new ListPanel( this, "Servers" );
  23. // Add the column headers
  24. m_pDiscoveredGames->AddColumnHeader(0, "Password", "#ServerBrowser_Password", 16, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE);
  25. m_pDiscoveredGames->AddColumnHeader(1, "Bots", "#ServerBrowser_Bots", 16, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE | ListPanel::COLUMN_HIDDEN);
  26. m_pDiscoveredGames->AddColumnHeader(2, "Secure", "#ServerBrowser_Secure", 16, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE);
  27. m_pDiscoveredGames->AddColumnHeader(3, "Name", "#ServerBrowser_Servers", 20, ListPanel::COLUMN_RESIZEWITHWINDOW | ListPanel::COLUMN_UNHIDABLE);
  28. m_pDiscoveredGames->AddColumnHeader(4, "IPAddr", "#ServerBrowser_IPAddress", 60, ListPanel::COLUMN_HIDDEN);
  29. m_pDiscoveredGames->AddColumnHeader(5, "GameDesc", "#ServerBrowser_Game", 150);
  30. m_pDiscoveredGames->AddColumnHeader(6, "Players", "#ServerBrowser_Players", 60);
  31. m_pDiscoveredGames->AddColumnHeader(7, "Map", "#ServerBrowser_Map", 80);
  32. m_pDiscoveredGames->AddColumnHeader(8, "Ping", "#ServerBrowser_Latency", 60);
  33. m_pDiscoveredGames->SetColumnHeaderTooltip(0, "#ServerBrowser_PasswordColumn_Tooltip");
  34. m_pDiscoveredGames->SetColumnHeaderTooltip(1, "#ServerBrowser_BotColumn_Tooltip");
  35. m_pDiscoveredGames->SetColumnHeaderTooltip(2, "#ServerBrowser_SecureColumn_Tooltip");
  36. // setup fast sort functions
  37. m_pDiscoveredGames->SetSortFunc(0, PasswordCompare);
  38. m_pDiscoveredGames->SetSortFunc(1, BotsCompare);
  39. m_pDiscoveredGames->SetSortFunc(2, SecureCompare);
  40. m_pDiscoveredGames->SetSortFunc(3, ServerNameCompare);
  41. m_pDiscoveredGames->SetSortFunc(4, IPAddressCompare);
  42. m_pDiscoveredGames->SetSortFunc(5, GameCompare);
  43. m_pDiscoveredGames->SetSortFunc(6, PlayersCompare);
  44. m_pDiscoveredGames->SetSortFunc(7, MapCompare);
  45. m_pDiscoveredGames->SetSortFunc(8, PingCompare);
  46. m_pDiscoveredGames->SetSortColumn(8); // sort on ping
  47. m_pTextEntry = new vgui::TextEntry( this, "ServerNameText" );
  48. m_pTextEntry->AddActionSignalTarget( this );
  49. m_pTestServersButton = new vgui::Button( this, "TestServersButton", "" );
  50. m_pAddServerButton = new vgui::Button( this, "OKButton", "" );
  51. m_pAddSelectedServerButton = new vgui::Button( this, "SelectedOKButton", "", this, "addselected" );
  52. m_pTabPanel->AddPage( m_pDiscoveredGames, "#ServerBrowser_Servers" );
  53. LoadControlSettings("Servers/DialogAddServer.res");
  54. // Setup the buttons. We leave them disabled until there is text in the textbox.
  55. m_pAddServerButton->SetEnabled( false );
  56. m_pTestServersButton->SetEnabled( false );
  57. m_pAddSelectedServerButton->SetEnabled( false );
  58. m_pAddSelectedServerButton->SetVisible( false );
  59. m_pTabPanel->SetVisible( false );
  60. m_pTextEntry->RequestFocus();
  61. // Initially, we aren't high enough to show the tab panel.
  62. int x, y;
  63. m_pTabPanel->GetPos( x, y );
  64. m_OriginalHeight = m_pTabPanel->GetTall() + y + 50;
  65. SetTall( y );
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Purpose: Destructor
  69. //-----------------------------------------------------------------------------
  70. CDialogAddServer::~CDialogAddServer()
  71. {
  72. FOR_EACH_VEC( m_Queries, i )
  73. {
  74. if ( steamapicontext->SteamMatchmakingServers() )
  75. steamapicontext->SteamMatchmakingServers()->CancelServerQuery( m_Queries[ i ] );
  76. }
  77. }
  78. //-----------------------------------------------------------------------------
  79. // Lets us know when the text entry has changed.
  80. //-----------------------------------------------------------------------------
  81. void CDialogAddServer::OnTextChanged()
  82. {
  83. bool bAnyText = (m_pTextEntry->GetTextLength() > 0);
  84. m_pAddServerButton->SetEnabled( bAnyText );
  85. m_pTestServersButton->SetEnabled( bAnyText );
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Purpose: button command handler
  89. //-----------------------------------------------------------------------------
  90. void CDialogAddServer::OnCommand(const char *command)
  91. {
  92. if ( Q_stricmp(command, "OK") == 0 )
  93. {
  94. OnOK();
  95. }
  96. else if ( Q_stricmp( command, "TestServers" ) == 0 )
  97. {
  98. SetTall( m_OriginalHeight );
  99. m_pTabPanel->SetVisible( true );
  100. m_pAddSelectedServerButton->SetVisible( true );
  101. TestServers();
  102. }
  103. else if ( !Q_stricmp( command, "addselected" ) )
  104. {
  105. if ( m_pDiscoveredGames->GetSelectedItemsCount() )
  106. {
  107. // get the server
  108. int serverID = m_pDiscoveredGames->GetItemUserData( m_pDiscoveredGames->GetSelectedItem(0) );
  109. FinishAddServer( m_Servers[ serverID ] );
  110. m_pDiscoveredGames->RemoveItem( m_pDiscoveredGames->GetSelectedItem(0) ); // as we add to favs remove from the list
  111. m_pDiscoveredGames->SetEmptyListText( "" );
  112. }
  113. }
  114. else
  115. {
  116. BaseClass::OnCommand(command);
  117. }
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Purpose: Handles the OK button being pressed; adds the server to the game list
  121. //-----------------------------------------------------------------------------
  122. void CDialogAddServer::OnOK()
  123. {
  124. // try and parse out IP address
  125. const char *address = GetControlString("ServerNameText", "");
  126. netadr_t netaddr;
  127. netaddr.SetFromString( address, true );
  128. if ( !netaddr.GetPort() && !AllowInvalidIPs() )
  129. {
  130. // use the default port since it was not entered
  131. netaddr.SetPort( 27015 );
  132. }
  133. if ( AllowInvalidIPs() || netaddr.IsValid() )
  134. {
  135. gameserveritem_t server;
  136. memset(&server, 0, sizeof(server));
  137. server.SetName( address );
  138. // We assume here that the query and connection ports are the same. This is why it's much
  139. // better if they click "Servers" and choose a server in there.
  140. server.m_NetAdr.Init( netaddr.GetIPHostByteOrder(), netaddr.GetPort(), netaddr.GetPort() );
  141. server.m_nAppID = 0;
  142. FinishAddServer( server );
  143. }
  144. else
  145. {
  146. // could not parse the ip address, popup an error
  147. MessageBox *dlg = new MessageBox("#ServerBrowser_AddServerErrorTitle", "#ServerBrowser_AddServerError");
  148. dlg->DoModal();
  149. }
  150. // mark ourselves to be closed
  151. PostMessage(this, new KeyValues("Close"));
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose: Ping a particular IP for server presence
  155. //-----------------------------------------------------------------------------
  156. void CDialogAddServer::TestServers()
  157. {
  158. if ( !steamapicontext->SteamMatchmakingServers() )
  159. return;
  160. m_pDiscoveredGames->SetEmptyListText( "" );
  161. // If they specified a port, then send a query to that port.
  162. const char *address = GetControlString("ServerNameText", "");
  163. netadr_t netaddr;
  164. netaddr.SetFromString( address, true );
  165. m_Servers.RemoveAll();
  166. CUtlVector<netadr_t> vecAdress;
  167. if ( netaddr.GetPort() == 0 )
  168. {
  169. // No port specified. Go to town on the ports.
  170. CUtlVector<uint16> portsToTry;
  171. GetMostCommonQueryPorts( portsToTry );
  172. for ( int i=0; i < portsToTry.Count(); i++ )
  173. {
  174. netadr_t newAddr = netaddr;
  175. newAddr.SetPort( portsToTry[i] );
  176. vecAdress.AddToTail( newAddr );
  177. }
  178. }
  179. else
  180. {
  181. vecAdress.AddToTail( netaddr );
  182. }
  183. // Change the text on the tab panel..
  184. m_pTabPanel->RemoveAllPages();
  185. wchar_t wstr[512];
  186. if ( address[0] == 0 )
  187. {
  188. Q_wcsncpy( wstr, g_pVGuiLocalize->Find( "#ServerBrowser_ServersRespondingLocal"), sizeof( wstr ) );
  189. }
  190. else
  191. {
  192. wchar_t waddress[512];
  193. Q_UTF8ToUnicode( address, waddress, sizeof( waddress ) );
  194. g_pVGuiLocalize->ConstructString( wstr, sizeof( wstr ), g_pVGuiLocalize->Find( "#ServerBrowser_ServersResponding"), 1, waddress );
  195. }
  196. char str[512];
  197. Q_UnicodeToUTF8( wstr, str, sizeof( str ) );
  198. m_pTabPanel->AddPage( m_pDiscoveredGames, str );
  199. m_pTabPanel->InvalidateLayout();
  200. FOR_EACH_VEC( vecAdress, iAddress )
  201. {
  202. m_Queries.AddToTail( steamapicontext->SteamMatchmakingServers()->PingServer( vecAdress[ iAddress ].GetIPHostByteOrder(), vecAdress[ iAddress ].GetPort(), this ) );
  203. }
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Purpose: A server answered our ping
  207. //-----------------------------------------------------------------------------
  208. void CDialogAddServer::ServerResponded( gameserveritem_t &server )
  209. {
  210. KeyValues *kv = new KeyValues( "Server" );
  211. kv->SetString( "name", server.GetName() );
  212. kv->SetString( "map", server.m_szMap );
  213. kv->SetString( "GameDir", server.m_szGameDir );
  214. kv->SetString( "GameDesc", server.m_szGameDescription );
  215. kv->SetString( "GameTags", server.m_szGameTags );
  216. kv->SetBool( "password", server.m_bPassword );
  217. kv->SetInt( "bots", server.m_nBotPlayers ? 2 : 0);
  218. if ( server.m_bSecure )
  219. {
  220. // show the denied icon if banned from secure servers, the secure icon otherwise
  221. kv->SetInt("secure", ServerBrowser().IsVACBannedFromGame( server.m_nAppID ) ? 4 : 3);
  222. }
  223. else
  224. {
  225. kv->SetInt("secure", 0);
  226. }
  227. netadr_t reportedIPAddr;
  228. reportedIPAddr.SetIP( server.m_NetAdr.GetIP() );
  229. reportedIPAddr.SetPort( server.m_NetAdr.GetConnectionPort() );
  230. kv->SetString("IPAddr", reportedIPAddr.ToString() );
  231. char buf[32];
  232. Q_snprintf(buf, sizeof(buf), "%d / %d", server.m_nPlayers, server.m_nMaxPlayers);
  233. kv->SetString("Players", buf);
  234. kv->SetInt("Ping", server.m_nPing);
  235. // new server, add to list
  236. int iServer = m_Servers.AddToTail( server );
  237. int iListID = m_pDiscoveredGames->AddItem(kv, iServer, false, false);
  238. if ( m_pDiscoveredGames->GetItemCount() == 1 )
  239. {
  240. m_pDiscoveredGames->AddSelectedItem( iListID );
  241. }
  242. kv->deleteThis();
  243. m_pDiscoveredGames->InvalidateLayout();
  244. }
  245. void CDialogAddServer::ServerFailedToRespond()
  246. {
  247. m_pDiscoveredGames->SetEmptyListText( "#ServerBrowser_ServerNotResponding" );
  248. }
  249. void CDialogAddServer::ApplySchemeSettings( IScheme *pScheme )
  250. {
  251. BaseClass::ApplySchemeSettings( pScheme );
  252. ImageList *imageList = new ImageList(false);
  253. imageList->AddImage(scheme()->GetImage("servers/icon_password", false));
  254. imageList->AddImage(scheme()->GetImage("servers/icon_bots", false));
  255. imageList->AddImage(scheme()->GetImage("servers/icon_robotron", false));
  256. imageList->AddImage(scheme()->GetImage("servers/icon_secure_deny", false));
  257. int passwordColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_password_column", false));
  258. int botColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_bots_column", false));
  259. int secureColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_robotron_column", false));
  260. m_pDiscoveredGames->SetImageList(imageList, true);
  261. vgui::HFont hFont = pScheme->GetFont( "ListSmall", IsProportional() );
  262. if ( !hFont )
  263. hFont = pScheme->GetFont( "DefaultSmall", IsProportional() );
  264. m_pDiscoveredGames->SetFont( hFont );
  265. m_pDiscoveredGames->SetColumnHeaderImage(0, passwordColumnImage);
  266. m_pDiscoveredGames->SetColumnHeaderImage(1, botColumnImage);
  267. m_pDiscoveredGames->SetColumnHeaderImage(2, secureColumnImage);
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Purpose: A server on the listed IP responded
  271. //-----------------------------------------------------------------------------
  272. void CDialogAddServer::OnItemSelected()
  273. {
  274. int nSelectedItem = m_pDiscoveredGames->GetSelectedItem(0);
  275. if( nSelectedItem != -1 )
  276. {
  277. m_pAddSelectedServerButton->SetEnabled( true );
  278. }
  279. else
  280. {
  281. m_pAddSelectedServerButton->SetEnabled( false );
  282. }
  283. }
  284. //-----------------------------------------------------------------------------
  285. // Purpose:
  286. //-----------------------------------------------------------------------------
  287. void CDialogAddServer::FinishAddServer( gameserveritem_t &pServer )
  288. {
  289. ServerBrowserDialog().AddServerToFavorites( pServer );
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Purpose:
  293. //-----------------------------------------------------------------------------
  294. void CDialogAddBlacklistedServer::FinishAddServer( gameserveritem_t &pServer )
  295. {
  296. ServerBrowserDialog().AddServerToBlacklist( pServer );
  297. ServerBrowserDialog().BlacklistsChanged();
  298. }
  299. //-----------------------------------------------------------------------------
  300. // Purpose:
  301. //-----------------------------------------------------------------------------
  302. void CDialogAddBlacklistedServer::ApplySchemeSettings( vgui::IScheme *pScheme )
  303. {
  304. BaseClass::ApplySchemeSettings( pScheme );
  305. m_pAddServerButton->SetText( "#ServerBrowser_AddAddressToBlacklist" );
  306. m_pAddSelectedServerButton->SetText( "#ServerBrowser_AddSelectedToBlacklist" );
  307. }