source-engine/serverbrowser/InternetGames.cpp

320 lines
9.3 KiB
C++
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "pch_serverbrowser.h"
using namespace vgui;
// How often to re-sort the server list
const float MINIMUM_SORT_TIME = 1.5f;
//-----------------------------------------------------------------------------
// Purpose: Constructor
// NOTE: m_Servers can not use more than 96 sockets, else it will
// cause internet explorer to Stop working under win98 SE!
//-----------------------------------------------------------------------------
CInternetGames::CInternetGames(vgui::Panel *parent, const char *panelName, EPageType eType ) :
CBaseGamesPage(parent, panelName, eType )
{
m_fLastSort = 0.0f;
m_bDirty = false;
m_bRequireUpdate = true;
m_bOfflineMode = !IsSteamGameServerBrowsingEnabled();
m_bAnyServersRetrievedFromMaster = false;
m_bNoServersListedOnMaster = false;
m_bAnyServersRespondedToQuery = false;
m_pLocationFilter->DeleteAllItems();
KeyValues *kv = new KeyValues("Regions");
if (kv->LoadFromFile( g_pFullFileSystem, "servers/Regions.vdf", NULL))
{
// iterate the list loading all the servers
for (KeyValues *srv = kv->GetFirstSubKey(); srv != NULL; srv = srv->GetNextKey())
{
struct regions_s region;
region.name = srv->GetString("text");
region.code = srv->GetInt("code");
KeyValues *regionKV = new KeyValues("region", "code", region.code);
m_pLocationFilter->AddItem( region.name.String(), regionKV );
regionKV->deleteThis();
m_Regions.AddToTail(region);
}
}
else
{
Assert(!("Could not load file servers/Regions.vdf; server browser will not function."));
}
kv->deleteThis();
LoadFilterSettings();
ivgui()->AddTickSignal( GetVPanel(), 250 );
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CInternetGames::~CInternetGames()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInternetGames::PerformLayout()
{
if ( !m_bOfflineMode && m_bRequireUpdate && ServerBrowserDialog().IsVisible() )
{
PostMessage( this, new KeyValues( "GetNewServerList" ), 0.1f );
m_bRequireUpdate = false;
}
if ( m_bOfflineMode )
{
m_pGameList->SetEmptyListText("#ServerBrowser_OfflineMode");
m_pConnect->SetEnabled( false );
m_pRefreshAll->SetEnabled( false );
m_pRefreshQuick->SetEnabled( false );
m_pAddServer->SetEnabled( false );
m_pFilter->SetEnabled( false );
}
BaseClass::PerformLayout();
m_pLocationFilter->SetEnabled(true);
}
//-----------------------------------------------------------------------------
// Purpose: Activates the page, starts refresh if needed
//-----------------------------------------------------------------------------
void CInternetGames::OnPageShow()
{
if ( m_pGameList->GetItemCount() == 0 && ServerBrowserDialog().IsVisible() )
BaseClass::OnPageShow();
// the "internet games" tab (unlike the other browser tabs)
// does not automatically start a query when the user
// navigates to this tab unless they have no servers listed.
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame, maintains sockets and runs refreshes
//-----------------------------------------------------------------------------
void CInternetGames::OnTick()
{
if ( m_bOfflineMode )
{
BaseClass::OnTick();
return;
}
BaseClass::OnTick();
CheckRedoSort();
}
//-----------------------------------------------------------------------------
// Purpose: Handles incoming server refresh data
// updates the server browser with the refreshed information from the server itself
//-----------------------------------------------------------------------------
void CInternetGames::ServerResponded( HServerListRequest hReq, int iServer )
{
m_bDirty = true;
BaseClass::ServerResponded( hReq, iServer );
m_bAnyServersRespondedToQuery = true;
m_bAnyServersRetrievedFromMaster = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInternetGames::ServerFailedToRespond( HServerListRequest hReq, int iServer )
{
m_bDirty = true;
gameserveritem_t *pServer = steamapicontext->SteamMatchmakingServers()->GetServerDetails( hReq, iServer );
Assert( pServer );
if ( pServer->m_bHadSuccessfulResponse )
{
// if it's had a successful response in the past, leave it on
ServerResponded( hReq, iServer );
}
else
{
int iServerMap = m_mapServers.Find( iServer );
if ( iServerMap != m_mapServers.InvalidIndex() )
RemoveServer( m_mapServers[ iServerMap ] );
// we've never had a good response from this server, remove it from the list
m_iServerRefreshCount++;
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when server refresh has been completed
//-----------------------------------------------------------------------------
void CInternetGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response )
{
SetRefreshing(false);
UpdateFilterSettings();
if ( response != eServerFailedToRespond )
{
if ( m_bAnyServersRespondedToQuery )
{
m_pGameList->SetEmptyListText( GetStringNoUnfilteredServers() );
}
else if ( response == eNoServersListedOnMasterServer )
{
m_pGameList->SetEmptyListText( GetStringNoUnfilteredServersOnMaster() );
}
else
{
m_pGameList->SetEmptyListText( GetStringNoServersResponded() );
}
}
else
{
m_pGameList->SetEmptyListText("#ServerBrowser_MasterServerNotResponsive");
}
// perform last sort
m_bDirty = false;
m_fLastSort = Plat_FloatTime();
if (IsVisible())
{
m_pGameList->SortList();
}
UpdateStatus();
BaseClass::RefreshComplete( hReq, response );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInternetGames::GetNewServerList()
{
BaseClass::GetNewServerList();
UpdateStatus();
m_bRequireUpdate = false;
m_bAnyServersRetrievedFromMaster = false;
m_bAnyServersRespondedToQuery = false;
m_pGameList->DeleteAllItems();
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the game list supports the specified ui elements
//-----------------------------------------------------------------------------
bool CInternetGames::SupportsItem(IGameList::InterfaceItem_e item)
{
switch (item)
{
case FILTERS:
case GETNEWLIST:
return true;
default:
return false;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInternetGames::CheckRedoSort( void )
{
float fCurTime;
// No changes detected
if ( !m_bDirty )
return;
fCurTime = Plat_FloatTime();
// Not time yet
if ( fCurTime - m_fLastSort < MINIMUM_SORT_TIME)
return;
// postpone sort if mouse button is down
if ( input()->IsMouseDown(MOUSE_LEFT) || input()->IsMouseDown(MOUSE_RIGHT) )
{
// don't sort for at least another second
m_fLastSort = fCurTime - MINIMUM_SORT_TIME + 1.0f;
return;
}
// Reset timer
m_bDirty = false;
m_fLastSort = fCurTime;
// Force sort to occur now!
m_pGameList->SortList();
}
//-----------------------------------------------------------------------------
// Purpose: opens context menu (user right clicked on a server)
//-----------------------------------------------------------------------------
void CInternetGames::OnOpenContextMenu(int itemID)
{
// get the server
int serverID = GetSelectedServerID();
if ( serverID == -1 )
return;
// Activate context menu
CServerContextMenu *menu = ServerBrowserDialog().GetContextMenu(GetActiveList());
menu->ShowMenu(this, serverID, true, true, true, true);
}
//-----------------------------------------------------------------------------
// Purpose: refreshes a single server
//-----------------------------------------------------------------------------
void CInternetGames::OnRefreshServer(int serverID)
{
BaseClass::OnRefreshServer( serverID );
ServerBrowserDialog().UpdateStatusText("#ServerBrowser_GettingNewServerList");
}
//-----------------------------------------------------------------------------
// Purpose: get the region code selected in the ui
// Output: returns the region code the user wants to filter by
//-----------------------------------------------------------------------------
int CInternetGames::GetRegionCodeToFilter()
{
KeyValues *kv = m_pLocationFilter->GetActiveItemUserData();
if ( kv )
return kv->GetInt( "code" );
else
return 255;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CInternetGames::CheckTagFilter( gameserveritem_t &server )
{
// Servers without tags go in the official games, servers with tags go in custom games
bool bOfficialServer = !( server.m_szGameTags && server.m_szGameTags[0] );
if ( !bOfficialServer )
return false;
return true;
}