1
This commit is contained in:
2323
serverbrowser/BaseGamesPage.cpp
Normal file
2323
serverbrowser/BaseGamesPage.cpp
Normal file
File diff suppressed because it is too large
Load Diff
325
serverbrowser/BaseGamesPage.h
Normal file
325
serverbrowser/BaseGamesPage.h
Normal file
@ -0,0 +1,325 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef BASEGAMESPAGE_H
|
||||
#define BASEGAMESPAGE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/utldict.h"
|
||||
|
||||
class CBaseGamesPage;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Acts like a regular ListPanel but forwards enter key presses
|
||||
// to its outer control.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CGameListPanel : public vgui::ListPanel
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( CGameListPanel, vgui::ListPanel );
|
||||
|
||||
CGameListPanel( CBaseGamesPage *pOuter, const char *pName );
|
||||
|
||||
virtual void OnKeyCodePressed(vgui::KeyCode code);
|
||||
|
||||
private:
|
||||
CBaseGamesPage *m_pOuter;
|
||||
};
|
||||
|
||||
class CQuickListMapServerList : public CUtlVector< int >
|
||||
{
|
||||
public:
|
||||
CQuickListMapServerList() : CUtlVector< int >( 1, 0 )
|
||||
{
|
||||
}
|
||||
|
||||
CQuickListMapServerList( const CQuickListMapServerList& src )
|
||||
{
|
||||
CopyArray( src.Base(), src.Count() );
|
||||
}
|
||||
|
||||
CQuickListMapServerList &operator=( const CQuickListMapServerList &src )
|
||||
{
|
||||
CopyArray( src.Base(), src.Count() );
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CCheckBoxWithStatus : public vgui::CheckButton
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( CCheckBoxWithStatus, vgui::CheckButton );
|
||||
|
||||
CCheckBoxWithStatus(Panel *parent, const char *panelName, const char *text) : vgui::CheckButton( parent, panelName, text )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void OnCursorEntered();
|
||||
virtual void OnCursorExited();
|
||||
};
|
||||
|
||||
struct servermaps_t
|
||||
{
|
||||
const char *pOriginalName;
|
||||
const char *pFriendlyName;
|
||||
int iPanelIndex;
|
||||
bool bOnDisk;
|
||||
};
|
||||
|
||||
struct gametypes_t
|
||||
{
|
||||
const char *pPrefix;
|
||||
const char *pGametypeName;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base property page for all the games lists (internet/favorites/lan/etc.)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBaseGamesPage : public vgui::PropertyPage, public IGameList, public ISteamMatchmakingServerListResponse, public ISteamMatchmakingPingResponse
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CBaseGamesPage, vgui::PropertyPage );
|
||||
|
||||
public:
|
||||
enum EPageType
|
||||
{
|
||||
eInternetServer,
|
||||
eLANServer,
|
||||
eFriendsServer,
|
||||
eFavoritesServer,
|
||||
eHistoryServer,
|
||||
eSpectatorServer
|
||||
};
|
||||
|
||||
// Column indices
|
||||
enum
|
||||
{
|
||||
k_nColumn_Password = 0,
|
||||
k_nColumn_Secure = 1,
|
||||
k_nColumn_Replay = 2,
|
||||
k_nColumn_Name = 3,
|
||||
k_nColumn_IPAddr = 4,
|
||||
k_nColumn_GameDesc = 5,
|
||||
k_nColumn_Players = 6,
|
||||
k_nColumn_Bots = 7,
|
||||
k_nColumn_Map = 8,
|
||||
k_nColumn_Ping = 9,
|
||||
};
|
||||
|
||||
CBaseGamesPage( vgui::Panel *parent, const char *name, EPageType eType, const char *pCustomResFilename=NULL);
|
||||
~CBaseGamesPage();
|
||||
|
||||
virtual void PerformLayout();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
// gets information about specified server
|
||||
virtual gameserveritem_t *GetServer(unsigned int serverID);
|
||||
virtual const char *GetConnectCode();
|
||||
|
||||
uint32 GetServerFilters( MatchMakingKeyValuePair_t **pFilters );
|
||||
|
||||
virtual void SetRefreshing(bool state);
|
||||
|
||||
// loads filter settings from disk
|
||||
virtual void LoadFilterSettings();
|
||||
|
||||
// Called by CGameList when the enter key is pressed.
|
||||
// This is overridden in the add server dialog - since there is no Connect button, the message
|
||||
// never gets handled, but we want to add a server when they dbl-click or press enter.
|
||||
virtual bool OnGameListEnterPressed();
|
||||
|
||||
int GetSelectedItemsCount();
|
||||
|
||||
// adds a server to the favorites
|
||||
MESSAGE_FUNC( OnAddToFavorites, "AddToFavorites" );
|
||||
MESSAGE_FUNC( OnAddToBlacklist, "AddToBlacklist" );
|
||||
|
||||
virtual void StartRefresh();
|
||||
|
||||
virtual void UpdateDerivedLayouts( void );
|
||||
|
||||
void PrepareQuickListMap( const char *pMapName, int iListID );
|
||||
void SelectQuickListServers( void );
|
||||
vgui::Panel *GetActiveList( void );
|
||||
virtual bool IsQuickListButtonChecked()
|
||||
{
|
||||
return m_pQuickListCheckButton ? m_pQuickListCheckButton->IsSelected() : false;
|
||||
}
|
||||
|
||||
STEAM_CALLBACK( CBaseGamesPage, OnFavoritesMsg, FavoritesListChanged_t, m_CallbackFavoritesMsg );
|
||||
|
||||
// applies games filters to current list
|
||||
void ApplyGameFilters();
|
||||
|
||||
void OnLoadingStarted()
|
||||
{
|
||||
StopRefresh();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void OnCommand(const char *command);
|
||||
virtual void OnKeyCodePressed(vgui::KeyCode code);
|
||||
virtual int GetRegionCodeToFilter() { return 255; }
|
||||
|
||||
MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
|
||||
|
||||
// updates server count UI
|
||||
void UpdateStatus();
|
||||
|
||||
// ISteamMatchmakingServerListResponse callbacks
|
||||
virtual void ServerResponded( HServerListRequest hReq, int iServer );
|
||||
virtual void ServerResponded( int iServer, gameserveritem_t *pServerItem );
|
||||
virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer );
|
||||
virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response ) = 0;
|
||||
|
||||
// ISteamMatchmakingPingResponse callbacks
|
||||
virtual void ServerResponded( gameserveritem_t &server );
|
||||
virtual void ServerFailedToRespond() {}
|
||||
|
||||
// Removes server from list
|
||||
void RemoveServer( serverdisplay_t &server );
|
||||
|
||||
virtual bool BShowServer( serverdisplay_t &server ) { return server.m_bDoNotRefresh; }
|
||||
void ClearServerList();
|
||||
|
||||
// filtering methods
|
||||
// returns true if filters passed; false if failed
|
||||
virtual bool CheckPrimaryFilters( gameserveritem_t &server);
|
||||
virtual bool CheckSecondaryFilters( gameserveritem_t &server );
|
||||
virtual bool CheckTagFilter( gameserveritem_t &server ) { return true; }
|
||||
virtual bool CheckWorkshopFilter( gameserveritem_t &server ) { return true; }
|
||||
virtual int GetInvalidServerListID();
|
||||
|
||||
virtual void OnSaveFilter(KeyValues *filter);
|
||||
virtual void OnLoadFilter(KeyValues *filter);
|
||||
virtual void UpdateFilterSettings();
|
||||
|
||||
// whether filter settings limit which master server to query
|
||||
CGameID &GetFilterAppID() { return m_iLimitToAppID; }
|
||||
|
||||
virtual void GetNewServerList();
|
||||
virtual void StopRefresh();
|
||||
virtual bool IsRefreshing();
|
||||
virtual void OnPageShow();
|
||||
virtual void OnPageHide();
|
||||
|
||||
// called when Connect button is pressed
|
||||
MESSAGE_FUNC( OnBeginConnect, "ConnectToServer" );
|
||||
// called to look at game info
|
||||
MESSAGE_FUNC( OnViewGameInfo, "ViewGameInfo" );
|
||||
// refreshes a single server
|
||||
MESSAGE_FUNC_INT( OnRefreshServer, "RefreshServer", serverID );
|
||||
|
||||
// If true, then we automatically select the first item that comes into the games list.
|
||||
bool m_bAutoSelectFirstItemInGameList;
|
||||
|
||||
CGameListPanel *m_pGameList;
|
||||
vgui::PanelListPanel *m_pQuickList;
|
||||
|
||||
vgui::ComboBox *m_pLocationFilter;
|
||||
|
||||
// command buttons
|
||||
vgui::Button *m_pConnect;
|
||||
vgui::Button *m_pRefreshAll;
|
||||
vgui::Button *m_pRefreshQuick;
|
||||
vgui::Button *m_pAddServer;
|
||||
vgui::Button *m_pAddCurrentServer;
|
||||
vgui::Button *m_pAddToFavoritesButton;
|
||||
vgui::ToggleButton *m_pFilter;
|
||||
|
||||
CUtlMap<uint64, int> m_mapGamesFilterItem;
|
||||
CUtlMap<int, serverdisplay_t> m_mapServers;
|
||||
CUtlMap<netadr_t, int> m_mapServerIP;
|
||||
CUtlVector<MatchMakingKeyValuePair_t> m_vecServerFilters;
|
||||
CUtlDict< CQuickListMapServerList, int > m_quicklistserverlist;
|
||||
int m_iServerRefreshCount;
|
||||
CUtlVector< servermaps_t > m_vecMapNamesFound;
|
||||
|
||||
|
||||
EPageType m_eMatchMakingType;
|
||||
HServerListRequest m_hRequest;
|
||||
|
||||
int GetSelectedServerID( KeyValues **pKV = NULL );
|
||||
|
||||
void ClearQuickList( void );
|
||||
|
||||
bool TagsExclude( void );
|
||||
|
||||
enum eWorkshopMode {
|
||||
// These correspond to the dropdown indices
|
||||
eWorkshop_None = 0,
|
||||
eWorkshop_WorkshopOnly = 1,
|
||||
eWorkshop_SubscribedOnly = 2
|
||||
};
|
||||
eWorkshopMode WorkshopMode();
|
||||
|
||||
void HideReplayFilter( void );
|
||||
|
||||
protected:
|
||||
virtual void CreateFilters();
|
||||
virtual void UpdateGameFilter();
|
||||
|
||||
MESSAGE_FUNC_PTR_CHARPTR( OnTextChanged, "TextChanged", panel, text );
|
||||
MESSAGE_FUNC_PTR_INT( OnButtonToggled, "ButtonToggled", panel, state );
|
||||
|
||||
void UpdateFilterAndQuickListVisibility();
|
||||
bool BFiltersVisible() { return m_bFiltersVisible; }
|
||||
|
||||
private:
|
||||
void RequestServersResponse( int iServer, EMatchMakingServerResponse response, bool bLastServer ); // callback for matchmaking interface
|
||||
|
||||
void RecalculateFilterString();
|
||||
|
||||
void SetQuickListEnabled( bool bEnabled );
|
||||
void SetFiltersVisible( bool bVisible );
|
||||
|
||||
// If set, it uses the specified resfile name instead of its default one.
|
||||
const char *m_pCustomResFilename;
|
||||
|
||||
// filter controls
|
||||
vgui::ComboBox *m_pGameFilter;
|
||||
vgui::TextEntry *m_pMapFilter;
|
||||
vgui::TextEntry *m_pMaxPlayerFilter;
|
||||
vgui::ComboBox *m_pPingFilter;
|
||||
vgui::ComboBox *m_pSecureFilter;
|
||||
vgui::ComboBox *m_pTagsIncludeFilter;
|
||||
vgui::ComboBox *m_pWorkshopFilter;
|
||||
vgui::CheckButton *m_pNoFullServersFilterCheck;
|
||||
vgui::CheckButton *m_pNoEmptyServersFilterCheck;
|
||||
vgui::CheckButton *m_pNoPasswordFilterCheck;
|
||||
CCheckBoxWithStatus *m_pQuickListCheckButton;
|
||||
vgui::Label *m_pFilterString;
|
||||
char m_szComboAllText[64];
|
||||
vgui::CheckButton *m_pReplayFilterCheck;
|
||||
|
||||
KeyValues *m_pFilters; // base filter data
|
||||
bool m_bFiltersVisible; // true if filter section is currently visible
|
||||
vgui::HFont m_hFont;
|
||||
|
||||
int m_nImageIndexPassword;
|
||||
int m_nImageIndexSecure;
|
||||
int m_nImageIndexSecureVacBanned;
|
||||
int m_nImageIndexReplay;
|
||||
|
||||
// filter data
|
||||
char m_szGameFilter[32];
|
||||
char m_szMapFilter[32];
|
||||
int m_iMaxPlayerFilter;
|
||||
int m_iPingFilter;
|
||||
bool m_bFilterNoFullServers;
|
||||
bool m_bFilterNoEmptyServers;
|
||||
bool m_bFilterNoPasswordedServers;
|
||||
int m_iSecureFilter;
|
||||
int m_iServersBlacklisted;
|
||||
bool m_bFilterReplayServers;
|
||||
|
||||
CGameID m_iLimitToAppID;
|
||||
};
|
||||
|
||||
#endif // BASEGAMESPAGE_H
|
500
serverbrowser/BlacklistedServers.cpp
Normal file
500
serverbrowser/BlacklistedServers.cpp
Normal file
@ -0,0 +1,500 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
ConVar sb_showblacklists( "sb_showblacklists", "0", FCVAR_NONE, "If set to 1, blacklist rules will be printed to the console as they're applied." );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Server name comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl BlacklistedServerNameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
blacklisted_server_t *pSvr1 = ServerBrowserDialog().GetBlacklistPage()->GetBlacklistedServer( p1.userData );
|
||||
blacklisted_server_t *pSvr2 = ServerBrowserDialog().GetBlacklistPage()->GetBlacklistedServer( p2.userData );
|
||||
|
||||
if ( !pSvr1 && pSvr2 )
|
||||
return -1;
|
||||
if ( !pSvr2 && pSvr1 )
|
||||
return 1;
|
||||
if ( !pSvr1 && !pSvr2 )
|
||||
return 0;
|
||||
|
||||
return Q_stricmp( pSvr1->m_szServerName, pSvr2->m_szServerName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: list column sort function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl BlacklistedIPAddressCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
blacklisted_server_t *pSvr1 = ServerBrowserDialog().GetBlacklistPage()->GetBlacklistedServer( p1.userData );
|
||||
blacklisted_server_t *pSvr2 = ServerBrowserDialog().GetBlacklistPage()->GetBlacklistedServer( p2.userData );
|
||||
|
||||
if ( !pSvr1 && pSvr2 )
|
||||
return -1;
|
||||
if ( !pSvr2 && pSvr1 )
|
||||
return 1;
|
||||
if ( !pSvr1 && !pSvr2 )
|
||||
return 0;
|
||||
|
||||
if ( pSvr1->m_NetAdr < pSvr2->m_NetAdr )
|
||||
return -1;
|
||||
else if ( pSvr2->m_NetAdr < pSvr1->m_NetAdr )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Player number comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl BlacklistedAtCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
blacklisted_server_t *pSvr1 = ServerBrowserDialog().GetBlacklistPage()->GetBlacklistedServer( p1.userData );
|
||||
blacklisted_server_t *pSvr2 = ServerBrowserDialog().GetBlacklistPage()->GetBlacklistedServer( p2.userData );
|
||||
|
||||
if ( !pSvr1 && pSvr2 )
|
||||
return -1;
|
||||
if ( !pSvr2 && pSvr1 )
|
||||
return 1;
|
||||
if ( !pSvr1 && !pSvr2 )
|
||||
return 0;
|
||||
|
||||
if ( pSvr1->m_ulTimeBlacklistedAt > pSvr2->m_ulTimeBlacklistedAt )
|
||||
return -1;
|
||||
if ( pSvr1->m_ulTimeBlacklistedAt < pSvr2->m_ulTimeBlacklistedAt )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CBlacklistedServers::CBlacklistedServers( vgui::Panel *parent ) :
|
||||
vgui::PropertyPage( parent, "BlacklistedGames" )
|
||||
{
|
||||
SetSize( 624, 278 );
|
||||
|
||||
m_pAddServer = new Button(this, "AddServerButton", "#ServerBrowser_AddServer");
|
||||
m_pAddCurrentServer = new Button(this, "AddCurrentServerButton", "#ServerBrowser_AddCurrentServer");
|
||||
m_pGameList = vgui::SETUP_PANEL( new vgui::ListPanel(this, "gamelist") );
|
||||
m_pGameList->SetAllowUserModificationOfColumns(true);
|
||||
|
||||
// Add the column headers
|
||||
m_pGameList->AddColumnHeader(0, "Name", "#ServerBrowser_BlacklistedServers", 50, ListPanel::COLUMN_RESIZEWITHWINDOW | ListPanel::COLUMN_UNHIDABLE);
|
||||
m_pGameList->AddColumnHeader(1, "IPAddr", "#ServerBrowser_IPAddress", 64, ListPanel::COLUMN_HIDDEN);
|
||||
m_pGameList->AddColumnHeader(2, "BlacklistedAt", "#ServerBrowser_BlacklistedDate", 100);
|
||||
|
||||
//m_pGameList->SetColumnHeaderTooltip(0, "#ServerBrowser_PasswordColumn_Tooltip");
|
||||
|
||||
// setup fast sort functions
|
||||
m_pGameList->SetSortFunc(0, BlacklistedServerNameCompare);
|
||||
m_pGameList->SetSortFunc(1, BlacklistedIPAddressCompare);
|
||||
m_pGameList->SetSortFunc(2, BlacklistedAtCompare);
|
||||
|
||||
// Sort by name by default
|
||||
m_pGameList->SetSortColumn(0);
|
||||
|
||||
m_blackList.Reset();
|
||||
m_blackListTimestamp = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CBlacklistedServers::~CBlacklistedServers()
|
||||
{
|
||||
ClearServerList();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads the initial blacklist from disk
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::LoadBlacklistedList()
|
||||
{
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoBlacklistedServers");
|
||||
|
||||
ClearServerList();
|
||||
m_blackList.Reset();
|
||||
|
||||
int count = m_blackList.LoadServersFromFile( BLACKLIST_DEFAULT_SAVE_FILE, false );
|
||||
|
||||
m_blackListTimestamp = g_pFullFileSystem->GetFileTime( BLACKLIST_DEFAULT_SAVE_FILE );
|
||||
|
||||
for( int i=0; i<count; ++i )
|
||||
{
|
||||
UpdateBlacklistUI( m_blackList.GetServer(i) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: adds all the servers inside the specified file to the blacklist
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBlacklistedServers::AddServersFromFile( const char *pszFilename, bool bResetTimes )
|
||||
{
|
||||
KeyValues *pKV = new KeyValues( "serverblacklist" );
|
||||
if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFilename, "GAME" ) )
|
||||
return false;
|
||||
|
||||
for ( KeyValues *pData = pKV->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
|
||||
{
|
||||
const char *pszName = pData->GetString( "name" );
|
||||
|
||||
uint32 ulDate = pData->GetInt( "date" );
|
||||
if ( bResetTimes )
|
||||
{
|
||||
time_t today;
|
||||
time( &today );
|
||||
ulDate = today;
|
||||
}
|
||||
|
||||
const char *pszNetAddr = pData->GetString( "addr" );
|
||||
|
||||
if ( pszNetAddr && pszNetAddr[0] && pszName && pszName[0] )
|
||||
{
|
||||
blacklisted_server_t *blackServer = m_blackList.AddServer( pszName, pszNetAddr, ulDate );
|
||||
|
||||
UpdateBlacklistUI( blackServer );
|
||||
}
|
||||
}
|
||||
|
||||
// write out blacklist to preserve changes
|
||||
SaveBlacklistedList();
|
||||
|
||||
pKV->deleteThis();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: save blacklist to disk
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::SaveBlacklistedList()
|
||||
{
|
||||
m_blackList.SaveToFile( BLACKLIST_DEFAULT_SAVE_FILE );
|
||||
m_blackListTimestamp = g_pFullFileSystem->GetFileTime( BLACKLIST_DEFAULT_SAVE_FILE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::AddServer( gameserveritem_t &server )
|
||||
{
|
||||
blacklisted_server_t *blackServer = m_blackList.AddServer( server );
|
||||
|
||||
if ( !blackServer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SaveBlacklistedList();
|
||||
|
||||
UpdateBlacklistUI( blackServer );
|
||||
|
||||
if ( GameSupportsReplay() )
|
||||
{
|
||||
// send command to propagate to the client so the client can send it on to the GC
|
||||
char command[ 256 ];
|
||||
Q_snprintf( command, Q_ARRAYSIZE( command ), "rbgc %s\n", blackServer->m_NetAdr.ToString() );
|
||||
g_pRunGameEngine->AddTextCommand( command );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
blacklisted_server_t *CBlacklistedServers::GetBlacklistedServer( int iServerID )
|
||||
{
|
||||
return m_blackList.GetServer( iServerID );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBlacklistedServers::IsServerBlacklisted( gameserveritem_t &server )
|
||||
{
|
||||
// if something has changed the blacklist file, reload it
|
||||
if ( g_pFullFileSystem->GetFileTime( BLACKLIST_DEFAULT_SAVE_FILE ) != m_blackListTimestamp )
|
||||
{
|
||||
LoadBlacklistedList();
|
||||
}
|
||||
|
||||
return m_blackList.IsServerBlacklisted( server );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::UpdateBlacklistUI( blacklisted_server_t *blackServer )
|
||||
{
|
||||
if ( !blackServer )
|
||||
return;
|
||||
|
||||
KeyValues *kv;
|
||||
int iItemId = m_pGameList->GetItemIDFromUserData( blackServer->m_nServerID );
|
||||
if ( m_pGameList->IsValidItemID( iItemId ) )
|
||||
{
|
||||
// we're updating an existing entry
|
||||
kv = m_pGameList->GetItem( iItemId );
|
||||
m_pGameList->SetUserData( iItemId, blackServer->m_nServerID );
|
||||
}
|
||||
else
|
||||
{
|
||||
// new entry
|
||||
kv = new KeyValues("Server");
|
||||
}
|
||||
|
||||
kv->SetString( "name", blackServer->m_szServerName );
|
||||
|
||||
// construct a time string for blacklisted time
|
||||
struct tm *now;
|
||||
now = localtime( (time_t*)&blackServer->m_ulTimeBlacklistedAt );
|
||||
if ( now )
|
||||
{
|
||||
char buf[64];
|
||||
strftime(buf, sizeof(buf), "%a %d %b %I:%M%p", now);
|
||||
Q_strlower(buf + strlen(buf) - 4);
|
||||
kv->SetString("BlacklistedAt", buf);
|
||||
}
|
||||
|
||||
kv->SetString( "IPAddr", blackServer->m_NetAdr.ToString() );
|
||||
|
||||
if ( !m_pGameList->IsValidItemID( iItemId ) )
|
||||
{
|
||||
// new server, add to list
|
||||
iItemId = m_pGameList->AddItem(kv, blackServer->m_nServerID, false, false);
|
||||
kv->deleteThis();
|
||||
}
|
||||
else
|
||||
{
|
||||
// tell the list that we've changed the data
|
||||
m_pGameList->ApplyItemChanges( iItemId );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
const char *pPathID = "PLATFORM";
|
||||
const char *pszFileName = "servers/BlacklistedServersPage.res";
|
||||
if ( g_pFullFileSystem->FileExists( pszFileName, "MOD" ) )
|
||||
{
|
||||
pPathID = "MOD";
|
||||
}
|
||||
LoadControlSettings( pszFileName, pPathID );
|
||||
|
||||
vgui::HFont hFont = pScheme->GetFont( "ListSmall", IsProportional() );
|
||||
if ( !hFont )
|
||||
{
|
||||
hFont = pScheme->GetFont( "DefaultSmall", IsProportional() );
|
||||
}
|
||||
m_pGameList->SetFont( hFont );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnPageShow( void )
|
||||
{
|
||||
// reload list since client may have changed it
|
||||
LoadBlacklistedList();
|
||||
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoBlacklistedServers");
|
||||
m_pGameList->SortList();
|
||||
|
||||
BaseClass::OnPageShow();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBlacklistedServers::GetSelectedServerID( void )
|
||||
{
|
||||
int serverID = -1;
|
||||
if ( m_pGameList->GetSelectedItemsCount() )
|
||||
{
|
||||
serverID = m_pGameList->GetItemUserData( m_pGameList->GetSelectedItem(0) );
|
||||
}
|
||||
|
||||
return serverID;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens context menu (user right clicked on a server)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnOpenContextMenu(int itemID)
|
||||
{
|
||||
CServerContextMenu *menu = ServerBrowserDialog().GetContextMenu( m_pGameList );
|
||||
|
||||
// get the server
|
||||
int serverID = GetSelectedServerID();
|
||||
|
||||
menu->ShowMenu( this,(uint32)-1, false, false, false, false );
|
||||
if ( serverID != -1 )
|
||||
{
|
||||
menu->AddMenuItem("RemoveServer", "#ServerBrowser_RemoveServerFromBlacklist", new KeyValues("RemoveFromBlacklist"), this);
|
||||
}
|
||||
|
||||
menu->AddMenuItem("AddServerByName", "#ServerBrowser_AddServerByIP", new KeyValues("AddServerByName"), this);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a server by IP address
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnAddServerByName()
|
||||
{
|
||||
// open the add server dialog
|
||||
CDialogAddBlacklistedServer *dlg = new CDialogAddBlacklistedServer( &ServerBrowserDialog(), NULL );
|
||||
dlg->MoveToCenterOfScreen();
|
||||
dlg->DoModal();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: removes a server from the blacklist
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnRemoveFromBlacklist()
|
||||
{
|
||||
// iterate the selection
|
||||
for ( int iGame = (m_pGameList->GetSelectedItemsCount() - 1); iGame >= 0; iGame-- )
|
||||
{
|
||||
int itemID = m_pGameList->GetSelectedItem( iGame );
|
||||
int serverID = m_pGameList->GetItemData( itemID )->userData;
|
||||
|
||||
m_pGameList->RemoveItem( itemID );
|
||||
m_blackList.RemoveServer( serverID );
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
|
||||
ServerBrowserDialog().BlacklistsChanged();
|
||||
|
||||
SaveBlacklistedList();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::ClearServerList( void )
|
||||
{
|
||||
m_pGameList->RemoveAll();
|
||||
m_blackList.Reset();
|
||||
m_blackListTimestamp = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds the currently connected server to the list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnAddCurrentServer()
|
||||
{
|
||||
gameserveritem_t *pConnected = ServerBrowserDialog().GetCurrentConnectedServer();
|
||||
|
||||
if ( pConnected )
|
||||
{
|
||||
blacklisted_server_t *blackServer = m_blackList.AddServer( *pConnected );
|
||||
|
||||
if ( !blackServer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateBlacklistUI( blackServer );
|
||||
|
||||
ServerBrowserDialog().BlacklistsChanged();
|
||||
|
||||
SaveBlacklistedList();
|
||||
|
||||
if ( GameSupportsReplay() )
|
||||
{
|
||||
// send command to propagate to the client so the client can send it on to the GC
|
||||
char command[ 256 ];
|
||||
Q_snprintf( command, Q_ARRAYSIZE( command ), "rbgc %s\n", pConnected->m_NetAdr.GetConnectionAddressString() );
|
||||
g_pRunGameEngine->AddTextCommand( command );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnImportBlacklist()
|
||||
{
|
||||
if ( m_hImportDialog.Get() )
|
||||
{
|
||||
m_hImportDialog.Get()->MarkForDeletion();
|
||||
}
|
||||
|
||||
m_hImportDialog = new FileOpenDialog( this, "#ServerBrowser_ImportBlacklistTitle", true );
|
||||
if ( m_hImportDialog.Get() )
|
||||
{
|
||||
m_hImportDialog->SetStartDirectory( "cfg/" );
|
||||
m_hImportDialog->AddFilter( "*.txt", "#ServerBrowser_BlacklistFiles", true );
|
||||
m_hImportDialog->DoModal( false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnFileSelected( char const *fullpath )
|
||||
{
|
||||
AddServersFromFile( fullpath, true );
|
||||
|
||||
if ( m_hImportDialog.Get() )
|
||||
{
|
||||
m_hImportDialog.Get()->MarkForDeletion();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Parse posted messages
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnCommand(const char *command)
|
||||
{
|
||||
if (!Q_stricmp(command, "AddServerByName"))
|
||||
{
|
||||
OnAddServerByName();
|
||||
}
|
||||
else if (!Q_stricmp(command, "AddCurrentServer" ))
|
||||
{
|
||||
OnAddCurrentServer();
|
||||
}
|
||||
else if (!Q_stricmp(command, "ImportBlacklist" ))
|
||||
{
|
||||
OnImportBlacklist();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: enables adding server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnConnectToGame()
|
||||
{
|
||||
m_pAddCurrentServer->SetEnabled( true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: disables adding current server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBlacklistedServers::OnDisconnectFromGame( void )
|
||||
{
|
||||
m_pAddCurrentServer->SetEnabled( false );
|
||||
}
|
68
serverbrowser/BlacklistedServers.h
Normal file
68
serverbrowser/BlacklistedServers.h
Normal file
@ -0,0 +1,68 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef BLACKLISTEDSERVERS_H
|
||||
#define BLACKLISTEDSERVERS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "ServerBrowser/blacklisted_server_manager.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Blacklisted servers list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBlacklistedServers : public vgui::PropertyPage
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CBlacklistedServers, vgui::PropertyPage );
|
||||
|
||||
public:
|
||||
CBlacklistedServers(vgui::Panel *parent);
|
||||
~CBlacklistedServers();
|
||||
|
||||
// blacklist list, loads/saves from file
|
||||
void LoadBlacklistedList();
|
||||
void SaveBlacklistedList();
|
||||
void AddServer(gameserveritem_t &server);
|
||||
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
// passed from main server browser window instead of messages
|
||||
void OnConnectToGame();
|
||||
void OnDisconnectFromGame( void );
|
||||
|
||||
blacklisted_server_t *GetBlacklistedServer( int iServerID );
|
||||
bool IsServerBlacklisted(gameserveritem_t &server);
|
||||
|
||||
private:
|
||||
// context menu message handlers
|
||||
MESSAGE_FUNC( OnPageShow, "PageShow" );
|
||||
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
|
||||
MESSAGE_FUNC( OnAddServerByName, "AddServerByName" );
|
||||
MESSAGE_FUNC( OnRemoveFromBlacklist, "RemoveFromBlacklist" );
|
||||
MESSAGE_FUNC_CHARPTR( OnFileSelected, "FileSelected", fullpath );
|
||||
|
||||
void ClearServerList( void );
|
||||
void OnAddCurrentServer( void );
|
||||
void OnImportBlacklist( void );
|
||||
void OnCommand(const char *command);
|
||||
void UpdateBlacklistUI( blacklisted_server_t *blackServer );
|
||||
int GetSelectedServerID( void );
|
||||
bool AddServersFromFile( const char *pszFilename, bool bResetTimes );
|
||||
|
||||
private:
|
||||
vgui::Button *m_pAddServer;
|
||||
vgui::Button *m_pAddCurrentServer;
|
||||
vgui::ListPanel *m_pGameList;
|
||||
vgui::DHANDLE< vgui::FileOpenDialog > m_hImportDialog;
|
||||
|
||||
CBlacklistedServerManager m_blackList;
|
||||
long m_blackListTimestamp;
|
||||
};
|
||||
|
||||
|
||||
#endif // BLACKLISTEDSERVERS_H
|
448
serverbrowser/CustomGames.cpp
Normal file
448
serverbrowser/CustomGames.cpp
Normal file
@ -0,0 +1,448 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
#include <vgui_controls/HTML.h>
|
||||
#include <vgui_controls/MessageDialog.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define NUM_COMMON_TAGS 20
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
TagMenuButton::TagMenuButton(Panel *parent, const char *panelName, const char *text) : BaseClass(parent,panelName,text)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void TagMenuButton::OnShowMenu( vgui::Menu *menu )
|
||||
{
|
||||
PostActionSignal(new KeyValues("TagMenuButtonOpened"));
|
||||
BaseClass::OnShowMenu(menu);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCustomServerInfoURLQuery : public vgui::QueryBox
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CCustomServerInfoURLQuery, vgui::QueryBox );
|
||||
public:
|
||||
CCustomServerInfoURLQuery(const char *title, const char *queryText,vgui::Panel *parent) : BaseClass( title, queryText, parent )
|
||||
{
|
||||
SetOKButtonText( "#ServerBrowser_CustomServerURLButton" );
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_BUILD_FACTORY( TagInfoLabel );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
TagInfoLabel::TagInfoLabel(Panel *parent, const char *panelName) : BaseClass(parent,panelName, (const char *)NULL, NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
TagInfoLabel::TagInfoLabel(Panel *parent, const char *panelName, const char *text, const char *pszURL) : BaseClass(parent,panelName,text,pszURL)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: If we were left clicked on, launch the URL
|
||||
//-----------------------------------------------------------------------------
|
||||
void TagInfoLabel::OnMousePressed(MouseCode code)
|
||||
{
|
||||
if (code == MOUSE_LEFT)
|
||||
{
|
||||
if ( GetURL() )
|
||||
{
|
||||
// Pop up the dialog with the url in it
|
||||
CCustomServerInfoURLQuery *qb = new CCustomServerInfoURLQuery( "#ServerBrowser_CustomServerURLWarning", "#ServerBrowser_CustomServerURLOpen", this );
|
||||
if (qb != NULL)
|
||||
{
|
||||
qb->SetOKCommand( new KeyValues("DoOpenCustomServerInfoURL") );
|
||||
qb->AddActionSignalTarget(this);
|
||||
qb->MoveToFront();
|
||||
qb->DoModal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void TagInfoLabel::DoOpenCustomServerInfoURL( void )
|
||||
{
|
||||
if ( GetURL() )
|
||||
{
|
||||
system()->ShellExecute("open", GetURL() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCustomGames::CCustomGames(vgui::Panel *parent) :
|
||||
BaseClass(parent, "CustomGames", eInternetServer )
|
||||
{
|
||||
m_pGameList->AddColumnHeader(10, "Tags", "#ServerBrowser_Tags", 200);
|
||||
m_pGameList->SetSortFunc(10, TagsCompare);
|
||||
|
||||
if ( !IsSteamGameServerBrowsingEnabled() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
m_szTagFilter[0] = 0;
|
||||
|
||||
m_pTagFilter = new TextEntry(this, "TagFilter");
|
||||
m_pTagFilter->SetEnabled( false );
|
||||
m_pTagFilter->SetMaximumCharCount( MAX_TAG_CHARACTERS );
|
||||
|
||||
m_pAddTagList = new TagMenuButton( this, "AddTagList", "#ServerBrowser_AddCommonTags" );
|
||||
m_pTagListMenu = new Menu( m_pAddTagList, "TagList" );
|
||||
m_pAddTagList->SetMenu( m_pTagListMenu );
|
||||
m_pAddTagList->SetOpenDirection( Menu::UP );
|
||||
m_pAddTagList->SetEnabled( false );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CCustomGames::~CCustomGames()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::UpdateDerivedLayouts( void )
|
||||
{
|
||||
const char *pPathID = "PLATFORM";
|
||||
|
||||
KeyValues *pConditions = NULL;
|
||||
if ( ServerBrowser().IsWorkshopEnabled() )
|
||||
{
|
||||
pConditions = new KeyValues( "conditions" );
|
||||
if ( pConditions )
|
||||
{
|
||||
KeyValues *pNewKey = new KeyValues( "if_workshop_enabled" );
|
||||
if ( pNewKey )
|
||||
{
|
||||
pConditions->AddSubKey( pNewKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_pFilter->IsSelected() )
|
||||
{
|
||||
if ( g_pFullFileSystem->FileExists( "servers/CustomGamesPage_Filters.res", "MOD" ) )
|
||||
{
|
||||
pPathID = "MOD";
|
||||
}
|
||||
|
||||
LoadControlSettings( "servers/CustomGamesPage_Filters.res", pPathID, NULL, pConditions );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( g_pFullFileSystem->FileExists( "servers/CustomGamesPage.res", "MOD" ) )
|
||||
{
|
||||
pPathID = "MOD";
|
||||
}
|
||||
|
||||
LoadControlSettings( "servers/CustomGamesPage.res", pPathID, NULL, pConditions );
|
||||
}
|
||||
|
||||
if ( pConditions )
|
||||
{
|
||||
pConditions->deleteThis();
|
||||
}
|
||||
|
||||
if ( !GameSupportsReplay() )
|
||||
{
|
||||
HideReplayFilter();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::OnLoadFilter(KeyValues *filter)
|
||||
{
|
||||
BaseClass::OnLoadFilter( filter );
|
||||
|
||||
Q_strncpy(m_szTagFilter, filter->GetString("gametype"), sizeof(m_szTagFilter));
|
||||
|
||||
if ( m_pTagFilter )
|
||||
{
|
||||
m_pTagFilter->SetText(m_szTagFilter);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CCustomGames::CheckTagFilter( gameserveritem_t &server )
|
||||
{
|
||||
bool bRetVal = true;
|
||||
|
||||
// Custom games substring matches tags with the server's tags
|
||||
int count = Q_strlen( m_szTagFilter );
|
||||
if ( count )
|
||||
{
|
||||
CUtlVector<char*> TagList;
|
||||
V_SplitString( m_szTagFilter, ",", TagList );
|
||||
for ( int i = 0; i < TagList.Count(); i++ )
|
||||
{
|
||||
if ( ( Q_strnistr( server.m_szGameTags, TagList[i], MAX_TAG_CHARACTERS ) > 0 ) == TagsExclude() )
|
||||
{
|
||||
bRetVal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TagList.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
return bRetVal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Checks the workshop filtering setting, taking into account workshop filtering might be disabled
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CCustomGames::CheckWorkshopFilter( gameserveritem_t &server )
|
||||
{
|
||||
eWorkshopMode workshopMode = WorkshopMode();
|
||||
const char szWorkshopPrefix[] = "workshop/";
|
||||
if ( workshopMode == eWorkshop_WorkshopOnly )
|
||||
{
|
||||
return V_strncasecmp( server.m_szMap, szWorkshopPrefix, sizeof( szWorkshopPrefix ) - 1 ) == 0;
|
||||
}
|
||||
else if ( workshopMode == eWorkshop_SubscribedOnly )
|
||||
{
|
||||
return ServerBrowser().IsWorkshopSubscribedMap( server.m_szMap );
|
||||
}
|
||||
|
||||
Assert( workshopMode == eWorkshop_None );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets filter settings from controls
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::OnSaveFilter(KeyValues *filter)
|
||||
{
|
||||
BaseClass::OnSaveFilter( filter );
|
||||
|
||||
if ( m_pTagFilter )
|
||||
{
|
||||
// tags
|
||||
m_pTagFilter->GetText(m_szTagFilter, sizeof(m_szTagFilter) - 1);
|
||||
}
|
||||
|
||||
if ( m_szTagFilter[0] )
|
||||
{
|
||||
Q_strlower(m_szTagFilter);
|
||||
}
|
||||
|
||||
if ( TagsExclude() )
|
||||
{
|
||||
m_vecServerFilters.AddToTail( MatchMakingKeyValuePair_t( "gametype", "" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vecServerFilters.AddToTail( MatchMakingKeyValuePair_t( "gametype", m_szTagFilter ) );
|
||||
}
|
||||
|
||||
filter->SetString("gametype", m_szTagFilter);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::SetRefreshing(bool state)
|
||||
{
|
||||
if ( state )
|
||||
{
|
||||
m_pAddTagList->SetEnabled( false );
|
||||
}
|
||||
|
||||
BaseClass::SetRefreshing( state );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::ServerResponded( int iServer, gameserveritem_t *pServerItem )
|
||||
{
|
||||
CBaseGamesPage::ServerResponded( iServer, pServerItem );
|
||||
|
||||
// If we've found a server with some tags, enable the add tag button
|
||||
if ( pServerItem->m_szGameTags[0] )
|
||||
{
|
||||
m_pAddTagList->SetEnabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
struct tagentry_t
|
||||
{
|
||||
const char *pszTag;
|
||||
int iCount;
|
||||
};
|
||||
int __cdecl SortTagsInUse( const tagentry_t *pTag1, const tagentry_t *pTag2 )
|
||||
{
|
||||
return (pTag1->iCount < pTag2->iCount);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::RecalculateCommonTags( void )
|
||||
{
|
||||
// Regenerate our tag list
|
||||
m_pTagListMenu->DeleteAllItems();
|
||||
|
||||
// Loop through our servers, and build a list of all the tags
|
||||
CUtlVector<tagentry_t> aTagsInUse;
|
||||
|
||||
int iCount = m_pGameList->GetItemCount();
|
||||
for ( int i = 0; i < iCount; i++ )
|
||||
{
|
||||
int serverID = m_pGameList->GetItemUserData( i );
|
||||
gameserveritem_t *pServer = GetServer( serverID );
|
||||
if ( pServer && pServer->m_szGameTags && pServer->m_szGameTags[0] )
|
||||
{
|
||||
CUtlVector<char*> TagList;
|
||||
V_SplitString( pServer->m_szGameTags, ",", TagList );
|
||||
|
||||
for ( int iTag = 0; iTag < TagList.Count(); iTag++ )
|
||||
{
|
||||
// First make sure it's not already in our list
|
||||
bool bFound = false;
|
||||
for ( int iCheck = 0; iCheck < aTagsInUse.Count(); iCheck++ )
|
||||
{
|
||||
if ( !Q_strnicmp(TagList[iTag], aTagsInUse[iCheck].pszTag, MAX_TAG_CHARACTERS ) )
|
||||
{
|
||||
aTagsInUse[iCheck].iCount++;
|
||||
bFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bFound )
|
||||
{
|
||||
int iIdx = aTagsInUse.AddToTail();
|
||||
aTagsInUse[iIdx].pszTag = TagList[iTag];
|
||||
aTagsInUse[iIdx].iCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aTagsInUse.Sort( SortTagsInUse );
|
||||
|
||||
int iTagsToAdd = min( aTagsInUse.Count(), NUM_COMMON_TAGS );
|
||||
for ( int i = 0; i < iTagsToAdd; i++ )
|
||||
{
|
||||
const char *pszTag = aTagsInUse[i].pszTag;
|
||||
m_pTagListMenu->AddMenuItem( pszTag, new KeyValues("AddTag", "tag", pszTag), this, new KeyValues( "data", "tag", pszTag ) );
|
||||
}
|
||||
|
||||
m_pTagListMenu->SetFixedWidth( m_pAddTagList->GetWide() );
|
||||
m_pTagListMenu->InvalidateLayout( true, false );
|
||||
m_pTagListMenu->PositionRelativeToPanel( m_pAddTagList, Menu::UP );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::OnTagMenuButtonOpened( void )
|
||||
{
|
||||
RecalculateCommonTags();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets the text from the message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::OnAddTag(KeyValues *params)
|
||||
{
|
||||
KeyValues *pkvText = params->FindKey("tag", false);
|
||||
if (!pkvText)
|
||||
return;
|
||||
|
||||
AddTagToFilterList( pkvText->GetString() );
|
||||
}
|
||||
|
||||
|
||||
int SortServerTags( char* const *p1, char* const *p2 )
|
||||
{
|
||||
return ( Q_strcmp( *p1, *p2 ) > 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CCustomGames::AddTagToFilterList( const char *pszTag )
|
||||
{
|
||||
char txt[ 128 ];
|
||||
m_pTagFilter->GetText( txt, sizeof( txt ) );
|
||||
|
||||
CUtlVector<char*> TagList;
|
||||
V_SplitString( txt, ",", TagList );
|
||||
|
||||
if ( txt[0] )
|
||||
{
|
||||
for ( int i = 0; i < TagList.Count(); i++ )
|
||||
{
|
||||
// Already in the tag list?
|
||||
if ( !Q_stricmp( TagList[i], pszTag ) )
|
||||
{
|
||||
TagList.PurgeAndDeleteElements();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *pszNewTag = new char[64];
|
||||
Q_strncpy( pszNewTag, pszTag, 64 );
|
||||
TagList.AddToHead( pszNewTag );
|
||||
|
||||
TagList.Sort( SortServerTags );
|
||||
|
||||
// Append it
|
||||
char tmptags[MAX_TAG_CHARACTERS];
|
||||
tmptags[0] = '\0';
|
||||
|
||||
for ( int i = 0; i < TagList.Count(); i++ )
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
Q_strncat( tmptags, ",", MAX_TAG_CHARACTERS );
|
||||
}
|
||||
|
||||
Q_strncat( tmptags, TagList[i], MAX_TAG_CHARACTERS );
|
||||
}
|
||||
|
||||
m_pTagFilter->SetText( tmptags );
|
||||
TagList.PurgeAndDeleteElements();
|
||||
|
||||
// Update & apply filters now that the tag list has changed
|
||||
UpdateFilterSettings();
|
||||
ApplyGameFilters();
|
||||
}
|
70
serverbrowser/CustomGames.h
Normal file
70
serverbrowser/CustomGames.h
Normal file
@ -0,0 +1,70 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef CUSTOMGAMES_H
|
||||
#define CUSTOMGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define MAX_TAG_CHARACTERS 128
|
||||
|
||||
class TagInfoLabel : public vgui::URLLabel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( TagInfoLabel, vgui::URLLabel );
|
||||
public:
|
||||
TagInfoLabel(Panel *parent, const char *panelName);
|
||||
TagInfoLabel(Panel *parent, const char *panelName, const char *text, const char *pszURL);
|
||||
|
||||
virtual void OnMousePressed(vgui::MouseCode code);
|
||||
|
||||
MESSAGE_FUNC( DoOpenCustomServerInfoURL, "DoOpenCustomServerInfoURL" );
|
||||
};
|
||||
|
||||
class TagMenuButton : public vgui::MenuButton
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( TagMenuButton, vgui::MenuButton );
|
||||
public:
|
||||
TagMenuButton( Panel *parent, const char *panelName, const char *text);
|
||||
|
||||
virtual void OnShowMenu(vgui::Menu *menu);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Internet games with tags
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CCustomGames : public CInternetGames
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CCustomGames, CInternetGames );
|
||||
public:
|
||||
CCustomGames(vgui::Panel *parent);
|
||||
~CCustomGames();
|
||||
|
||||
virtual void UpdateDerivedLayouts( void ) OVERRIDE;
|
||||
virtual void OnLoadFilter(KeyValues *filter) OVERRIDE;
|
||||
virtual void OnSaveFilter(KeyValues *filter) OVERRIDE;
|
||||
bool CheckTagFilter( gameserveritem_t &server ) OVERRIDE;
|
||||
bool CheckWorkshopFilter( gameserveritem_t &server ) OVERRIDE;
|
||||
virtual void SetRefreshing(bool state) OVERRIDE;
|
||||
virtual void ServerResponded( int iServer, gameserveritem_t *pServerItem ) OVERRIDE;
|
||||
|
||||
MESSAGE_FUNC_PARAMS( OnAddTag, "AddTag", params );
|
||||
MESSAGE_FUNC( OnTagMenuButtonOpened, "TagMenuButtonOpened" );
|
||||
|
||||
void RecalculateCommonTags( void );
|
||||
void AddTagToFilterList( const char *pszTag );
|
||||
|
||||
private:
|
||||
TagInfoLabel *m_pTagInfoURL;
|
||||
TagMenuButton *m_pAddTagList;
|
||||
vgui::Menu *m_pTagListMenu;
|
||||
vgui::TextEntry *m_pTagFilter;
|
||||
char m_szTagFilter[MAX_TAG_CHARACTERS];
|
||||
};
|
||||
|
||||
|
||||
#endif // CUSTOMGAMES_H
|
392
serverbrowser/DialogAddServer.cpp
Normal file
392
serverbrowser/DialogAddServer.cpp
Normal file
@ -0,0 +1,392 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : *gameList - game list to add specified server to
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogAddServer::CDialogAddServer(vgui::Panel *parent, IGameList *gameList) : Frame(parent, "DialogAddServer")
|
||||
{
|
||||
SetDeleteSelfOnClose(true);
|
||||
|
||||
m_pGameList = gameList;
|
||||
|
||||
SetTitle("#ServerBrowser_AddServersTitle", true);
|
||||
SetSizeable( false );
|
||||
|
||||
m_pTabPanel = new PropertySheet(this, "GameTabs");
|
||||
m_pTabPanel->SetTabWidth(72);
|
||||
|
||||
m_pDiscoveredGames = new ListPanel( this, "Servers" );
|
||||
|
||||
// Add the column headers
|
||||
m_pDiscoveredGames->AddColumnHeader(0, "Password", "#ServerBrowser_Password", 16, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE);
|
||||
m_pDiscoveredGames->AddColumnHeader(1, "Bots", "#ServerBrowser_Bots", 16, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE | ListPanel::COLUMN_HIDDEN);
|
||||
m_pDiscoveredGames->AddColumnHeader(2, "Secure", "#ServerBrowser_Secure", 16, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE);
|
||||
|
||||
bool bGameSupportsReplay = GameSupportsReplay();
|
||||
|
||||
int nReplayWidth = 16;
|
||||
if ( !bGameSupportsReplay )
|
||||
{
|
||||
nReplayWidth = 0;
|
||||
}
|
||||
|
||||
m_pDiscoveredGames->AddColumnHeader(3, "Replay", "#ServerBrowser_Replay", nReplayWidth, ListPanel::COLUMN_FIXEDSIZE | ListPanel::COLUMN_IMAGE);
|
||||
m_pDiscoveredGames->AddColumnHeader(4, "Name", "#ServerBrowser_Servers", 20, ListPanel::COLUMN_RESIZEWITHWINDOW | ListPanel::COLUMN_UNHIDABLE);
|
||||
m_pDiscoveredGames->AddColumnHeader(5, "IPAddr", "#ServerBrowser_IPAddress", 60, ListPanel::COLUMN_HIDDEN);
|
||||
m_pDiscoveredGames->AddColumnHeader(6, "GameDesc", "#ServerBrowser_Game", 150);
|
||||
m_pDiscoveredGames->AddColumnHeader(7, "Players", "#ServerBrowser_Players", 60);
|
||||
m_pDiscoveredGames->AddColumnHeader(8, "Map", "#ServerBrowser_Map", 80);
|
||||
m_pDiscoveredGames->AddColumnHeader(9, "Ping", "#ServerBrowser_Latency", 60);
|
||||
|
||||
m_pDiscoveredGames->SetColumnHeaderTooltip(0, "#ServerBrowser_PasswordColumn_Tooltip");
|
||||
m_pDiscoveredGames->SetColumnHeaderTooltip(1, "#ServerBrowser_BotColumn_Tooltip");
|
||||
m_pDiscoveredGames->SetColumnHeaderTooltip(2, "#ServerBrowser_SecureColumn_Tooltip");
|
||||
|
||||
if ( bGameSupportsReplay )
|
||||
{
|
||||
m_pDiscoveredGames->SetColumnHeaderTooltip(3, "#ServerBrowser_ReplayColumn_Tooltip");
|
||||
}
|
||||
|
||||
// setup fast sort functions
|
||||
m_pDiscoveredGames->SetSortFunc(0, PasswordCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(1, BotsCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(2, SecureCompare);
|
||||
|
||||
if ( bGameSupportsReplay )
|
||||
{
|
||||
m_pDiscoveredGames->SetSortFunc(3, ReplayCompare);
|
||||
}
|
||||
|
||||
m_pDiscoveredGames->SetSortFunc(4, ServerNameCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(5, IPAddressCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(6, GameCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(7, PlayersCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(8, MapCompare);
|
||||
m_pDiscoveredGames->SetSortFunc(9, PingCompare);
|
||||
|
||||
m_pDiscoveredGames->SetSortColumn(9); // sort on ping
|
||||
|
||||
m_pTextEntry = new vgui::TextEntry( this, "ServerNameText" );
|
||||
m_pTextEntry->AddActionSignalTarget( this );
|
||||
|
||||
m_pTestServersButton = new vgui::Button( this, "TestServersButton", "" );
|
||||
m_pAddServerButton = new vgui::Button( this, "OKButton", "" );
|
||||
m_pAddSelectedServerButton = new vgui::Button( this, "SelectedOKButton", "", this, "addselected" );
|
||||
|
||||
m_pTabPanel->AddPage( m_pDiscoveredGames, "#ServerBrowser_Servers" );
|
||||
|
||||
LoadControlSettings("Servers/DialogAddServer.res");
|
||||
|
||||
// Setup the buttons. We leave them disabled until there is text in the textbox.
|
||||
m_pAddServerButton->SetEnabled( false );
|
||||
m_pTestServersButton->SetEnabled( false );
|
||||
m_pAddSelectedServerButton->SetEnabled( false );
|
||||
m_pAddSelectedServerButton->SetVisible( false );
|
||||
m_pTabPanel->SetVisible( false );
|
||||
|
||||
m_pTextEntry->RequestFocus();
|
||||
|
||||
// Initially, we aren't high enough to show the tab panel.
|
||||
int x, y;
|
||||
m_pTabPanel->GetPos( x, y );
|
||||
m_OriginalHeight = m_pTabPanel->GetTall() + y + 50;
|
||||
SetTall( y );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogAddServer::~CDialogAddServer()
|
||||
{
|
||||
FOR_EACH_VEC( m_Queries, i )
|
||||
{
|
||||
if ( steamapicontext->SteamMatchmakingServers() )
|
||||
steamapicontext->SteamMatchmakingServers()->CancelServerQuery( m_Queries[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Lets us know when the text entry has changed.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::OnTextChanged()
|
||||
{
|
||||
bool bAnyText = (m_pTextEntry->GetTextLength() > 0);
|
||||
m_pAddServerButton->SetEnabled( bAnyText );
|
||||
m_pTestServersButton->SetEnabled( bAnyText );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: button command handler
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::OnCommand(const char *command)
|
||||
{
|
||||
if ( Q_stricmp(command, "OK") == 0 )
|
||||
{
|
||||
OnOK();
|
||||
}
|
||||
else if ( Q_stricmp( command, "TestServers" ) == 0 )
|
||||
{
|
||||
SetTall( m_OriginalHeight );
|
||||
m_pTabPanel->SetVisible( true );
|
||||
m_pAddSelectedServerButton->SetVisible( true );
|
||||
|
||||
TestServers();
|
||||
}
|
||||
else if ( !Q_stricmp( command, "addselected" ) )
|
||||
{
|
||||
if ( m_pDiscoveredGames->GetSelectedItemsCount() )
|
||||
{
|
||||
// get the server
|
||||
int serverID = m_pDiscoveredGames->GetItemUserData( m_pDiscoveredGames->GetSelectedItem(0) );
|
||||
FinishAddServer( m_Servers[ serverID ] );
|
||||
m_pDiscoveredGames->RemoveItem( m_pDiscoveredGames->GetSelectedItem(0) ); // as we add to favs remove from the list
|
||||
m_pDiscoveredGames->SetEmptyListText( "" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles the OK button being pressed; adds the server to the game list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::OnOK()
|
||||
{
|
||||
// try and parse out IP address
|
||||
const char *address = GetControlString("ServerNameText", "");
|
||||
netadr_t netaddr;
|
||||
netaddr.SetFromString( address, true );
|
||||
if ( !netaddr.GetPort() && !AllowInvalidIPs() )
|
||||
{
|
||||
// use the default port since it was not entered
|
||||
netaddr.SetPort( 27015 );
|
||||
}
|
||||
|
||||
if ( AllowInvalidIPs() || netaddr.IsValid() )
|
||||
{
|
||||
gameserveritem_t server;
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.SetName( address );
|
||||
|
||||
// We assume here that the query and connection ports are the same. This is why it's much
|
||||
// better if they click "Servers" and choose a server in there.
|
||||
server.m_NetAdr.Init( netaddr.GetIPHostByteOrder(), netaddr.GetPort(), netaddr.GetPort() );
|
||||
|
||||
server.m_nAppID = 0;
|
||||
FinishAddServer( server );
|
||||
}
|
||||
else
|
||||
{
|
||||
// could not parse the ip address, popup an error
|
||||
MessageBox *dlg = new MessageBox("#ServerBrowser_AddServerErrorTitle", "#ServerBrowser_AddServerError");
|
||||
dlg->DoModal();
|
||||
}
|
||||
|
||||
// mark ourselves to be closed
|
||||
PostMessage(this, new KeyValues("Close"));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ping a particular IP for server presence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::TestServers()
|
||||
{
|
||||
if ( !steamapicontext->SteamMatchmakingServers() )
|
||||
return;
|
||||
|
||||
m_pDiscoveredGames->SetEmptyListText( "" );
|
||||
m_pDiscoveredGames->RemoveAll();
|
||||
|
||||
// If they specified a port, then send a query to that port.
|
||||
const char *address = GetControlString("ServerNameText", "");
|
||||
netadr_t netaddr;
|
||||
netaddr.SetFromString( address, true );
|
||||
|
||||
m_Servers.RemoveAll();
|
||||
CUtlVector<netadr_t> vecAdress;
|
||||
|
||||
if ( netaddr.GetPort() == 0 )
|
||||
{
|
||||
// No port specified. Go to town on the ports.
|
||||
CUtlVector<uint16> portsToTry;
|
||||
GetMostCommonQueryPorts( portsToTry );
|
||||
|
||||
for ( int i=0; i < portsToTry.Count(); i++ )
|
||||
{
|
||||
netadr_t newAddr = netaddr;
|
||||
newAddr.SetPort( portsToTry[i] );
|
||||
vecAdress.AddToTail( newAddr );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vecAdress.AddToTail( netaddr );
|
||||
}
|
||||
|
||||
// Change the text on the tab panel..
|
||||
m_pTabPanel->RemoveAllPages();
|
||||
|
||||
wchar_t wstr[512];
|
||||
if ( address[0] == 0 )
|
||||
{
|
||||
Q_wcsncpy( wstr, g_pVGuiLocalize->Find( "#ServerBrowser_ServersRespondingLocal"), sizeof( wstr ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t waddress[512];
|
||||
Q_UTF8ToUnicode( address, waddress, sizeof( waddress ) );
|
||||
g_pVGuiLocalize->ConstructString( wstr, sizeof( wstr ), g_pVGuiLocalize->Find( "#ServerBrowser_ServersResponding"), 1, waddress );
|
||||
}
|
||||
|
||||
char str[512];
|
||||
Q_UnicodeToUTF8( wstr, str, sizeof( str ) );
|
||||
m_pTabPanel->AddPage( m_pDiscoveredGames, str );
|
||||
m_pTabPanel->InvalidateLayout();
|
||||
|
||||
FOR_EACH_VEC( vecAdress, iAddress )
|
||||
{
|
||||
m_Queries.AddToTail( steamapicontext->SteamMatchmakingServers()->PingServer( vecAdress[ iAddress ].GetIPHostByteOrder(), vecAdress[ iAddress ].GetPort(), this ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A server answered our ping
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::ServerResponded( gameserveritem_t &server )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "Server" );
|
||||
|
||||
kv->SetString( "name", server.GetName() );
|
||||
kv->SetString( "map", server.m_szMap );
|
||||
kv->SetString( "GameDir", server.m_szGameDir );
|
||||
kv->SetString( "GameDesc", server.m_szGameDescription );
|
||||
kv->SetString( "GameTags", server.m_szGameTags );
|
||||
kv->SetInt( "password", server.m_bPassword ? 1 : 0);
|
||||
kv->SetInt( "bots", server.m_nBotPlayers ? 2 : 0);
|
||||
kv->SetInt( "Replay", IsReplayServer( server ) ? 5 : 0 );
|
||||
|
||||
if ( server.m_bSecure )
|
||||
{
|
||||
// show the denied icon if banned from secure servers, the secure icon otherwise
|
||||
kv->SetInt("secure", ServerBrowser().IsVACBannedFromGame( server.m_nAppID ) ? 4 : 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
kv->SetInt("secure", 0);
|
||||
}
|
||||
|
||||
netadr_t reportedIPAddr;
|
||||
reportedIPAddr.SetIP( server.m_NetAdr.GetIP() );
|
||||
reportedIPAddr.SetPort( server.m_NetAdr.GetConnectionPort() );
|
||||
kv->SetString("IPAddr", reportedIPAddr.ToString() );
|
||||
|
||||
char buf[32];
|
||||
Q_snprintf(buf, sizeof(buf), "%d / %d", server.m_nPlayers, server.m_nMaxPlayers);
|
||||
kv->SetString("Players", buf);
|
||||
|
||||
kv->SetInt("Ping", server.m_nPing);
|
||||
|
||||
// new server, add to list
|
||||
int iServer = m_Servers.AddToTail( server );
|
||||
int iListID = m_pDiscoveredGames->AddItem(kv, iServer, false, false);
|
||||
if ( m_pDiscoveredGames->GetItemCount() == 1 )
|
||||
{
|
||||
m_pDiscoveredGames->AddSelectedItem( iListID );
|
||||
}
|
||||
kv->deleteThis();
|
||||
|
||||
m_pDiscoveredGames->InvalidateLayout();
|
||||
}
|
||||
|
||||
void CDialogAddServer::ServerFailedToRespond()
|
||||
{
|
||||
m_pDiscoveredGames->SetEmptyListText( "#ServerBrowser_ServerNotResponding" );
|
||||
}
|
||||
|
||||
void CDialogAddServer::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
ImageList *imageList = new ImageList(false);
|
||||
imageList->AddImage(scheme()->GetImage("servers/icon_password", false));
|
||||
imageList->AddImage(scheme()->GetImage("servers/icon_bots", false));
|
||||
imageList->AddImage(scheme()->GetImage("servers/icon_robotron", false));
|
||||
imageList->AddImage(scheme()->GetImage("servers/icon_secure_deny", false));
|
||||
imageList->AddImage(scheme()->GetImage("servers/icon_replay", false));
|
||||
|
||||
int passwordColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_password_column", false));
|
||||
int botColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_bots_column", false));
|
||||
int secureColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_robotron_column", false));
|
||||
int replayColumnImage = imageList->AddImage(scheme()->GetImage("servers/icon_replay_column", false));
|
||||
|
||||
m_pDiscoveredGames->SetImageList(imageList, true);
|
||||
vgui::HFont hFont = pScheme->GetFont( "ListSmall", IsProportional() );
|
||||
if ( !hFont )
|
||||
hFont = pScheme->GetFont( "DefaultSmall", IsProportional() );
|
||||
|
||||
m_pDiscoveredGames->SetFont( hFont );
|
||||
m_pDiscoveredGames->SetColumnHeaderImage(0, passwordColumnImage);
|
||||
m_pDiscoveredGames->SetColumnHeaderImage(1, botColumnImage);
|
||||
m_pDiscoveredGames->SetColumnHeaderImage(2, secureColumnImage);
|
||||
m_pDiscoveredGames->SetColumnHeaderImage(3, replayColumnImage);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A server on the listed IP responded
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::OnItemSelected()
|
||||
{
|
||||
int nSelectedItem = m_pDiscoveredGames->GetSelectedItem(0);
|
||||
if( nSelectedItem != -1 )
|
||||
{
|
||||
m_pAddSelectedServerButton->SetEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pAddSelectedServerButton->SetEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddServer::FinishAddServer( gameserveritem_t &pServer )
|
||||
{
|
||||
ServerBrowserDialog().AddServerToFavorites( pServer );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddBlacklistedServer::FinishAddServer( gameserveritem_t &pServer )
|
||||
{
|
||||
ServerBrowserDialog().AddServerToBlacklist( pServer );
|
||||
ServerBrowserDialog().BlacklistsChanged();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogAddBlacklistedServer::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
m_pAddServerButton->SetText( "#ServerBrowser_AddAddressToBlacklist" );
|
||||
m_pAddSelectedServerButton->SetText( "#ServerBrowser_AddSelectedToBlacklist" );
|
||||
}
|
75
serverbrowser/DialogAddServer.h
Normal file
75
serverbrowser/DialogAddServer.h
Normal file
@ -0,0 +1,75 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DIALOGADDSERVER_H
|
||||
#define DIALOGADDSERVER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CAddServerGameList;
|
||||
class IGameList;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dialog which lets the user add a server by IP address
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDialogAddServer : public vgui::Frame, public ISteamMatchmakingPingResponse
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CDialogAddServer, vgui::Frame );
|
||||
friend class CAddServerGameList;
|
||||
|
||||
public:
|
||||
CDialogAddServer(vgui::Panel *parent, IGameList *gameList);
|
||||
~CDialogAddServer();
|
||||
|
||||
void ServerResponded( gameserveritem_t &server );
|
||||
void ServerFailedToRespond();
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||
|
||||
MESSAGE_FUNC( OnItemSelected, "ItemSelected" );
|
||||
private:
|
||||
virtual void OnCommand(const char *command);
|
||||
|
||||
void OnOK();
|
||||
|
||||
void TestServers();
|
||||
MESSAGE_FUNC( OnTextChanged, "TextChanged" );
|
||||
|
||||
virtual void FinishAddServer( gameserveritem_t &pServer );
|
||||
virtual bool AllowInvalidIPs( void ) { return false; }
|
||||
|
||||
protected:
|
||||
IGameList *m_pGameList;
|
||||
|
||||
vgui::Button *m_pTestServersButton;
|
||||
vgui::Button *m_pAddServerButton;
|
||||
vgui::Button *m_pAddSelectedServerButton;
|
||||
|
||||
vgui::PropertySheet *m_pTabPanel;
|
||||
vgui::TextEntry *m_pTextEntry;
|
||||
vgui::ListPanel *m_pDiscoveredGames;
|
||||
int m_OriginalHeight;
|
||||
CUtlVector<gameserveritem_t> m_Servers;
|
||||
CUtlVector<HServerQuery> m_Queries;
|
||||
};
|
||||
|
||||
class CDialogAddBlacklistedServer : public CDialogAddServer
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CDialogAddBlacklistedServer, CDialogAddServer );
|
||||
public:
|
||||
CDialogAddBlacklistedServer( vgui::Panel *parent, IGameList *gameList) :
|
||||
CDialogAddServer( parent, gameList )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void FinishAddServer( gameserveritem_t &pServer );
|
||||
void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||
virtual bool AllowInvalidIPs( void ) { return true; }
|
||||
};
|
||||
|
||||
#endif // DIALOGADDSERVER_H
|
802
serverbrowser/DialogGameInfo.cpp
Normal file
802
serverbrowser/DialogGameInfo.cpp
Normal file
@ -0,0 +1,802 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
static const long RETRY_TIME = 10000; // refresh server every 10 seconds
|
||||
static const long CHALLENGE_ENTRIES = 1024;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
DLL_EXPORT bool JoiningSecureServerCall()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Comparison function used in query redblack tree
|
||||
//-----------------------------------------------------------------------------
|
||||
bool QueryLessFunc( const struct challenge_s &item1, const struct challenge_s &item2 )
|
||||
{
|
||||
// compare port then ip
|
||||
if ( item1.addr.GetPort() < item2.addr.GetPort() )
|
||||
return true;
|
||||
else if ( item1.addr.GetPort() > item2.addr.GetPort() )
|
||||
return false;
|
||||
|
||||
int ip1 = item1.addr.GetIPNetworkByteOrder();
|
||||
int ip2 = item2.addr.GetIPNetworkByteOrder();
|
||||
|
||||
return ip1 < ip2;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo::CDialogGameInfo( vgui::Panel *parent, int serverIP, int queryPort, unsigned short connectionPort, const char *pszConnectCode ) :
|
||||
Frame(parent, "DialogGameInfo"),
|
||||
m_CallbackPersonaStateChange( this, &CDialogGameInfo::OnPersonaStateChange ),
|
||||
m_sConnectCode( pszConnectCode )
|
||||
{
|
||||
SetBounds(0, 0, 512, 512);
|
||||
SetMinimumSize(416, 340);
|
||||
SetDeleteSelfOnClose(true);
|
||||
m_bConnecting = false;
|
||||
m_bServerFull = false;
|
||||
m_bShowAutoRetryToggle = false;
|
||||
m_bServerNotResponding = false;
|
||||
m_bShowingExtendedOptions = false;
|
||||
m_SteamIDFriend = 0;
|
||||
m_hPingQuery = HSERVERQUERY_INVALID;
|
||||
m_hPlayersQuery = HSERVERQUERY_INVALID;
|
||||
m_bPlayerListUpdatePending = false;
|
||||
|
||||
m_szPassword[0] = 0;
|
||||
|
||||
m_pConnectButton = new Button(this, "Connect", "#ServerBrowser_JoinGame");
|
||||
m_pCloseButton = new Button(this, "Close", "#ServerBrowser_Close");
|
||||
m_pRefreshButton = new Button(this, "Refresh", "#ServerBrowser_Refresh");
|
||||
m_pInfoLabel = new Label(this, "InfoLabel", "");
|
||||
m_pAutoRetry = new ToggleButton(this, "AutoRetry", "#ServerBrowser_AutoRetry");
|
||||
m_pAutoRetry->AddActionSignalTarget(this);
|
||||
|
||||
m_pAutoRetryAlert = new RadioButton(this, "AutoRetryAlert", "#ServerBrowser_AlertMeWhenSlotOpens");
|
||||
m_pAutoRetryJoin = new RadioButton(this, "AutoRetryJoin", "#ServerBrowser_JoinWhenSlotOpens");
|
||||
m_pPlayerList = new ListPanel(this, "PlayerList");
|
||||
m_pPlayerList->AddColumnHeader(0, "PlayerName", "#ServerBrowser_PlayerName", 156);
|
||||
m_pPlayerList->AddColumnHeader(1, "Score", "#ServerBrowser_Score", 64);
|
||||
m_pPlayerList->AddColumnHeader(2, "Time", "#ServerBrowser_Time", 64);
|
||||
|
||||
m_pPlayerList->SetSortFunc(2, &PlayerTimeColumnSortFunc);
|
||||
|
||||
// set the defaults for sorting
|
||||
// hack, need to make this more explicit functions in ListPanel
|
||||
PostMessage(m_pPlayerList, new KeyValues("SetSortColumn", "column", 2));
|
||||
PostMessage(m_pPlayerList, new KeyValues("SetSortColumn", "column", 1));
|
||||
PostMessage(m_pPlayerList, new KeyValues("SetSortColumn", "column", 1));
|
||||
|
||||
m_pAutoRetryAlert->SetSelected(true);
|
||||
|
||||
m_pConnectButton->SetCommand(new KeyValues("Connect"));
|
||||
m_pCloseButton->SetCommand(new KeyValues("Close"));
|
||||
m_pRefreshButton->SetCommand(new KeyValues("Refresh"));
|
||||
|
||||
m_iRequestRetry = 0;
|
||||
|
||||
// create a new server to watch
|
||||
memset(&m_Server, 0, sizeof(m_Server) );
|
||||
m_Server.m_NetAdr.Init( serverIP, queryPort, connectionPort );
|
||||
|
||||
// refresh immediately
|
||||
RequestInfo();
|
||||
|
||||
// let us be ticked every frame
|
||||
ivgui()->AddTickSignal(this->GetVPanel());
|
||||
|
||||
LoadControlSettings("Servers/DialogGameInfo.res");
|
||||
RegisterControlSettingsFile( "Servers/DialogGameInfo_SinglePlayer.res" );
|
||||
RegisterControlSettingsFile( "Servers/DialogGameInfo_AutoRetry.res" );
|
||||
MoveToCenterOfScreen();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo::~CDialogGameInfo()
|
||||
{
|
||||
if ( !steamapicontext->SteamMatchmakingServers() )
|
||||
return;
|
||||
|
||||
if ( m_hPingQuery != HSERVERQUERY_INVALID )
|
||||
steamapicontext->SteamMatchmakingServers()->CancelServerQuery( m_hPingQuery );
|
||||
if ( m_hPlayersQuery != HSERVERQUERY_INVALID )
|
||||
steamapicontext->SteamMatchmakingServers()->CancelServerQuery( m_hPlayersQuery );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: send a player query to a server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::SendPlayerQuery( uint32 unIP, uint16 usQueryPort )
|
||||
{
|
||||
if ( !steamapicontext->SteamMatchmakingServers() )
|
||||
return;
|
||||
|
||||
if ( m_hPlayersQuery != HSERVERQUERY_INVALID )
|
||||
steamapicontext->SteamMatchmakingServers()->CancelServerQuery( m_hPlayersQuery );
|
||||
m_hPlayersQuery = steamapicontext->SteamMatchmakingServers()->PlayerDetails( unIP, usQueryPort, this );
|
||||
m_bPlayerListUpdatePending = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activates the dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::Run(const char *titleName)
|
||||
{
|
||||
if ( titleName )
|
||||
{
|
||||
SetTitle( "#ServerBrowser_GameInfoWithNameTitle", true );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTitle( "#ServerBrowser_GameInfoWithNameTitle", true );
|
||||
}
|
||||
SetDialogVariable( "game", titleName );
|
||||
|
||||
// get the info from the user
|
||||
RequestInfo();
|
||||
Activate();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Changes which server to watch
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ChangeGame( int serverIP, int queryPort, unsigned short connectionPort )
|
||||
{
|
||||
memset( &m_Server, 0x0, sizeof(m_Server) );
|
||||
|
||||
m_Server.m_NetAdr.Init( serverIP, queryPort, connectionPort );
|
||||
|
||||
// remember the dialogs position so we can keep it the same
|
||||
int x, y;
|
||||
GetPos( x, y );
|
||||
|
||||
// see if we need to change dialog state
|
||||
if ( !m_Server.m_NetAdr.GetIP() || !m_Server.m_NetAdr.GetQueryPort() )
|
||||
{
|
||||
// not in a server, load the simple settings dialog
|
||||
SetMinimumSize(0, 0);
|
||||
SetSizeable( false );
|
||||
LoadControlSettings( "Servers/DialogGameInfo_SinglePlayer.res" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// moving from a single-player game -> multiplayer, reset dialog
|
||||
SetMinimumSize(416, 340);
|
||||
SetSizeable( true );
|
||||
LoadControlSettings( "Servers/DialogGameInfo.res" );
|
||||
}
|
||||
SetPos( x, y );
|
||||
|
||||
// Start refresh immediately
|
||||
m_iRequestRetry = 0;
|
||||
RequestInfo();
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates the dialog if it's watching a friend who changes servers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnPersonaStateChange( PersonaStateChange_t *pPersonaStateChange )
|
||||
{
|
||||
#if 0 // TBD delete this func
|
||||
if ( m_SteamIDFriend && m_SteamIDFriend == pPersonaStateChange->m_ulSteamID )
|
||||
{
|
||||
// friend may have changed servers
|
||||
uint64 nGameID;
|
||||
uint32 unGameIP;
|
||||
uint16 usGamePort;
|
||||
uint16 usQueryPort;
|
||||
|
||||
if ( SteamFriends()->GetFriendGamePlayed( m_SteamIDFriend, &nGameID, &unGameIP, &usGamePort, &usQueryPort ) )
|
||||
{
|
||||
if ( pPersonaStateChange->m_nChangeFlags & k_EPersonaChangeGamePlayed )
|
||||
{
|
||||
ChangeGame( unGameIP, usQueryPort, usGamePort );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// bugbug johnc: change to not be in a game anymore
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Associates a user with this dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::SetFriend( uint64 ulSteamIDFriend )
|
||||
{
|
||||
// set the title to include the friends name
|
||||
SetTitle( "#ServerBrowser_GameInfoWithNameTitle", true );
|
||||
SetDialogVariable( "game", steamapicontext->SteamFriends()->GetFriendPersonaName( ulSteamIDFriend ) );
|
||||
SetDialogVariable( "friend", steamapicontext->SteamFriends()->GetFriendPersonaName( ulSteamIDFriend ) );
|
||||
|
||||
// store the friend we're associated with
|
||||
m_SteamIDFriend = ulSteamIDFriend;
|
||||
|
||||
FriendGameInfo_t friendGameInfo;
|
||||
if ( steamapicontext->SteamFriends()->GetFriendGamePlayed( ulSteamIDFriend, &friendGameInfo ) )
|
||||
{
|
||||
uint16 usConnPort = friendGameInfo.m_usGamePort;
|
||||
if ( friendGameInfo.m_usQueryPort < QUERY_PORT_ERROR )
|
||||
usConnPort = friendGameInfo.m_usQueryPort;
|
||||
ChangeGame( friendGameInfo.m_unGameIP, usConnPort, friendGameInfo.m_usGamePort );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data access
|
||||
//-----------------------------------------------------------------------------
|
||||
uint64 CDialogGameInfo::GetAssociatedFriend()
|
||||
{
|
||||
return m_SteamIDFriend;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: lays out the data
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::PerformLayout()
|
||||
{
|
||||
BaseClass::PerformLayout();
|
||||
|
||||
SetControlString( "ServerText", m_Server.GetName() );
|
||||
SetControlString( "GameText", m_Server.m_szGameDescription );
|
||||
SetControlString( "MapText", m_Server.m_szMap );
|
||||
SetControlString( "GameTags", m_Server.m_szGameTags );
|
||||
|
||||
|
||||
if ( !m_Server.m_bHadSuccessfulResponse )
|
||||
{
|
||||
SetControlString("SecureText", "");
|
||||
}
|
||||
else if ( m_Server.m_bSecure )
|
||||
{
|
||||
SetControlString("SecureText", "#ServerBrowser_Secure");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetControlString("SecureText", "#ServerBrowser_NotSecure");
|
||||
}
|
||||
|
||||
char buf[128];
|
||||
if ( m_Server.m_nMaxPlayers > 0)
|
||||
{
|
||||
Q_snprintf(buf, sizeof(buf), "%d / %d", m_Server.m_nPlayers, m_Server.m_nMaxPlayers);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[0] = 0;
|
||||
}
|
||||
SetControlString("PlayersText", buf);
|
||||
|
||||
if ( m_Server.m_NetAdr.GetIP() && m_Server.m_NetAdr.GetQueryPort() )
|
||||
{
|
||||
SetControlString("ServerIPText", m_Server.m_NetAdr.GetConnectionAddressString() );
|
||||
m_pConnectButton->SetEnabled(true);
|
||||
if ( m_pAutoRetry->IsSelected() )
|
||||
{
|
||||
m_pAutoRetryAlert->SetVisible(true);
|
||||
m_pAutoRetryJoin->SetVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pAutoRetryAlert->SetVisible(false);
|
||||
m_pAutoRetryJoin->SetVisible(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetControlString("ServerIPText", "");
|
||||
m_pConnectButton->SetEnabled(false);
|
||||
}
|
||||
|
||||
if ( m_Server.m_bHadSuccessfulResponse )
|
||||
{
|
||||
Q_snprintf(buf, sizeof(buf), "%d", m_Server.m_nPing );
|
||||
SetControlString("PingText", buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetControlString("PingText", "");
|
||||
}
|
||||
|
||||
// set the info text
|
||||
if ( m_pAutoRetry->IsSelected() )
|
||||
{
|
||||
if ( m_Server.m_nPlayers < m_Server.m_nMaxPlayers )
|
||||
{
|
||||
m_pInfoLabel->SetText("#ServerBrowser_PressJoinToConnect");
|
||||
}
|
||||
else if (m_pAutoRetryJoin->IsSelected())
|
||||
{
|
||||
m_pInfoLabel->SetText("#ServerBrowser_JoinWhenSlotIsFree");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pInfoLabel->SetText("#ServerBrowser_AlertWhenSlotIsFree");
|
||||
}
|
||||
}
|
||||
else if (m_bServerFull)
|
||||
{
|
||||
m_pInfoLabel->SetText("#ServerBrowser_CouldNotConnectServerFull");
|
||||
}
|
||||
else if (m_bServerNotResponding)
|
||||
{
|
||||
m_pInfoLabel->SetText("#ServerBrowser_ServerNotResponding");
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear the status
|
||||
m_pInfoLabel->SetText("");
|
||||
}
|
||||
|
||||
if ( m_Server.m_bHadSuccessfulResponse && !(m_Server.m_nPlayers + m_Server.m_nBotPlayers) )
|
||||
{
|
||||
m_pPlayerList->SetEmptyListText("#ServerBrowser_ServerHasNoPlayers");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPlayerList->SetEmptyListText("#ServerBrowser_ServerNotResponding");
|
||||
}
|
||||
|
||||
// auto-retry layout
|
||||
m_pAutoRetry->SetVisible(m_bShowAutoRetryToggle);
|
||||
|
||||
Repaint();
|
||||
}
|
||||
|
||||
void CDialogGameInfo::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
if ( code == KEY_XBUTTON_B || code == KEY_XBUTTON_A || code == STEAMCONTROLLER_A || code == STEAMCONTROLLER_B )
|
||||
{
|
||||
m_pCloseButton->DoClick();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnKeyCodePressed(code);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Forces the game info dialog to try and connect
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::Connect()
|
||||
{
|
||||
OnConnect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Connects the user to this game
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnConnect()
|
||||
{
|
||||
// flag that we are attempting connection
|
||||
m_bConnecting = true;
|
||||
|
||||
// reset state
|
||||
m_bServerFull = false;
|
||||
m_bServerNotResponding = false;
|
||||
|
||||
InvalidateLayout();
|
||||
|
||||
// need to refresh server before attempting to connect, to make sure there is enough room on the server
|
||||
m_iRequestRetry = 0;
|
||||
RequestInfo();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Cancel auto-retry if we connect to the game by other means
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnConnectToGame( int ip, int port )
|
||||
{
|
||||
// if we just connected to the server we were looking at, close the dialog
|
||||
// important so that we don't auto-retry a server that we are already on
|
||||
if ( m_Server.m_NetAdr.GetIP() == (uint32)ip && m_Server.m_NetAdr.GetConnectionPort() == (uint16)port )
|
||||
{
|
||||
// close this dialog
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles Refresh button press, starts a re-ping of the server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnRefresh()
|
||||
{
|
||||
m_iRequestRetry = 0;
|
||||
// re-ask the server for the game info
|
||||
RequestInfo();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Forces the whole dialog to redraw when the auto-retry button is toggled
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnButtonToggled(Panel *panel)
|
||||
{
|
||||
if (panel == m_pAutoRetry)
|
||||
{
|
||||
ShowAutoRetryOptions(m_pAutoRetry->IsSelected());
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sets whether the extended auto-retry options are visible or not
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ShowAutoRetryOptions(bool state)
|
||||
{
|
||||
// we need to extend the dialog
|
||||
int growSize = 60;
|
||||
if (!state)
|
||||
{
|
||||
growSize = -growSize;
|
||||
}
|
||||
|
||||
// alter the dialog size accordingly
|
||||
int x, y, wide, tall;
|
||||
GetBounds( x, y, wide, tall );
|
||||
|
||||
// load a new layout file depending on the state
|
||||
SetMinimumSize(416, 340);
|
||||
if ( state )
|
||||
LoadControlSettings( "Servers/DialogGameInfo_AutoRetry.res" );
|
||||
else
|
||||
LoadControlSettings( "Servers/DialogGameInfo.res" );
|
||||
|
||||
// restore size and position as
|
||||
// load control settings will override them
|
||||
SetBounds( x, y, wide, tall + growSize );
|
||||
|
||||
// restore other properties of the dialog
|
||||
PerformLayout();
|
||||
|
||||
m_pAutoRetryAlert->SetSelected( true );
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Requests the right info from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::RequestInfo()
|
||||
{
|
||||
if ( !steamapicontext->SteamMatchmakingServers() )
|
||||
return;
|
||||
|
||||
if ( m_iRequestRetry == 0 )
|
||||
{
|
||||
// reset the time at which we auto-refresh
|
||||
m_iRequestRetry = system()->GetTimeMillis() + RETRY_TIME;
|
||||
if ( m_hPingQuery != HSERVERQUERY_INVALID )
|
||||
steamapicontext->SteamMatchmakingServers()->CancelServerQuery( m_hPingQuery );
|
||||
m_hPingQuery = steamapicontext->SteamMatchmakingServers()->PingServer( m_Server.m_NetAdr.GetIP(), m_Server.m_NetAdr.GetQueryPort(), this );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called every frame, handles resending network messages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnTick()
|
||||
{
|
||||
// check to see if we should perform an auto-refresh
|
||||
if ( m_iRequestRetry && m_iRequestRetry < system()->GetTimeMillis() )
|
||||
{
|
||||
m_iRequestRetry = 0;
|
||||
RequestInfo();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the server has successfully responded
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ServerResponded( gameserveritem_t &server )
|
||||
{
|
||||
if( m_Server.m_NetAdr.GetQueryPort() &&
|
||||
m_Server.m_NetAdr.GetQueryPort() != server.m_NetAdr.GetQueryPort() )
|
||||
{
|
||||
return; // this is not the guy we talked about
|
||||
}
|
||||
|
||||
uint16 connectionPort = m_Server.m_NetAdr.GetConnectionPort();
|
||||
|
||||
// FIXME(johns): This is a workaround for a steam bug, where it inproperly reads signed bytes out of the
|
||||
// message. Once the upstream fix makes it into our SteamSDK, this block can be removed.
|
||||
server.m_nPlayers = (uint8)(int8)server.m_nPlayers;
|
||||
server.m_nBotPlayers = (uint8)(int8)server.m_nBotPlayers;
|
||||
server.m_nMaxPlayers = (uint8)(int8)server.m_nMaxPlayers;
|
||||
|
||||
m_hPingQuery = HSERVERQUERY_INVALID;
|
||||
m_Server = server;
|
||||
|
||||
// Preserve our connection port, since we may be querying the sourceTV port but getting a response for the real
|
||||
// server. This is a limitation of the steam Matchmaking API where it doesn't properly send us a sourcetv response
|
||||
// but instead the main server's response (unless we're connecting to a proxy, THEN we get the sourcetv response!)
|
||||
m_Server.m_NetAdr.SetConnectionPort( connectionPort );
|
||||
|
||||
if ( m_bConnecting )
|
||||
{
|
||||
ConnectToServer();
|
||||
}
|
||||
else if ( m_pAutoRetry->IsSelected() && server.m_nPlayers < server.m_nMaxPlayers )
|
||||
{
|
||||
// there is a slot free, we can join
|
||||
|
||||
// make the sound
|
||||
surface()->PlaySound("Servers/game_ready.wav");
|
||||
|
||||
// flash this window
|
||||
FlashWindow();
|
||||
|
||||
// if it's set, connect right away
|
||||
if (m_pAutoRetryJoin->IsSelected())
|
||||
{
|
||||
ConnectToServer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SendPlayerQuery( server.m_NetAdr.GetIP(), server.m_NetAdr.GetQueryPort() );
|
||||
}
|
||||
|
||||
m_bServerNotResponding = false;
|
||||
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when a server response has timed out
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ServerFailedToRespond()
|
||||
{
|
||||
// the server didn't respond, mark that in the UI
|
||||
// only mark if we haven't ever received a response
|
||||
if ( !m_Server.m_bHadSuccessfulResponse )
|
||||
{
|
||||
m_bServerNotResponding = true;
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructs a command to send a running game to connect to a server,
|
||||
// based on the server type
|
||||
//
|
||||
// TODO it would be nice to push this logic into the IRunGameEngine interface; that
|
||||
// way we could ask the engine itself to construct arguments in ways that fit.
|
||||
// Might be worth the effort as we start to add more engines.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ApplyConnectCommand( const gameserveritem_t &server )
|
||||
{
|
||||
char command[ 256 ];
|
||||
// set the server password, if any
|
||||
if ( m_szPassword[0] )
|
||||
{
|
||||
Q_snprintf( command, Q_ARRAYSIZE( command ), "password \"%s\"\n", m_szPassword );
|
||||
g_pRunGameEngine->AddTextCommand( command );
|
||||
}
|
||||
// send engine command to change servers
|
||||
Q_snprintf( command, Q_ARRAYSIZE( command ), "connect %s %s\n", server.m_NetAdr.GetConnectionAddressString(), m_sConnectCode.String() );
|
||||
g_pRunGameEngine->AddTextCommand( command );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructs game options to use when running a game to connect to a server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ConstructConnectArgs( char *pchOptions, int cchOptions, const gameserveritem_t &server )
|
||||
{
|
||||
Q_snprintf( pchOptions, cchOptions, " +connect %s", server.m_NetAdr.GetConnectionAddressString() );
|
||||
if ( m_szPassword[0] )
|
||||
{
|
||||
Q_strcat( pchOptions, " +password \"", cchOptions );
|
||||
Q_strcat( pchOptions, m_szPassword, cchOptions );
|
||||
Q_strcat( pchOptions, "\"", cchOptions );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Connects to the server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ConnectToServer()
|
||||
{
|
||||
m_bConnecting = false;
|
||||
|
||||
// check VAC status
|
||||
if ( m_Server.m_bSecure && ServerBrowser().IsVACBannedFromGame( m_Server.m_nAppID ) )
|
||||
{
|
||||
// refuse the user
|
||||
CVACBannedConnRefusedDialog *pDlg = new CVACBannedConnRefusedDialog( GetVParent(), "VACBannedConnRefusedDialog" );
|
||||
pDlg->Activate();
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// check to see if we need a password
|
||||
if ( m_Server.m_bPassword && !m_szPassword[0] )
|
||||
{
|
||||
CDialogServerPassword *box = new CDialogServerPassword(this);
|
||||
box->AddActionSignalTarget(this);
|
||||
box->Activate( m_Server.GetName(), 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
// check the player count
|
||||
if ( m_Server.m_nPlayers >= m_Server.m_nMaxPlayers )
|
||||
{
|
||||
// mark why we cannot connect
|
||||
m_bServerFull = true;
|
||||
// give them access to auto-retry options
|
||||
m_bShowAutoRetryToggle = true;
|
||||
InvalidateLayout();
|
||||
return;
|
||||
}
|
||||
|
||||
// tell the engine to connect
|
||||
const char *gameDir = m_Server.m_szGameDir;
|
||||
if (g_pRunGameEngine->IsRunning())
|
||||
{
|
||||
ApplyConnectCommand( m_Server );
|
||||
}
|
||||
else
|
||||
{
|
||||
char connectArgs[256];
|
||||
ConstructConnectArgs( connectArgs, Q_ARRAYSIZE( connectArgs ), m_Server );
|
||||
|
||||
if ( ( m_Server.m_bSecure && JoiningSecureServerCall() )|| !m_Server.m_bSecure )
|
||||
{
|
||||
switch ( g_pRunGameEngine->RunEngine( m_Server.m_nAppID, gameDir, connectArgs ) )
|
||||
{
|
||||
case IRunGameEngine::k_ERunResultModNotInstalled:
|
||||
{
|
||||
MessageBox *dlg = new MessageBox( "#ServerBrowser_GameInfoTitle", "#ServerBrowser_ModNotInstalled" );
|
||||
dlg->DoModal();
|
||||
SetVisible(false);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IRunGameEngine::k_ERunResultAppNotFound:
|
||||
{
|
||||
MessageBox *dlg = new MessageBox( "#ServerBrowser_GameInfoTitle", "#ServerBrowser_AppNotFound" );
|
||||
dlg->DoModal();
|
||||
SetVisible(false);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IRunGameEngine::k_ERunResultNotInitialized:
|
||||
{
|
||||
MessageBox *dlg = new MessageBox( "#ServerBrowser_GameInfoTitle", "#ServerBrowser_NotInitialized" );
|
||||
dlg->DoModal();
|
||||
SetVisible(false);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IRunGameEngine::k_ERunResultOkay:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// close this dialog
|
||||
PostMessage(this, new KeyValues("Close"));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the current refresh list is complete
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::RefreshComplete( EMatchMakingServerResponse response )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: handles response from the get password dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::OnJoinServerWithPassword(const char *password)
|
||||
{
|
||||
// copy out the password
|
||||
Q_strncpy(m_szPassword, password, sizeof(m_szPassword));
|
||||
|
||||
// retry connecting to the server again
|
||||
OnConnect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: player list received
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::ClearPlayerList()
|
||||
{
|
||||
m_pPlayerList->DeleteAllItems();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: on individual player added
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogGameInfo::AddPlayerToList(const char *playerName, int score, float timePlayedSeconds)
|
||||
{
|
||||
if ( m_bPlayerListUpdatePending )
|
||||
{
|
||||
m_bPlayerListUpdatePending = false;
|
||||
m_pPlayerList->RemoveAll();
|
||||
}
|
||||
|
||||
KeyValues *player = new KeyValues("player");
|
||||
player->SetString("PlayerName", playerName);
|
||||
player->SetInt("Score", score);
|
||||
player->SetInt("TimeSec", (int)timePlayedSeconds);
|
||||
|
||||
// construct a time string
|
||||
int seconds = (int)timePlayedSeconds;
|
||||
int minutes = seconds / 60;
|
||||
int hours = minutes / 60;
|
||||
seconds %= 60;
|
||||
minutes %= 60;
|
||||
char buf[64];
|
||||
buf[0] = 0;
|
||||
if (hours)
|
||||
{
|
||||
Q_snprintf(buf, sizeof(buf), "%dh %dm %ds", hours, minutes, seconds);
|
||||
}
|
||||
else if (minutes)
|
||||
{
|
||||
Q_snprintf(buf, sizeof(buf), "%dm %ds", minutes, seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf(buf, sizeof(buf), "%ds", seconds);
|
||||
}
|
||||
player->SetString("Time", buf);
|
||||
|
||||
m_pPlayerList->AddItem(player, 0, false, true);
|
||||
player->deleteThis();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sorting function for time column
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDialogGameInfo::PlayerTimeColumnSortFunc(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
int p1time = p1.kv->GetInt("TimeSec");
|
||||
int p2time = p2.kv->GetInt("TimeSec");
|
||||
|
||||
if (p1time > p2time)
|
||||
return -1;
|
||||
if (p1time < p2time)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
126
serverbrowser/DialogGameInfo.h
Normal file
126
serverbrowser/DialogGameInfo.h
Normal file
@ -0,0 +1,126 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DIALOGGAMEINFO_H
|
||||
#define DIALOGGAMEINFO_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct challenge_s
|
||||
{
|
||||
netadr_t addr;
|
||||
int challenge;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dialog for displaying information about a game server
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDialogGameInfo : public vgui::Frame, public ISteamMatchmakingPlayersResponse, public ISteamMatchmakingPingResponse
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CDialogGameInfo, vgui::Frame );
|
||||
|
||||
public:
|
||||
CDialogGameInfo(vgui::Panel *parent, int serverIP, int queryPort, unsigned short connectionPort, const char *pszConnectCode );
|
||||
~CDialogGameInfo();
|
||||
|
||||
void Run(const char *titleName);
|
||||
void ChangeGame(int serverIP, int queryPort, unsigned short connectionPort);
|
||||
void SetFriend( uint64 ulSteamIDFriend );
|
||||
uint64 GetAssociatedFriend();
|
||||
|
||||
// forces the dialog to attempt to connect to the server
|
||||
void Connect();
|
||||
|
||||
// implementation of IServerRefreshResponse interface
|
||||
// called when the server has successfully responded
|
||||
virtual void ServerResponded( gameserveritem_t &server );
|
||||
|
||||
// called when a server response has timed out
|
||||
virtual void ServerFailedToRespond();
|
||||
|
||||
// on individual player added
|
||||
virtual void AddPlayerToList(const char *playerName, int score, float timePlayedSeconds);
|
||||
virtual void PlayersFailedToRespond() {}
|
||||
virtual void PlayersRefreshComplete() { m_hPlayersQuery = HSERVERQUERY_INVALID; }
|
||||
|
||||
// called when the current refresh list is complete
|
||||
virtual void RefreshComplete( EMatchMakingServerResponse response );
|
||||
|
||||
// player list received
|
||||
virtual void ClearPlayerList();
|
||||
|
||||
//virtual void SendChallengeQuery( const netadr_t & to );
|
||||
virtual void SendPlayerQuery( uint32 unIP, uint16 usQueryPort );
|
||||
//virtual void InsertChallengeResponse( const netadr_t & to, int nChallenge );
|
||||
|
||||
protected:
|
||||
// message handlers
|
||||
MESSAGE_FUNC( OnConnect, "Connect" );
|
||||
MESSAGE_FUNC( OnRefresh, "Refresh" );
|
||||
MESSAGE_FUNC_PTR( OnButtonToggled, "ButtonToggled", panel );
|
||||
MESSAGE_FUNC_PTR( OnRadioButtonChecked, "RadioButtonChecked", panel )
|
||||
{
|
||||
OnButtonToggled( panel );
|
||||
}
|
||||
|
||||
// response from the get password dialog
|
||||
MESSAGE_FUNC_CHARPTR( OnJoinServerWithPassword, "JoinServerWithPassword", password );
|
||||
|
||||
MESSAGE_FUNC_INT_INT( OnConnectToGame, "ConnectedToGame", ip, port );
|
||||
|
||||
// vgui overrides
|
||||
virtual void OnTick();
|
||||
virtual void PerformLayout();
|
||||
|
||||
virtual void OnKeyCodePressed( vgui::KeyCode code );
|
||||
|
||||
private:
|
||||
STEAM_CALLBACK( CDialogGameInfo, OnPersonaStateChange, PersonaStateChange_t, m_CallbackPersonaStateChange );
|
||||
|
||||
long m_iRequestRetry; // time at which to retry the request
|
||||
static int PlayerTimeColumnSortFunc(vgui::ListPanel *pPanel, const vgui::ListPanelItem &p1, const vgui::ListPanelItem &p2);
|
||||
|
||||
// methods
|
||||
void RequestInfo();
|
||||
void ConnectToServer();
|
||||
void ShowAutoRetryOptions(bool state);
|
||||
void ConstructConnectArgs( char *pchOptions, int cchOptions, const gameserveritem_t &server );
|
||||
void ApplyConnectCommand( const gameserveritem_t &server );
|
||||
|
||||
vgui::Button *m_pConnectButton;
|
||||
vgui::Button *m_pCloseButton;
|
||||
vgui::Button *m_pRefreshButton;
|
||||
vgui::Label *m_pInfoLabel;
|
||||
vgui::ToggleButton *m_pAutoRetry;
|
||||
vgui::RadioButton *m_pAutoRetryAlert;
|
||||
vgui::RadioButton *m_pAutoRetryJoin;
|
||||
vgui::ListPanel *m_pPlayerList;
|
||||
|
||||
enum { PING_TIMES_MAX = 4 };
|
||||
|
||||
// true if we should try connect to the server when it refreshes
|
||||
bool m_bConnecting;
|
||||
|
||||
// password, if entered
|
||||
char m_szPassword[64];
|
||||
|
||||
// state
|
||||
bool m_bServerNotResponding;
|
||||
bool m_bServerFull;
|
||||
bool m_bShowAutoRetryToggle;
|
||||
bool m_bShowingExtendedOptions;
|
||||
uint64 m_SteamIDFriend;
|
||||
|
||||
CUtlString m_sConnectCode;
|
||||
gameserveritem_t m_Server;
|
||||
HServerQuery m_hPingQuery;
|
||||
HServerQuery m_hPlayersQuery;
|
||||
bool m_bPlayerListUpdatePending;
|
||||
};
|
||||
|
||||
#endif // DIALOGGAMEINFO_H
|
89
serverbrowser/DialogServerPassword.cpp
Normal file
89
serverbrowser/DialogServerPassword.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogServerPassword::CDialogServerPassword(vgui::Panel *parent) : Frame(parent, "DialogServerPassword")
|
||||
{
|
||||
m_iServerID = -1;
|
||||
SetSize(320, 240);
|
||||
SetDeleteSelfOnClose(true);
|
||||
SetSizeable(false);
|
||||
|
||||
m_pInfoLabel = new Label(this, "InfoLabel", "#ServerBrowser_ServerRequiresPassword");
|
||||
m_pGameLabel = new Label(this, "GameLabel", "<game label>");
|
||||
m_pPasswordEntry = new TextEntry(this, "PasswordEntry");
|
||||
m_pConnectButton = new Button(this, "ConnectButton", "#ServerBrowser_Connect");
|
||||
m_pPasswordEntry->SetTextHidden(true);
|
||||
|
||||
LoadControlSettings("Servers/DialogServerPassword.res");
|
||||
|
||||
SetTitle("#ServerBrowser_ServerRequiresPasswordTitle", true);
|
||||
|
||||
// set our initial position in the middle of the workspace
|
||||
MoveToCenterOfScreen();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogServerPassword::~CDialogServerPassword()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: initializes the dialog and brings it to the foreground
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogServerPassword::Activate(const char *serverName, unsigned int serverID)
|
||||
{
|
||||
m_pGameLabel->SetText(serverName);
|
||||
m_iServerID = serverID;
|
||||
|
||||
m_pConnectButton->SetAsDefaultButton(true);
|
||||
m_pPasswordEntry->RequestFocus();
|
||||
BaseClass::Activate();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *command -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDialogServerPassword::OnCommand(const char *command)
|
||||
{
|
||||
bool bClose = false;
|
||||
|
||||
if (!Q_stricmp(command, "Connect"))
|
||||
{
|
||||
KeyValues *msg = new KeyValues("JoinServerWithPassword");
|
||||
char buf[64];
|
||||
m_pPasswordEntry->GetText(buf, sizeof(buf)-1);
|
||||
msg->SetString("password", buf);
|
||||
msg->SetInt("serverID", m_iServerID);
|
||||
PostActionSignal(msg);
|
||||
|
||||
bClose = true;
|
||||
}
|
||||
else if (!Q_stricmp(command, "Close"))
|
||||
{
|
||||
bClose = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
|
||||
if (bClose)
|
||||
{
|
||||
PostMessage(this, new KeyValues("Close"));
|
||||
}
|
||||
}
|
||||
|
46
serverbrowser/DialogServerPassword.h
Normal file
46
serverbrowser/DialogServerPassword.h
Normal file
@ -0,0 +1,46 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DIALOGSERVERPASSWORD_H
|
||||
#define DIALOGSERVERPASSWORD_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Prompt for user to enter a password to be able to connect to the server
|
||||
//-----------------------------------------------------------------------------
|
||||
class CDialogServerPassword : public vgui::Frame
|
||||
{
|
||||
public:
|
||||
CDialogServerPassword(vgui::Panel *parent);
|
||||
~CDialogServerPassword();
|
||||
|
||||
// initializes the dialog and brings it to the foreground
|
||||
void Activate(const char *serverName, unsigned int serverID);
|
||||
|
||||
/* message returned:
|
||||
"JoinServerWithPassword"
|
||||
"serverID"
|
||||
"password"
|
||||
*/
|
||||
|
||||
private:
|
||||
virtual void OnCommand(const char *command);
|
||||
|
||||
vgui::Label *m_pInfoLabel;
|
||||
vgui::Label *m_pGameLabel;
|
||||
vgui::TextEntry *m_pPasswordEntry;
|
||||
vgui::Button *m_pConnectButton;
|
||||
|
||||
typedef vgui::Frame BaseClass;
|
||||
|
||||
int m_iServerID;
|
||||
};
|
||||
|
||||
|
||||
#endif // DIALOGSERVERPASSWORD_H
|
214
serverbrowser/FavoriteGames.cpp
Normal file
214
serverbrowser/FavoriteGames.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFavoriteGames::CFavoriteGames(vgui::Panel *parent) :
|
||||
CBaseGamesPage(parent, "FavoriteGames", eFavoritesServer )
|
||||
{
|
||||
m_bRefreshOnListReload = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFavoriteGames::~CFavoriteGames()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads favorites list from disk
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::LoadFavoritesList()
|
||||
{
|
||||
if ( steamapicontext->SteamMatchmaking() && steamapicontext->SteamMatchmaking()->GetFavoriteGameCount() == 0 )
|
||||
{
|
||||
// set empty message
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoFavoriteServers");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoInternetGamesResponded");
|
||||
|
||||
}
|
||||
|
||||
if ( m_bRefreshOnListReload )
|
||||
{
|
||||
m_bRefreshOnListReload = false;
|
||||
StartRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if the game list supports the specified ui elements
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFavoriteGames::SupportsItem(InterfaceItem_e item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case FILTERS:
|
||||
case ADDSERVER:
|
||||
return true;
|
||||
|
||||
case ADDCURRENTSERVER:
|
||||
return !IsSteam() && BFiltersVisible();
|
||||
|
||||
case GETNEWLIST:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the current refresh list is complete
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response )
|
||||
{
|
||||
SetRefreshing(false);
|
||||
if ( steamapicontext->SteamMatchmaking() && steamapicontext->SteamMatchmaking()->GetFavoriteGameCount() == 0 )
|
||||
{
|
||||
// set empty message
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoFavoriteServers");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoInternetGamesResponded");
|
||||
|
||||
}
|
||||
m_pGameList->SortList();
|
||||
|
||||
BaseClass::RefreshComplete( hReq, response );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens context menu (user right clicked on a server)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnOpenContextMenu(int itemID)
|
||||
{
|
||||
CServerContextMenu *menu = ServerBrowserDialog().GetContextMenu(GetActiveList());
|
||||
|
||||
// get the server
|
||||
int serverID = GetSelectedServerID();
|
||||
|
||||
if ( serverID != -1 )
|
||||
{
|
||||
// Activate context menu
|
||||
menu->ShowMenu(this, serverID, true, true, true, false);
|
||||
menu->AddMenuItem("RemoveServer", "#ServerBrowser_RemoveServerFromFavorites", new KeyValues("RemoveFromFavorites"), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no selected rows, so don't display default stuff in menu
|
||||
menu->ShowMenu( this,(uint32)-1, false, false, false, false );
|
||||
}
|
||||
|
||||
menu->AddMenuItem("AddServerByName", "#ServerBrowser_AddServerByIP", new KeyValues("AddServerByName"), this);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: removes a server from the favorites
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnRemoveFromFavorites()
|
||||
{
|
||||
if ( !steamapicontext->SteamMatchmakingServers() || !steamapicontext->SteamMatchmaking() )
|
||||
return;
|
||||
|
||||
// iterate the selection
|
||||
for ( int iGame = 0; iGame < m_pGameList->GetSelectedItemsCount(); iGame++ )
|
||||
{
|
||||
int itemID = m_pGameList->GetSelectedItem( iGame );
|
||||
int serverID = m_pGameList->GetItemData(itemID)->userData;
|
||||
|
||||
gameserveritem_t *pServer = steamapicontext->SteamMatchmakingServers()->GetServerDetails( m_hRequest, serverID );
|
||||
|
||||
if ( pServer )
|
||||
{
|
||||
steamapicontext->SteamMatchmaking()->RemoveFavoriteGame( pServer->m_nAppID, pServer->m_NetAdr.GetIP(), pServer->m_NetAdr.GetConnectionPort(), pServer->m_NetAdr.GetQueryPort(), k_unFavoriteFlagFavorite );
|
||||
}
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a server by IP address
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnAddServerByName()
|
||||
{
|
||||
// open the add server dialog
|
||||
CDialogAddServer *dlg = new CDialogAddServer( &ServerBrowserDialog(), this );
|
||||
dlg->MoveToCenterOfScreen();
|
||||
dlg->DoModal();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds the currently connected server to the list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnAddCurrentServer()
|
||||
{
|
||||
gameserveritem_t *pConnected = ServerBrowserDialog().GetCurrentConnectedServer();
|
||||
|
||||
if ( pConnected && steamapicontext->SteamMatchmaking() )
|
||||
{
|
||||
steamapicontext->SteamMatchmaking()->AddFavoriteGame( pConnected->m_nAppID, pConnected->m_NetAdr.GetIP(), pConnected->m_NetAdr.GetConnectionPort(), pConnected->m_NetAdr.GetQueryPort(), k_unFavoriteFlagFavorite, time( NULL ) );
|
||||
m_bRefreshOnListReload = true;
|
||||
|
||||
if ( GameSupportsReplay() )
|
||||
{
|
||||
// send command to propagate to the client so the client can send it on to the GC
|
||||
char command[ 256 ];
|
||||
Q_snprintf( command, Q_ARRAYSIZE( command ), "rfgc %s\n", pConnected->m_NetAdr.GetConnectionAddressString() );
|
||||
g_pRunGameEngine->AddTextCommand( command );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Parse posted messages
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnCommand(const char *command)
|
||||
{
|
||||
if (!Q_stricmp(command, "AddServerByName"))
|
||||
{
|
||||
OnAddServerByName();
|
||||
}
|
||||
else if (!Q_stricmp(command, "AddCurrentServer" ))
|
||||
{
|
||||
OnAddCurrentServer();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: enables adding server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnConnectToGame()
|
||||
{
|
||||
m_pAddCurrentServer->SetEnabled( true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: disables adding current server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFavoriteGames::OnDisconnectFromGame( void )
|
||||
{
|
||||
m_pAddCurrentServer->SetEnabled( false );
|
||||
}
|
55
serverbrowser/FavoriteGames.h
Normal file
55
serverbrowser/FavoriteGames.h
Normal file
@ -0,0 +1,55 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef FAVORITEGAMES_H
|
||||
#define FAVORITEGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Favorite games list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFavoriteGames : public CBaseGamesPage
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CFavoriteGames, CBaseGamesPage );
|
||||
|
||||
public:
|
||||
CFavoriteGames(vgui::Panel *parent);
|
||||
~CFavoriteGames();
|
||||
|
||||
// favorites list, loads/saves into keyvalues
|
||||
void LoadFavoritesList();
|
||||
|
||||
// IGameList handlers
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(InterfaceItem_e item);
|
||||
|
||||
// called when the current refresh list is complete
|
||||
virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response );
|
||||
|
||||
// passed from main server browser window instead of messages
|
||||
void OnConnectToGame();
|
||||
void OnDisconnectFromGame( void );
|
||||
|
||||
void SetRefreshOnReload() { m_bRefreshOnListReload = true; }
|
||||
|
||||
private:
|
||||
// context menu message handlers
|
||||
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
|
||||
MESSAGE_FUNC( OnRemoveFromFavorites, "RemoveFromFavorites" );
|
||||
MESSAGE_FUNC( OnAddServerByName, "AddServerByName" );
|
||||
|
||||
void OnAddCurrentServer( void );
|
||||
|
||||
void OnCommand(const char *command);
|
||||
|
||||
bool m_bRefreshOnListReload;
|
||||
};
|
||||
|
||||
|
||||
#endif // FAVORITEGAMES_H
|
88
serverbrowser/FriendsGames.cpp
Normal file
88
serverbrowser/FriendsGames.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFriendsGames::CFriendsGames(vgui::Panel *parent) :
|
||||
CBaseGamesPage(parent, "FriendsGames", eFriendsServer )
|
||||
{
|
||||
m_iServerRefreshCount = 0;
|
||||
|
||||
if ( !IsSteamGameServerBrowsingEnabled() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CFriendsGames::~CFriendsGames()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if the game list supports the specified ui elements
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CFriendsGames::SupportsItem(InterfaceItem_e item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case FILTERS:
|
||||
return true;
|
||||
|
||||
case GETNEWLIST:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the current refresh list is complete
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFriendsGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response )
|
||||
{
|
||||
SetRefreshing(false);
|
||||
m_pGameList->SortList();
|
||||
m_iServerRefreshCount = 0;
|
||||
|
||||
if ( IsSteamGameServerBrowsingEnabled() )
|
||||
{
|
||||
// set empty message
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoFriendsServers");
|
||||
}
|
||||
|
||||
BaseClass::RefreshComplete( hReq, response );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens context menu (user right clicked on a server)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CFriendsGames::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);
|
||||
}
|
39
serverbrowser/FriendsGames.h
Normal file
39
serverbrowser/FriendsGames.h
Normal file
@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef FRIENDSGAMES_H
|
||||
#define FRIENDSGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Favorite games list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFriendsGames : public CBaseGamesPage
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CFriendsGames, CBaseGamesPage );
|
||||
|
||||
public:
|
||||
CFriendsGames(vgui::Panel *parent);
|
||||
~CFriendsGames();
|
||||
|
||||
// IGameList handlers
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(InterfaceItem_e item);
|
||||
|
||||
// called when the current refresh list is complete
|
||||
virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response );
|
||||
|
||||
private:
|
||||
// context menu message handlers
|
||||
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
|
||||
|
||||
int m_iServerRefreshCount; // number of servers refreshed
|
||||
};
|
||||
|
||||
#endif // FRIENDSGAMES_H
|
136
serverbrowser/HistoryGames.cpp
Normal file
136
serverbrowser/HistoryGames.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHistoryGames::CHistoryGames(vgui::Panel *parent) :
|
||||
CBaseGamesPage(parent, "HistoryGames", eHistoryServer )
|
||||
{
|
||||
m_bRefreshOnListReload = false;
|
||||
m_pGameList->AddColumnHeader(10, "LastPlayed", "#ServerBrowser_LastPlayed", 100);
|
||||
m_pGameList->SetSortFunc(10, LastPlayedCompare);
|
||||
m_pGameList->SetSortColumn(10);
|
||||
|
||||
if ( !IsSteamGameServerBrowsingEnabled() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHistoryGames::~CHistoryGames()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: loads favorites list from disk
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHistoryGames::LoadHistoryList()
|
||||
{
|
||||
if ( IsSteamGameServerBrowsingEnabled() )
|
||||
{
|
||||
// set empty message
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoServersPlayed");
|
||||
}
|
||||
|
||||
if ( m_bRefreshOnListReload )
|
||||
{
|
||||
m_bRefreshOnListReload = false;
|
||||
StartRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if the game list supports the specified ui elements
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHistoryGames::SupportsItem(InterfaceItem_e item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case FILTERS:
|
||||
return true;
|
||||
|
||||
case ADDSERVER:
|
||||
case GETNEWLIST:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the current refresh list is complete
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHistoryGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response )
|
||||
{
|
||||
SetRefreshing(false);
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoServersPlayed");
|
||||
m_pGameList->SortList();
|
||||
|
||||
BaseClass::RefreshComplete( hReq, response );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens context menu (user right clicked on a server)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHistoryGames::OnOpenContextMenu(int itemID)
|
||||
{
|
||||
CServerContextMenu *menu = ServerBrowserDialog().GetContextMenu(GetActiveList());
|
||||
|
||||
// get the server
|
||||
int serverID = GetSelectedServerID();
|
||||
|
||||
if( serverID != -1 )
|
||||
{
|
||||
// Activate context menu
|
||||
menu->ShowMenu(this, serverID, true, true, true, true);
|
||||
menu->AddMenuItem("RemoveServer", "#ServerBrowser_RemoveServerFromHistory", new KeyValues("RemoveFromHistory"), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no selected rows, so don't display default stuff in menu
|
||||
menu->ShowMenu(this, (uint32)-1, false, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: removes a server from the favorites
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHistoryGames::OnRemoveFromHistory()
|
||||
{
|
||||
if ( !steamapicontext->SteamMatchmakingServers() || !steamapicontext->SteamMatchmaking() )
|
||||
return;
|
||||
|
||||
// iterate the selection
|
||||
for ( int i = m_pGameList->GetSelectedItemsCount() - 1; i >= 0; i-- )
|
||||
{
|
||||
int itemID = m_pGameList->GetSelectedItem( i );
|
||||
int serverID = m_pGameList->GetItemData(itemID)->userData;
|
||||
|
||||
gameserveritem_t *pServer = steamapicontext->SteamMatchmakingServers()->GetServerDetails( m_hRequest, serverID );
|
||||
if ( pServer )
|
||||
steamapicontext->SteamMatchmaking()->RemoveFavoriteGame( pServer->m_nAppID, pServer->m_NetAdr.GetIP(), pServer->m_NetAdr.GetConnectionPort(), pServer->m_NetAdr.GetQueryPort(), k_unFavoriteFlagHistory );
|
||||
}
|
||||
|
||||
UpdateStatus();
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
}
|
||||
|
46
serverbrowser/HistoryGames.h
Normal file
46
serverbrowser/HistoryGames.h
Normal file
@ -0,0 +1,46 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef HISTORYGAMES_H
|
||||
#define HISTORYGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: History of all the servers joined
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHistoryGames : public CBaseGamesPage
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHistoryGames, CBaseGamesPage );
|
||||
|
||||
public:
|
||||
CHistoryGames(vgui::Panel *parent);
|
||||
~CHistoryGames();
|
||||
|
||||
// favorites list, loads/saves into keyvalues
|
||||
void LoadHistoryList();
|
||||
|
||||
|
||||
// IGameList handlers
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(InterfaceItem_e item);
|
||||
|
||||
// called when the current refresh list is complete
|
||||
virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response );
|
||||
|
||||
void SetRefreshOnReload() { m_bRefreshOnListReload = true; }
|
||||
|
||||
private:
|
||||
// context menu message handlers
|
||||
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
|
||||
MESSAGE_FUNC( OnRemoveFromHistory, "RemoveFromHistory" );
|
||||
|
||||
bool m_bRefreshOnListReload;
|
||||
};
|
||||
|
||||
|
||||
#endif // HISTORYGAMES_H
|
319
serverbrowser/InternetGames.cpp
Normal file
319
serverbrowser/InternetGames.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
//========= 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;
|
||||
}
|
83
serverbrowser/InternetGames.h
Normal file
83
serverbrowser/InternetGames.h
Normal file
@ -0,0 +1,83 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef INTERNETGAMES_H
|
||||
#define INTERNETGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "BaseGamesPage.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Internet games list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CInternetGames : public CBaseGamesPage
|
||||
{
|
||||
|
||||
DECLARE_CLASS_SIMPLE( CInternetGames, CBaseGamesPage );
|
||||
|
||||
public:
|
||||
CInternetGames( vgui::Panel *parent, const char *panelName = "InternetGames", EPageType eType = eInternetServer );
|
||||
~CInternetGames();
|
||||
|
||||
// property page handlers
|
||||
virtual void OnPageShow();
|
||||
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(IGameList::InterfaceItem_e item);
|
||||
|
||||
// gets a new server list
|
||||
MESSAGE_FUNC( GetNewServerList, "GetNewServerList" );
|
||||
|
||||
// serverlist refresh responses
|
||||
virtual void ServerResponded( HServerListRequest hReq, int iServer );
|
||||
virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer );
|
||||
virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response );
|
||||
MESSAGE_FUNC_INT( OnRefreshServer, "RefreshServer", serverID );
|
||||
|
||||
virtual int GetRegionCodeToFilter();
|
||||
virtual bool CheckTagFilter( gameserveritem_t &server );
|
||||
|
||||
protected:
|
||||
// vgui overrides
|
||||
virtual void PerformLayout();
|
||||
virtual void OnTick();
|
||||
|
||||
virtual const char *GetStringNoUnfilteredServers() { return "#ServerBrowser_NoInternetGames"; }
|
||||
virtual const char *GetStringNoUnfilteredServersOnMaster() { return "#ServerBrowser_MasterServerHasNoServersListed"; }
|
||||
virtual const char *GetStringNoServersResponded() { return "#ServerBrowser_NoInternetGamesResponded"; }
|
||||
|
||||
private:
|
||||
// Called once per frame to see if sorting needs to occur again
|
||||
void CheckRedoSort();
|
||||
// Called once per frame to check re-send request to master server
|
||||
void CheckRetryRequest( ESteamServerType serverType );
|
||||
// opens context menu (user right clicked on a server)
|
||||
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
|
||||
|
||||
struct regions_s
|
||||
{
|
||||
CUtlSymbol name;
|
||||
unsigned char code;
|
||||
};
|
||||
|
||||
CUtlVector<struct regions_s> m_Regions; // list of the different regions you can query for
|
||||
|
||||
float m_fLastSort; // Time of last re-sort
|
||||
bool m_bDirty; // Has the list been modified, thereby needing re-sort
|
||||
bool m_bRequireUpdate; // checks whether we need an update upon opening
|
||||
|
||||
// error cases for if no servers are listed
|
||||
bool m_bAnyServersRetrievedFromMaster;
|
||||
bool m_bAnyServersRespondedToQuery;
|
||||
bool m_bNoServersListedOnMaster;
|
||||
|
||||
bool m_bOfflineMode;
|
||||
};
|
||||
|
||||
#endif // INTERNETGAMES_H
|
160
serverbrowser/LanGames.cpp
Normal file
160
serverbrowser/LanGames.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
const float BROADCAST_LIST_TIMEOUT = 0.4f;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CLanGames::CLanGames(vgui::Panel *parent, bool bAutoRefresh, const char *pCustomResFilename ) :
|
||||
CBaseGamesPage(parent, "LanGames", eLANServer, pCustomResFilename)
|
||||
{
|
||||
m_iServerRefreshCount = 0;
|
||||
m_bRequesting = false;
|
||||
m_bAutoRefresh = bAutoRefresh;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CLanGames::~CLanGames()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activates the page, starts refresh
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::OnPageShow()
|
||||
{
|
||||
if ( m_bAutoRefresh )
|
||||
StartRefresh();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called every frame
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
CheckRetryRequest();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if the game list supports the specified ui elements
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CLanGames::SupportsItem(InterfaceItem_e item)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case FILTERS:
|
||||
return true;
|
||||
|
||||
case GETNEWLIST:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: starts the servers refreshing
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::StartRefresh()
|
||||
{
|
||||
BaseClass::StartRefresh();
|
||||
m_fRequestTime = Plat_FloatTime();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Control which button are visible.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::ManualShowButtons( bool bShowConnect, bool bShowRefreshAll, bool bShowFilter )
|
||||
{
|
||||
m_pConnect->SetVisible( bShowConnect );
|
||||
m_pRefreshAll->SetVisible( bShowRefreshAll );
|
||||
m_pFilter->SetVisible( bShowFilter );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: stops current refresh/GetNewServerList()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::StopRefresh()
|
||||
{
|
||||
BaseClass::StopRefresh();
|
||||
// clear update states
|
||||
m_bRequesting = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check to see if we've finished looking for local servers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::CheckRetryRequest()
|
||||
{
|
||||
if (!m_bRequesting)
|
||||
return;
|
||||
|
||||
double curtime = Plat_FloatTime();
|
||||
if (curtime - m_fRequestTime <= BROADCAST_LIST_TIMEOUT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// time has elapsed, finish up
|
||||
m_bRequesting = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when a server response has timed out, remove it
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::ServerFailedToRespond( HServerListRequest hReq, int iServer )
|
||||
{
|
||||
int iServerMap = m_mapServers.Find( iServer );
|
||||
if ( iServerMap != m_mapServers.InvalidIndex() )
|
||||
RemoveServer( m_mapServers[ iServerMap ] );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the current refresh list is complete
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response )
|
||||
{
|
||||
SetRefreshing( false );
|
||||
m_pGameList->SortList();
|
||||
m_iServerRefreshCount = 0;
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoLanServers");
|
||||
SetEmptyListText();
|
||||
|
||||
BaseClass::RefreshComplete( hReq, response );
|
||||
}
|
||||
|
||||
void CLanGames::SetEmptyListText()
|
||||
{
|
||||
m_pGameList->SetEmptyListText("#ServerBrowser_NoLanServers");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens context menu (user right clicked on a server)
|
||||
//-----------------------------------------------------------------------------
|
||||
void CLanGames::OnOpenContextMenu(int row)
|
||||
{
|
||||
int serverID = GetSelectedServerID();
|
||||
|
||||
if ( serverID == -1 )
|
||||
return;
|
||||
|
||||
// Activate context menu
|
||||
CServerContextMenu *menu = ServerBrowserDialog().GetContextMenu(GetActiveList());
|
||||
menu->ShowMenu(this, serverID, true, true, true, false);
|
||||
}
|
||||
|
81
serverbrowser/LanGames.h
Normal file
81
serverbrowser/LanGames.h
Normal file
@ -0,0 +1,81 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef LANGAMES_H
|
||||
#define LANGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CLanBroadcastMsgHandler;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Favorite games list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CLanGames : public CBaseGamesPage
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CLanGames, CBaseGamesPage );
|
||||
|
||||
public:
|
||||
CLanGames(vgui::Panel *parent, bool bAutoRefresh=true, const char *pCustomResFilename=NULL);
|
||||
~CLanGames();
|
||||
|
||||
// property page handlers
|
||||
virtual void OnPageShow();
|
||||
|
||||
// IGameList handlers
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(InterfaceItem_e item);
|
||||
|
||||
// Control which button are visible.
|
||||
void ManualShowButtons( bool bShowConnect, bool bShowRefreshAll, bool bShowFilter );
|
||||
|
||||
// If you pass NULL for pSpecificAddresses, it will broadcast on certain points.
|
||||
// If you pass a non-null value, then it will send info queries directly to those ports.
|
||||
void InternalGetNewServerList( CUtlVector<netadr_t> *pSpecificAddresses );
|
||||
|
||||
virtual void StartRefresh();
|
||||
|
||||
// stops current refresh/GetNewServerList()
|
||||
virtual void StopRefresh();
|
||||
|
||||
|
||||
// IServerRefreshResponse handlers
|
||||
// called when a server response has timed out
|
||||
virtual void ServerFailedToRespond( HServerListRequest hReq, int iServer );
|
||||
|
||||
// called when the current refresh list is complete
|
||||
virtual void RefreshComplete( HServerListRequest hReq, EMatchMakingServerResponse response );
|
||||
|
||||
// Tell the game list what to put in there when there are no games found.
|
||||
virtual void SetEmptyListText();
|
||||
|
||||
private:
|
||||
// vgui message handlers
|
||||
virtual void OnTick();
|
||||
|
||||
// lan timeout checking
|
||||
virtual void CheckRetryRequest();
|
||||
|
||||
// context menu message handlers
|
||||
MESSAGE_FUNC_INT( OnOpenContextMenu, "OpenContextMenu", itemID );
|
||||
|
||||
// number of servers refreshed
|
||||
int m_iServerRefreshCount;
|
||||
|
||||
// true if we're broadcasting for servers
|
||||
bool m_bRequesting;
|
||||
|
||||
// time at which we last broadcasted
|
||||
double m_fRequestTime;
|
||||
|
||||
bool m_bAutoRefresh;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // LANGAMES_H
|
125
serverbrowser/ModList.cpp
Normal file
125
serverbrowser/ModList.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Singleton accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
CModList &ModList()
|
||||
{
|
||||
static CModList s_ModList;
|
||||
return s_ModList;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CModList::CModList()
|
||||
{
|
||||
ParseSteamMods();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns number of mods
|
||||
//-----------------------------------------------------------------------------
|
||||
int CModList::ModCount()
|
||||
{
|
||||
return m_ModList.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CModList::GetModName(int index)
|
||||
{
|
||||
return m_ModList[index].description;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CModList::GetModDir(int index)
|
||||
{
|
||||
return m_ModList[index].gamedir;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
const CGameID &CModList::GetAppID(int index) const
|
||||
{
|
||||
return m_ModList[index].m_GameID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: get the modlist index for this app id
|
||||
//-----------------------------------------------------------------------------
|
||||
int CModList::GetIndex( const CGameID &iAppID ) const
|
||||
{
|
||||
mod_t mod;
|
||||
mod.m_GameID = iAppID;
|
||||
return m_ModList.Find( mod );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns the mod name for the associated gamedir
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CModList::GetModNameForModDir( const CGameID &gameID )
|
||||
{
|
||||
int iApp = GetIndex( gameID );
|
||||
if ( iApp != m_ModList.InvalidIndex() )
|
||||
{
|
||||
return m_ModList[iApp].description;
|
||||
}
|
||||
|
||||
if ( ServerBrowserDialog().GetActiveModName() )
|
||||
{
|
||||
return ServerBrowserDialog().GetActiveGameName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sort the mod list in alphabetical order
|
||||
//-----------------------------------------------------------------------------
|
||||
int CModList::ModNameCompare( const mod_t *pLeft, const mod_t *pRight )
|
||||
{
|
||||
return ( Q_stricmp( pLeft->description, pRight->description ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets list of steam games we can filter for
|
||||
//-----------------------------------------------------------------------------
|
||||
void CModList::ParseSteamMods()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: load settings for an app
|
||||
//-----------------------------------------------------------------------------
|
||||
int CModList::LoadAppConfiguration( uint32 nAppID )
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: add a vgui panel to message when the app list changes
|
||||
//-----------------------------------------------------------------------------
|
||||
void CModList::AddVGUIListener( vgui::VPANEL panel )
|
||||
{
|
||||
m_VGUIListeners.AddToTail( panel );
|
||||
}
|
62
serverbrowser/ModList.h
Normal file
62
serverbrowser/ModList.h
Normal file
@ -0,0 +1,62 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef MODLIST_H
|
||||
#define MODLIST_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles parsing of half-life directory for mod info
|
||||
//-----------------------------------------------------------------------------
|
||||
class CModList
|
||||
{
|
||||
public:
|
||||
CModList();
|
||||
|
||||
int GetIndex( const CGameID &iAppID ) const;
|
||||
void AddVGUIListener( vgui::VPANEL panel );
|
||||
|
||||
// returns number of mods
|
||||
int ModCount();
|
||||
|
||||
// returns the full name of the mod, index valid in range [0, ModCount)
|
||||
const char *GetModName( int index );
|
||||
|
||||
// returns mod directory string
|
||||
const char *GetModDir( int index );
|
||||
|
||||
const CGameID &GetAppID( int index ) const;
|
||||
|
||||
// returns the mod name for the associated gamedir
|
||||
const char *GetModNameForModDir( const CGameID &iAppID );
|
||||
|
||||
private:
|
||||
struct mod_t
|
||||
{
|
||||
char description[64];
|
||||
char gamedir[64];
|
||||
CGameID m_GameID;
|
||||
int m_InternalAppId;
|
||||
bool operator==( const mod_t& rhs ) const { return rhs.m_GameID == m_GameID; }
|
||||
};
|
||||
|
||||
static int ModNameCompare( const mod_t *pLeft, const mod_t *pRight );
|
||||
void ParseInstalledMods();
|
||||
void ParseSteamMods();
|
||||
int LoadAppConfiguration( uint32 nAppID );
|
||||
|
||||
CUtlVector<mod_t> m_ModList;
|
||||
CUtlVector<vgui::VPANEL> m_VGUIListeners;
|
||||
};
|
||||
|
||||
// singleton accessor
|
||||
extern CModList &ModList();
|
||||
|
||||
|
||||
#endif // MODLIST_H
|
317
serverbrowser/QuickListPanel.cpp
Normal file
317
serverbrowser/QuickListPanel.cpp
Normal file
@ -0,0 +1,317 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Invisible panel that forwards up mouse movement
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMouseMessageForwardingPanel : public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CMouseMessageForwardingPanel, vgui::Panel );
|
||||
public:
|
||||
CMouseMessageForwardingPanel( Panel *parent, const char *name );
|
||||
|
||||
virtual void PerformLayout( void );
|
||||
virtual void OnMousePressed( vgui::MouseCode code );
|
||||
virtual void OnMouseDoublePressed( vgui::MouseCode code );
|
||||
virtual void OnMouseWheeled(int delta);
|
||||
};
|
||||
|
||||
CMouseMessageForwardingPanel::CMouseMessageForwardingPanel( Panel *parent, const char *name ) : BaseClass( parent, name )
|
||||
{
|
||||
// don't draw an
|
||||
SetPaintEnabled(false);
|
||||
SetPaintBackgroundEnabled(false);
|
||||
SetPaintBorderEnabled(false);
|
||||
}
|
||||
|
||||
void CMouseMessageForwardingPanel::PerformLayout()
|
||||
{
|
||||
// fill out the whole area
|
||||
int w, t;
|
||||
GetParent()->GetSize(w, t);
|
||||
SetBounds(0, 0, w, t);
|
||||
}
|
||||
|
||||
void CMouseMessageForwardingPanel::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
if ( GetParent() )
|
||||
{
|
||||
GetParent()->OnMousePressed( code );
|
||||
}
|
||||
}
|
||||
|
||||
void CMouseMessageForwardingPanel::OnMouseDoublePressed( vgui::MouseCode code )
|
||||
{
|
||||
if ( GetParent() )
|
||||
{
|
||||
GetParent()->OnMouseDoublePressed( code );
|
||||
}
|
||||
}
|
||||
|
||||
void CMouseMessageForwardingPanel::OnMouseWheeled(int delta)
|
||||
{
|
||||
if ( GetParent() )
|
||||
{
|
||||
GetParent()->OnMouseWheeled( delta );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CQuickListPanel::CQuickListPanel( vgui::Panel* pParent, const char *pElementName ) : BaseClass( pParent, pElementName )
|
||||
{
|
||||
SetParent( pParent );
|
||||
|
||||
m_pListPanelParent = pParent;
|
||||
|
||||
CMouseMessageForwardingPanel *panel = new CMouseMessageForwardingPanel(this, NULL);
|
||||
panel->SetZPos(3);
|
||||
|
||||
m_pLatencyImage = new ImagePanel( this, "latencyimage" );
|
||||
m_pPlayerCountLabel = new Label( this, "playercount", "" );
|
||||
m_pOtherServersLabel = new Label( this, "otherservercount", "" );
|
||||
m_pServerNameLabel = new Label( this, "servername", "" );
|
||||
m_pBGroundPanel = new Panel( this, "background" );
|
||||
m_pMapImage = new ImagePanel( this, "mapimage" );
|
||||
m_pGameTypeLabel = new Label( this, "gametype", "" );
|
||||
m_pMapNameLabel = new Label( this, "mapname", "" );
|
||||
m_pLatencyLabel = new Label( this, "latencytext", "" );
|
||||
m_pReplayImage = new ImagePanel( this, "replayimage" );
|
||||
|
||||
const char *pPathID = "PLATFORM";
|
||||
|
||||
if ( g_pFullFileSystem->FileExists( "servers/QuickListPanel.res", "MOD" ) )
|
||||
{
|
||||
pPathID = "MOD";
|
||||
}
|
||||
|
||||
LoadControlSettings( "servers/QuickListPanel.res", pPathID );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CQuickListPanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
if ( pScheme && m_pBGroundPanel )
|
||||
{
|
||||
m_pBGroundPanel->SetBgColor( pScheme->GetColor("QuickListBGDeselected", Color(255, 255, 255, 0 ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CQuickListPanel::SetRefreshing( void )
|
||||
{
|
||||
if ( m_pServerNameLabel )
|
||||
{
|
||||
m_pServerNameLabel->SetText( g_pVGuiLocalize->Find("#ServerBrowser_QuickListRefreshing") );
|
||||
}
|
||||
|
||||
if ( m_pPlayerCountLabel )
|
||||
{
|
||||
m_pPlayerCountLabel->SetVisible( false );
|
||||
}
|
||||
if ( m_pOtherServersLabel )
|
||||
{
|
||||
m_pOtherServersLabel->SetVisible( false );
|
||||
}
|
||||
|
||||
if ( m_pLatencyImage )
|
||||
{
|
||||
m_pLatencyImage->SetVisible( false );
|
||||
}
|
||||
|
||||
if ( m_pReplayImage )
|
||||
{
|
||||
m_pReplayImage->SetVisible( false );
|
||||
}
|
||||
|
||||
if ( m_pLatencyLabel )
|
||||
{
|
||||
m_pLatencyLabel->SetVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CQuickListPanel::SetMapName( const char *pMapName )
|
||||
{
|
||||
Q_strncpy( m_szMapName, pMapName, sizeof( m_szMapName ) );
|
||||
|
||||
if ( m_pMapNameLabel )
|
||||
{
|
||||
m_pMapNameLabel->SetText( pMapName );
|
||||
m_pMapNameLabel->SizeToContents();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CQuickListPanel::SetGameType( const char *pGameType )
|
||||
{
|
||||
if ( strlen ( pGameType ) == 0 )
|
||||
{
|
||||
m_pGameTypeLabel->SetVisible( false );
|
||||
return;
|
||||
}
|
||||
|
||||
char gametype[ 512 ];
|
||||
Q_snprintf( gametype, sizeof( gametype ), "(%s)", pGameType );
|
||||
|
||||
m_pGameTypeLabel->SetText( gametype );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CQuickListPanel::SetServerInfo ( KeyValues *pKV, int iListID, int iTotalServers )
|
||||
{
|
||||
if ( pKV == NULL )
|
||||
return;
|
||||
|
||||
m_iListID = iListID;
|
||||
|
||||
m_pServerNameLabel->SetText( pKV->GetString( "name", " " ) );
|
||||
|
||||
int iPing = pKV->GetInt( "ping", 0 );
|
||||
|
||||
if ( iPing <= 100 )
|
||||
{
|
||||
m_pLatencyImage->SetImage( "../vgui/icon_con_high.vmt" );
|
||||
}
|
||||
else if ( iPing <= 150 )
|
||||
{
|
||||
m_pLatencyImage->SetImage( "../vgui/icon_con_medium.vmt" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLatencyImage->SetImage( "../vgui/icon_con_low.vmt" );
|
||||
}
|
||||
|
||||
m_pLatencyImage->SetVisible( false );
|
||||
|
||||
if ( GameSupportsReplay() )
|
||||
{
|
||||
if ( pKV->GetInt( "Replay", 0 ) > 0 )
|
||||
{
|
||||
m_pReplayImage->SetVisible( true );
|
||||
}
|
||||
}
|
||||
|
||||
char ping[ 512 ];
|
||||
Q_snprintf( ping, sizeof( ping ), "%d ms", iPing );
|
||||
|
||||
m_pLatencyLabel->SetText( ping );
|
||||
m_pLatencyLabel->SetVisible( true );
|
||||
|
||||
wchar_t players[ 512 ];
|
||||
wchar_t playercount[16];
|
||||
wchar_t *pwszPlayers = g_pVGuiLocalize->Find("#ServerBrowser_Players");
|
||||
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pKV->GetString( "players", " " ), playercount, sizeof( playercount ) );
|
||||
|
||||
_snwprintf( players, ARRAYSIZE( players ), L"%ls %ls", playercount, pwszPlayers );
|
||||
|
||||
m_pPlayerCountLabel->SetText( players );
|
||||
m_pPlayerCountLabel->SetVisible( true );
|
||||
|
||||
|
||||
// Now setup the other server count
|
||||
if ( iTotalServers == 2 )
|
||||
{
|
||||
m_pOtherServersLabel->SetText( g_pVGuiLocalize->Find("#ServerBrowser_QuickListOtherServer") );
|
||||
m_pOtherServersLabel->SetVisible( true );
|
||||
}
|
||||
else if ( iTotalServers > 2 )
|
||||
{
|
||||
wchar_t *pwszServers = g_pVGuiLocalize->Find("#ServerBrowser_QuickListOtherServers");
|
||||
_snwprintf( playercount, Q_ARRAYSIZE(playercount), L"%d", (iTotalServers-1) );
|
||||
g_pVGuiLocalize->ConstructString( players, sizeof( players ), pwszServers, 1, playercount );
|
||||
m_pOtherServersLabel->SetText( players );
|
||||
m_pOtherServersLabel->SetVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pOtherServersLabel->SetVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CQuickListPanel::SetImage( const char *pMapName )
|
||||
{
|
||||
char path[ 512 ];
|
||||
Q_snprintf( path, sizeof( path ), "materials/vgui/maps/menu_thumb_%s.vmt", pMapName );
|
||||
|
||||
char map[ 512 ];
|
||||
Q_snprintf( map, sizeof( map ), "maps/%s.bsp", pMapName );
|
||||
|
||||
if ( g_pFullFileSystem->FileExists( map, "MOD" ) == false )
|
||||
{
|
||||
pMapName = "default_download";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( g_pFullFileSystem->FileExists( path, "MOD" ) == false )
|
||||
{
|
||||
pMapName = "default";
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_pMapImage )
|
||||
{
|
||||
char imagename[ 512 ];
|
||||
Q_snprintf( imagename, sizeof( imagename ), "..\\vgui\\maps\\menu_thumb_%s", pMapName );
|
||||
|
||||
m_pMapImage->SetImage ( imagename );
|
||||
m_pMapImage->SetMouseInputEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
void CQuickListPanel::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
if ( m_pListPanelParent )
|
||||
{
|
||||
vgui::PanelListPanel *pParent = dynamic_cast < vgui::PanelListPanel *> ( m_pListPanelParent );
|
||||
|
||||
if ( pParent )
|
||||
{
|
||||
pParent->SetSelectedPanel( this );
|
||||
m_pListPanelParent->CallParentFunction( new KeyValues("ItemSelected", "itemID", -1 ) );
|
||||
}
|
||||
|
||||
if ( code == MOUSE_RIGHT )
|
||||
{
|
||||
m_pListPanelParent->CallParentFunction( new KeyValues("OpenContextMenu", "itemID", -1 ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void CQuickListPanel::OnMouseDoublePressed( vgui::MouseCode code )
|
||||
{
|
||||
if ( code == MOUSE_RIGHT )
|
||||
return;
|
||||
|
||||
// call the panel
|
||||
OnMousePressed( code );
|
||||
|
||||
m_pListPanelParent->CallParentFunction( new KeyValues("ConnectToServer", "code", code) );
|
||||
}
|
83
serverbrowser/QuickListPanel.h
Normal file
83
serverbrowser/QuickListPanel.h
Normal file
@ -0,0 +1,83 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef QUICKLISTPANEL
|
||||
#define QUICKLISTPANEL
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spectator games list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CQuickListPanel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CQuickListPanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CQuickListPanel( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
void SetMapName( const char *pMapName );
|
||||
void SetImage( const char *pMapName );
|
||||
void SetGameType( const char *pGameType );
|
||||
const char *GetMapName( void ) { return m_szMapName; }
|
||||
void SetRefreshing( void );
|
||||
|
||||
virtual void OnMousePressed( vgui::MouseCode code );
|
||||
virtual void OnMouseDoublePressed( vgui::MouseCode code );
|
||||
void SetServerInfo ( KeyValues *pKV, int iListID, int iTotalServers );
|
||||
int GetListID( void ) { return m_iListID; }
|
||||
|
||||
|
||||
MESSAGE_FUNC_INT( OnPanelSelected, "PanelSelected", state )
|
||||
{
|
||||
if ( state )
|
||||
{
|
||||
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
|
||||
|
||||
if ( pScheme && m_pBGroundPanel )
|
||||
{
|
||||
m_pBGroundPanel->SetBgColor( pScheme->GetColor("QuickListBGSelected", Color(255, 255, 255, 0 ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
|
||||
|
||||
if ( pScheme && m_pBGroundPanel )
|
||||
{
|
||||
m_pBGroundPanel->SetBgColor( pScheme->GetColor("QuickListBGDeselected", Color(255, 255, 255, 0 ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
PostMessage( GetParent()->GetVParent(), new KeyValues("PanelSelected") );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char m_szMapName[128];
|
||||
|
||||
vgui::ImagePanel *m_pLatencyImage;
|
||||
vgui::Label *m_pLatencyLabel;
|
||||
vgui::Label *m_pPlayerCountLabel;
|
||||
vgui::Label *m_pOtherServersLabel;
|
||||
vgui::Label *m_pServerNameLabel;
|
||||
vgui::Panel *m_pBGroundPanel;
|
||||
vgui::ImagePanel *m_pMapImage;
|
||||
|
||||
vgui::Panel *m_pListPanelParent;
|
||||
vgui::Label *m_pGameTypeLabel;
|
||||
vgui::Label *m_pMapNameLabel;
|
||||
|
||||
vgui::ImagePanel *m_pReplayImage;
|
||||
|
||||
int m_iListID;
|
||||
};
|
||||
|
||||
|
||||
#endif // QUICKLISTPANEL
|
489
serverbrowser/ServerBrowser.cpp
Normal file
489
serverbrowser/ServerBrowser.cpp
Normal file
@ -0,0 +1,489 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
// expose the server browser interfaces
|
||||
CServerBrowser g_ServerBrowserSingleton;
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerBrowser, IServerBrowser, SERVERBROWSER_INTERFACE_VERSION, g_ServerBrowserSingleton);
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerBrowser, IVGuiModule, "VGuiModuleServerBrowser001", g_ServerBrowserSingleton); // the interface loaded by PlatformMenu.vdf
|
||||
|
||||
// singleton accessor
|
||||
CServerBrowser &ServerBrowser()
|
||||
{
|
||||
return g_ServerBrowserSingleton;
|
||||
}
|
||||
|
||||
IRunGameEngine *g_pRunGameEngine = NULL;
|
||||
|
||||
static CSteamAPIContext g_SteamAPIContext;
|
||||
CSteamAPIContext *steamapicontext = &g_SteamAPIContext;
|
||||
|
||||
IEngineReplay *g_pEngineReplay = NULL;
|
||||
|
||||
ConVar sb_firstopentime( "sb_firstopentime", "0", FCVAR_DEVELOPMENTONLY, "Indicates the time the server browser was first opened." );
|
||||
ConVar sb_numtimesopened( "sb_numtimesopened", "0", FCVAR_DEVELOPMENTONLY, "Indicates the number of times the server browser was opened this session." );
|
||||
|
||||
// the original author of this code felt strdup was not acceptible.
|
||||
inline char *CloneString( const char *str )
|
||||
{
|
||||
char *cloneStr = new char [ strlen(str)+1 ];
|
||||
strcpy( cloneStr, str );
|
||||
return cloneStr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowser::CServerBrowser()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowser::~CServerBrowser()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::CreateDialog()
|
||||
{
|
||||
if (!m_hInternetDlg.Get())
|
||||
{
|
||||
m_hInternetDlg = new CServerBrowserDialog(NULL); // SetParent() call below fills this in
|
||||
m_hInternetDlg->Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: links to vgui and engine interfaces
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::Initialize(CreateInterfaceFn *factorylist, int factoryCount)
|
||||
{
|
||||
ConnectTier1Libraries( factorylist, factoryCount );
|
||||
ConVar_Register();
|
||||
ConnectTier2Libraries( factorylist, factoryCount );
|
||||
ConnectTier3Libraries( factorylist, factoryCount );
|
||||
g_pRunGameEngine = NULL;
|
||||
|
||||
for ( int i = 0; i < factoryCount; ++i )
|
||||
{
|
||||
if ( !g_pEngineReplay )
|
||||
{
|
||||
g_pEngineReplay = ( IEngineReplay * )factorylist[ i ]( ENGINE_REPLAY_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
SteamAPI_InitSafe();
|
||||
SteamAPI_SetTryCatchCallbacks( false ); // We don't use exceptions, so tell steam not to use try/catch in callback handlers
|
||||
steamapicontext->Init();
|
||||
|
||||
for (int i = 0; i < factoryCount; i++)
|
||||
{
|
||||
if (!g_pRunGameEngine)
|
||||
{
|
||||
g_pRunGameEngine = (IRunGameEngine *)(factorylist[i])(RUNGAMEENGINE_INTERFACE_VERSION, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// load the vgui interfaces
|
||||
#if defined( STEAM ) || defined( HL1 )
|
||||
if ( !vgui::VGuiControls_Init("ServerBrowser", factorylist, factoryCount) )
|
||||
#else
|
||||
if ( !vgui::VGui_InitInterfacesList("ServerBrowser", factorylist, factoryCount) )
|
||||
#endif
|
||||
return false;
|
||||
|
||||
// load localization file
|
||||
g_pVGuiLocalize->AddFile( "servers/serverbrowser_%language%.txt" );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: links to other modules interfaces (tracker)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::PostInitialize(CreateInterfaceFn *modules, int factoryCount)
|
||||
{
|
||||
// find the interfaces we need
|
||||
for (int i = 0; i < factoryCount; i++)
|
||||
{
|
||||
if (!g_pRunGameEngine)
|
||||
{
|
||||
g_pRunGameEngine = (IRunGameEngine *)(modules[i])(RUNGAMEENGINE_INTERFACE_VERSION, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
CreateDialog();
|
||||
m_hInternetDlg->SetVisible(false);
|
||||
|
||||
return g_pRunGameEngine;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: true if the user can't play a game due to VAC banning
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::IsVACBannedFromGame( int nAppID )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Marks that the tool/game loading us intends to feed us workshop information
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::SetWorkshopEnabled( bool bManaged )
|
||||
{
|
||||
m_bWorkshopEnabled = bManaged;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Add a mapname to our known user-subscribed workshop maps list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::AddWorkshopSubscribedMap( const char *pszMapName )
|
||||
{
|
||||
CUtlString strMap( pszMapName );
|
||||
if ( !IsWorkshopSubscribedMap( strMap ) )
|
||||
{
|
||||
m_vecWorkshopSubscribedMaps.AddToTail( strMap );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: remove a mapname to our known user-subscribed workshop maps list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::RemoveWorkshopSubscribedMap( const char *pszMapName )
|
||||
{
|
||||
m_vecWorkshopSubscribedMaps.FindAndFastRemove( CUtlString( pszMapName ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Well, is it?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::IsWorkshopEnabled()
|
||||
{
|
||||
return m_bWorkshopEnabled;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check if this map is in our subscribed list
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::IsWorkshopSubscribedMap( const char *pszMapName )
|
||||
{
|
||||
return m_vecWorkshopSubscribedMaps.HasElement( CUtlString( pszMapName ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::IsValid()
|
||||
{
|
||||
return ( g_pRunGameEngine );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::Activate()
|
||||
{
|
||||
static bool firstTimeOpening = true;
|
||||
if ( firstTimeOpening )
|
||||
{
|
||||
m_hInternetDlg->LoadUserData(); // reload the user data the first time the dialog is made visible, helps with the lag between module load and
|
||||
// steamui getting Deactivate() call
|
||||
firstTimeOpening = false;
|
||||
}
|
||||
|
||||
int numTimesOpened = sb_numtimesopened.GetInt() + 1;
|
||||
sb_numtimesopened.SetValue( numTimesOpened );
|
||||
if ( numTimesOpened == 1 )
|
||||
{
|
||||
time_t aclock;
|
||||
time( &aclock );
|
||||
sb_firstopentime.SetValue( (int) aclock );
|
||||
}
|
||||
|
||||
Open();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the server browser gets used in the game
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::Deactivate()
|
||||
{
|
||||
if (m_hInternetDlg.Get())
|
||||
{
|
||||
m_hInternetDlg->SaveUserData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called when the server browser is no longer being used in the game
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::Reactivate()
|
||||
{
|
||||
if (m_hInternetDlg.Get())
|
||||
{
|
||||
m_hInternetDlg->LoadUserData();
|
||||
if (m_hInternetDlg->IsVisible())
|
||||
{
|
||||
m_hInternetDlg->RefreshCurrentPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::Open()
|
||||
{
|
||||
m_hInternetDlg->Open();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns direct handle to main server browser dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::VPANEL CServerBrowser::GetPanel()
|
||||
{
|
||||
return m_hInternetDlg.Get() ? m_hInternetDlg->GetVPanel() : NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets the parent panel of the main module panel
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::SetParent(vgui::VPANEL parent)
|
||||
{
|
||||
if (m_hInternetDlg.Get())
|
||||
{
|
||||
m_hInternetDlg->SetParent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Closes down the server browser for good
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::Shutdown()
|
||||
{
|
||||
if (m_hInternetDlg.Get())
|
||||
{
|
||||
m_hInternetDlg->Close();
|
||||
m_hInternetDlg->MarkForDeletion();
|
||||
}
|
||||
|
||||
#if defined( STEAM )
|
||||
vgui::VGuiControls_Shutdown();
|
||||
#endif
|
||||
|
||||
DisconnectTier3Libraries();
|
||||
DisconnectTier2Libraries();
|
||||
ConVar_Unregister();
|
||||
DisconnectTier1Libraries();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens a game info dialog to watch the specified server; associated with the friend 'userName'
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::OpenGameInfoDialog( uint64 ulSteamIDFriend, const char *pszConnectCode )
|
||||
{
|
||||
#if !defined( _X360 ) // X360TBD: SteamFriends()
|
||||
if ( m_hInternetDlg.Get() )
|
||||
{
|
||||
// activate an already-existing dialog
|
||||
CDialogGameInfo *pDialogGameInfo = m_hInternetDlg->GetDialogGameInfoForFriend( ulSteamIDFriend );
|
||||
if ( pDialogGameInfo )
|
||||
{
|
||||
pDialogGameInfo->Activate();
|
||||
return true;
|
||||
}
|
||||
|
||||
// none yet, create a new dialog
|
||||
FriendGameInfo_t friendGameInfo;
|
||||
if ( steamapicontext->SteamFriends()->GetFriendGamePlayed( ulSteamIDFriend, &friendGameInfo ) )
|
||||
{
|
||||
uint16 usConnPort = friendGameInfo.m_usGamePort;
|
||||
if ( friendGameInfo.m_usQueryPort < QUERY_PORT_ERROR )
|
||||
usConnPort = friendGameInfo.m_usQueryPort;
|
||||
CDialogGameInfo *pDialogGameInfo = m_hInternetDlg->OpenGameInfoDialog( friendGameInfo.m_unGameIP, friendGameInfo.m_usGamePort, usConnPort, pszConnectCode );
|
||||
pDialogGameInfo->SetFriend( ulSteamIDFriend );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: joins a specified game - game info dialog will only be opened if the server is fully or passworded
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::JoinGame( uint64 ulSteamIDFriend, const char *pszConnectCode )
|
||||
{
|
||||
if ( OpenGameInfoDialog( ulSteamIDFriend, pszConnectCode ) )
|
||||
{
|
||||
CDialogGameInfo *pDialogGameInfo = m_hInternetDlg->GetDialogGameInfoForFriend( ulSteamIDFriend );
|
||||
pDialogGameInfo->Connect();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: joins a game by IP/Port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowser::JoinGame( uint32 unGameIP, uint16 usGamePort, const char *pszConnectCode )
|
||||
{
|
||||
m_hInternetDlg->JoinGame( unGameIP, usGamePort, pszConnectCode );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: forces the game info dialog closed
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::CloseGameInfoDialog( uint64 ulSteamIDFriend )
|
||||
{
|
||||
CDialogGameInfo *pDialogGameInfo = m_hInternetDlg->GetDialogGameInfoForFriend( ulSteamIDFriend );
|
||||
if ( pDialogGameInfo )
|
||||
{
|
||||
pDialogGameInfo->Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: closes all the game info dialogs
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowser::CloseAllGameInfoDialogs()
|
||||
{
|
||||
if ( m_hInternetDlg.Get() )
|
||||
{
|
||||
m_hInternetDlg->CloseAllGameInfoDialogs();
|
||||
}
|
||||
}
|
||||
|
||||
CUtlVector< gametypes_t > g_GameTypes;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void LoadGameTypes( void )
|
||||
{
|
||||
if ( g_GameTypes.Count() > 0 )
|
||||
return;
|
||||
|
||||
#define GAMETYPES_FILE "servers/ServerBrowserGameTypes.txt"
|
||||
|
||||
KeyValues * kv = new KeyValues( GAMETYPES_FILE );
|
||||
|
||||
if ( !kv->LoadFromFile( g_pFullFileSystem, GAMETYPES_FILE, "MOD" ) )
|
||||
{
|
||||
kv->deleteThis();
|
||||
return;
|
||||
}
|
||||
|
||||
g_GameTypes.RemoveAll();
|
||||
|
||||
for ( KeyValues *pData = kv->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
|
||||
{
|
||||
gametypes_t gametype;
|
||||
|
||||
gametype.pPrefix = CloneString( pData->GetString( "prefix", "" ) );
|
||||
gametype.pGametypeName = CloneString( pData->GetString( "name", "" ) );
|
||||
g_GameTypes.AddToTail( gametype );
|
||||
}
|
||||
|
||||
|
||||
kv->deleteThis();
|
||||
}
|
||||
|
||||
const char *GetGameTypeName( const char *pMapName )
|
||||
{
|
||||
LoadGameTypes();
|
||||
for ( int i = 0; i < g_GameTypes.Count(); i++ )
|
||||
{
|
||||
int iLength = strlen( g_GameTypes[i].pPrefix );
|
||||
|
||||
if ( !Q_strncmp( pMapName, g_GameTypes[i].pPrefix, iLength ) )
|
||||
{
|
||||
return g_GameTypes[i].pGametypeName;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose of comments like these: none
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CServerBrowser::GetMapFriendlyNameAndGameType( const char *pszMapName, char *szFriendlyMapName, int cchFriendlyName )
|
||||
{
|
||||
// Make sure game types are loaded
|
||||
LoadGameTypes();
|
||||
|
||||
// Scan list
|
||||
const char *pszFriendlyGameTypeName = "";
|
||||
for ( int i = 0; i < g_GameTypes.Count(); i++ )
|
||||
{
|
||||
int iLength = strlen( g_GameTypes[i].pPrefix );
|
||||
|
||||
if ( !Q_strnicmp( pszMapName, g_GameTypes[i].pPrefix, iLength ) )
|
||||
{
|
||||
pszMapName += iLength;
|
||||
pszFriendlyGameTypeName = g_GameTypes[i].pGametypeName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// See how many characters from the name to copy.
|
||||
// Start by assuming we'll copy the whole thing.
|
||||
// (After any prefix we just skipped)
|
||||
int l = V_strlen( pszMapName );
|
||||
const char *pszFinal = Q_stristr( pszMapName, "_final" );
|
||||
if ( pszFinal )
|
||||
{
|
||||
// truncate the _final (or _final1) part of the filename if it's at the end of the name
|
||||
const char *pszNextChar = pszFinal + Q_strlen( "_final" );
|
||||
if ( ( *pszNextChar == '\0' ) ||
|
||||
( ( *pszNextChar == '1' ) && ( *(pszNextChar+1) == '\0' ) ) )
|
||||
{
|
||||
l = pszFinal - pszMapName;
|
||||
}
|
||||
}
|
||||
|
||||
// Safety check against buffer size
|
||||
if ( l >= cchFriendlyName )
|
||||
{
|
||||
Assert( !"Map name too long for buffer!" );
|
||||
l = cchFriendlyName-1;
|
||||
}
|
||||
|
||||
// Copy friendly portion of name only
|
||||
V_memcpy( szFriendlyMapName, pszMapName, l );
|
||||
|
||||
// It's like the Alamo. We never forget.
|
||||
szFriendlyMapName[l] = '\0';
|
||||
|
||||
// Result should be the friendly game type name
|
||||
return pszFriendlyGameTypeName;
|
||||
}
|
||||
|
82
serverbrowser/ServerBrowser.h
Normal file
82
serverbrowser/ServerBrowser.h
Normal file
@ -0,0 +1,82 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVERBROWSER_H
|
||||
#define SERVERBROWSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class CServerBrowserDialog;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handles the UI and pinging of a half-life game server list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CServerBrowser : public IServerBrowser, public IVGuiModule
|
||||
{
|
||||
public:
|
||||
CServerBrowser();
|
||||
~CServerBrowser();
|
||||
|
||||
// IVGui module implementation
|
||||
virtual bool Initialize(CreateInterfaceFn *factorylist, int numFactories);
|
||||
virtual bool PostInitialize(CreateInterfaceFn *modules, int factoryCount);
|
||||
virtual vgui::VPANEL GetPanel();
|
||||
virtual bool Activate();
|
||||
virtual bool IsValid();
|
||||
virtual void Shutdown();
|
||||
virtual void Deactivate();
|
||||
virtual void Reactivate();
|
||||
virtual void SetParent(vgui::VPANEL parent);
|
||||
|
||||
// IServerBrowser implementation
|
||||
// joins a specified game - game info dialog will only be opened if the server is fully or passworded
|
||||
virtual bool JoinGame( uint32 unGameIP, uint16 usGamePort, const char *pszConnectCode );
|
||||
virtual bool JoinGame( uint64 ulSteamIDFriend, const char *pszConnectCode );
|
||||
|
||||
// opens a game info dialog to watch the specified server; associated with the friend 'userName'
|
||||
virtual bool OpenGameInfoDialog( uint64 ulSteamIDFriend, const char *pszConnectCode );
|
||||
|
||||
// forces the game info dialog closed
|
||||
virtual void CloseGameInfoDialog( uint64 ulSteamIDFriend );
|
||||
|
||||
// closes all the game info dialogs
|
||||
virtual void CloseAllGameInfoDialogs();
|
||||
|
||||
virtual const char *GetMapFriendlyNameAndGameType( const char *pszMapName, char *szFriendlyMapName, int cchFriendlyName ) OVERRIDE;
|
||||
|
||||
// methods
|
||||
virtual void CreateDialog();
|
||||
virtual void Open();
|
||||
|
||||
// true if the user can't play a game
|
||||
bool IsVACBannedFromGame( int nAppID );
|
||||
|
||||
// Enable filtering of workshop maps, requires the game/tool loading us to feed subscription data. This is a
|
||||
// slightly ugly workaround to TF2 not yet having native workshop UI in quickplay, once that is in place this should
|
||||
// either be stripped back out or expanded to be directly aware of the steam workshop without being managed.
|
||||
virtual void SetWorkshopEnabled( bool bManaged ) OVERRIDE;
|
||||
virtual void AddWorkshopSubscribedMap( const char *pszMapName ) OVERRIDE;
|
||||
virtual void RemoveWorkshopSubscribedMap( const char *pszMapName ) OVERRIDE;
|
||||
|
||||
bool IsWorkshopEnabled();
|
||||
bool IsWorkshopSubscribedMap( const char *pszMapName );
|
||||
private:
|
||||
vgui::DHANDLE<CServerBrowserDialog> m_hInternetDlg;
|
||||
|
||||
bool m_bWorkshopEnabled;
|
||||
CUtlVector< CUtlString > m_vecWorkshopSubscribedMaps;
|
||||
};
|
||||
|
||||
// singleton accessor
|
||||
CServerBrowser &ServerBrowser();
|
||||
|
||||
class CSteamAPIContext;
|
||||
extern CSteamAPIContext *steamapicontext;
|
||||
|
||||
|
||||
#endif // SERVERBROWSER_H
|
106
serverbrowser/ServerBrowser.vpc
Normal file
106
serverbrowser/ServerBrowser.vpc
Normal file
@ -0,0 +1,106 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// SERVERBROWSER.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR ".."
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;VERSION_SAFE_STEAM_API_INTERFACES;SERVERBROWSER_EXPORTS;GAME_SRC;_USE_32BIT_TIME_T"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$AdditionalDependencies "$BASE Advapi32.lib wsock32.lib Ws2_32.lib User32.lib" [$WIN32]
|
||||
$AdditionalDependencies "$BASE Xonline.lib" [$X360]
|
||||
$SystemLibraries "iconv" [$OSXALL]
|
||||
}
|
||||
}
|
||||
|
||||
$Project "ServerBrowser"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "BaseGamesPage.cpp"
|
||||
$File "BlacklistedServers.cpp"
|
||||
$File "CustomGames.cpp"
|
||||
$File "DialogAddServer.cpp"
|
||||
$File "DialogGameInfo.cpp"
|
||||
$File "DialogServerPassword.cpp"
|
||||
$File "FavoriteGames.cpp"
|
||||
$File "FriendsGames.cpp"
|
||||
$File "HistoryGames.cpp"
|
||||
$File "InternetGames.cpp"
|
||||
$File "LanGames.cpp"
|
||||
$File "ModList.cpp"
|
||||
$File "ServerBrowser.cpp"
|
||||
$File "ServerBrowserDialog.cpp"
|
||||
$File "ServerContextMenu.cpp"
|
||||
$File "ServerListCompare.cpp"
|
||||
$File "SpectateGames.cpp"
|
||||
$File "VACBannedConnRefusedDialog.cpp"
|
||||
$File "VACBannedConnRefusedDialog.h"
|
||||
|
||||
$File "QuickListPanel.cpp"
|
||||
|
||||
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
|
||||
{
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$File "$SRCDIR\common\ServerBrowser\blacklisted_server_manager.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "BaseGamesPage.h"
|
||||
$File "BlacklistedServers.h"
|
||||
$File "CustomGames.h"
|
||||
$File "DialogAddServer.h"
|
||||
$File "DialogGameInfo.h"
|
||||
$File "DialogServerPassword.h"
|
||||
$File "FavoriteGames.h"
|
||||
$File "FriendsGames.h"
|
||||
$File "HistoryGames.h"
|
||||
$File "InternetGames.h"
|
||||
$File "LanGames.h"
|
||||
$File "ModList.h"
|
||||
$File "ServerBrowser.h"
|
||||
$File "ServerBrowserDialog.h"
|
||||
$File "ServerContextMenu.h"
|
||||
$File "ServerListCompare.h"
|
||||
$File "SpectateGames.h"
|
||||
$File "QuickListPanel.h"
|
||||
|
||||
$File "$SRCDIR\common\ServerBrowser\blacklisted_server_manager.h"
|
||||
}
|
||||
|
||||
$Folder "Resource Files"
|
||||
{
|
||||
}
|
||||
$Folder "Exposed interfaces"
|
||||
{
|
||||
$File "$SRCDIR\common\ServerBrowser\IServerBrowser.h"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$ImpLib steam_api
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
$Lib vgui_controls
|
||||
$Lib mathlib
|
||||
}
|
||||
}
|
816
serverbrowser/ServerBrowserDialog.cpp
Normal file
816
serverbrowser/ServerBrowserDialog.cpp
Normal file
@ -0,0 +1,816 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_win32stubs.h"
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 ) && !defined( _X360 )
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
ConVar sb_quick_list_bit_field( "sb_quick_list_bit_field", "-1" );
|
||||
|
||||
static CServerBrowserDialog *s_InternetDlg = NULL;
|
||||
|
||||
CServerBrowserDialog &ServerBrowserDialog()
|
||||
{
|
||||
return *CServerBrowserDialog::GetInstance();
|
||||
}
|
||||
|
||||
|
||||
// Returns a list of the ports that we hit when looking for
|
||||
void GetMostCommonQueryPorts( CUtlVector<uint16> &ports )
|
||||
{
|
||||
for ( int i=0; i <= 5; i++ )
|
||||
{
|
||||
ports.AddToTail( 27015 + i );
|
||||
ports.AddToTail( 26900 + i );
|
||||
}
|
||||
|
||||
ports.AddToTail(4242); //RDKF
|
||||
ports.AddToTail(27215); //Lost Planet
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowserDialog::CServerBrowserDialog(vgui::Panel *parent) : Frame(parent, "CServerBrowserDialog")
|
||||
{
|
||||
s_InternetDlg = this;
|
||||
|
||||
m_szGameName[0] = 0;
|
||||
m_szModDir[0] = 0;
|
||||
m_pSavedData = NULL;
|
||||
m_pFilterData = NULL;
|
||||
m_pFavorites = NULL;
|
||||
m_pBlacklist = NULL;
|
||||
m_pHistory = NULL;
|
||||
|
||||
// Do this before LoadUserData() so it loads the blacklist file properly
|
||||
m_pBlacklist = new CBlacklistedServers(this);
|
||||
|
||||
LoadUserData();
|
||||
|
||||
m_pInternetGames = new CCustomGames(this);
|
||||
m_pFavorites = new CFavoriteGames(this);
|
||||
m_pHistory = new CHistoryGames(this);
|
||||
m_pSpectateGames = new CSpectateGames(this);
|
||||
m_pLanGames = new CLanGames(this);
|
||||
m_pFriendsGames = new CFriendsGames(this);
|
||||
|
||||
SetMinimumSize( 640, 384 );
|
||||
SetSize( 640, 384 );
|
||||
|
||||
m_pGameList = m_pInternetGames;
|
||||
|
||||
m_pContextMenu = new CServerContextMenu(this);;
|
||||
|
||||
// property sheet
|
||||
m_pTabPanel = new PropertySheet(this, "GameTabs");
|
||||
m_pTabPanel->SetTabWidth(72);
|
||||
m_pTabPanel->AddPage(m_pInternetGames, "#ServerBrowser_InternetTab");
|
||||
m_pTabPanel->AddPage(m_pFavorites, "#ServerBrowser_FavoritesTab");
|
||||
m_pTabPanel->AddPage(m_pHistory, "#ServerBrowser_HistoryTab");
|
||||
m_pTabPanel->AddPage(m_pSpectateGames, "#ServerBrowser_SpectateTab");
|
||||
m_pTabPanel->AddPage(m_pLanGames, "#ServerBrowser_LanTab");
|
||||
m_pTabPanel->AddPage(m_pFriendsGames, "#ServerBrowser_FriendsTab");
|
||||
if ( m_pBlacklist )
|
||||
{
|
||||
m_pTabPanel->AddPage(m_pBlacklist, "#ServerBrowser_BlacklistTab");
|
||||
}
|
||||
m_pTabPanel->AddActionSignalTarget(this);
|
||||
|
||||
m_pStatusLabel = new Label(this, "StatusLabel", "");
|
||||
|
||||
LoadControlSettingsAndUserConfig("Servers/DialogServerBrowser.res");
|
||||
|
||||
m_pStatusLabel->SetText("");
|
||||
|
||||
// load current tab
|
||||
const char *gameList = m_pSavedData->GetString("GameList");
|
||||
|
||||
if (!Q_stricmp(gameList, "spectate"))
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pSpectateGames);
|
||||
}
|
||||
else if (!Q_stricmp(gameList, "favorites"))
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pFavorites);
|
||||
}
|
||||
else if (!Q_stricmp(gameList, "history"))
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pHistory);
|
||||
}
|
||||
else if (!Q_stricmp(gameList, "lan"))
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pLanGames);
|
||||
}
|
||||
else if (!Q_stricmp(gameList, "friends"))
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pFriendsGames);
|
||||
}
|
||||
else if (!Q_stricmp(gameList, "blacklist"))
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pBlacklist);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTabPanel->SetActivePage(m_pInternetGames);
|
||||
}
|
||||
|
||||
ivgui()->AddTickSignal( GetVPanel() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowserDialog::~CServerBrowserDialog()
|
||||
{
|
||||
delete m_pContextMenu;
|
||||
|
||||
SaveUserData();
|
||||
|
||||
if (m_pSavedData)
|
||||
{
|
||||
m_pSavedData->deleteThis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called once to set up
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::Initialize()
|
||||
{
|
||||
SetTitle("#ServerBrowser_Servers", true);
|
||||
SetVisible(false);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a server in the list
|
||||
//-----------------------------------------------------------------------------
|
||||
gameserveritem_t *CServerBrowserDialog::GetServer( unsigned int serverID )
|
||||
{
|
||||
if (m_pGameList)
|
||||
return m_pGameList->GetServer( serverID );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activates and gives the tab focus
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::Open()
|
||||
{
|
||||
BaseClass::Activate();
|
||||
m_pTabPanel->RequestFocus();
|
||||
|
||||
MoveToCenterOfScreen();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called every frame, updates animations for this module
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
vgui::GetAnimationController()->UpdateAnimations( system()->GetFrameTime() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Loads filter settings from disk
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::LoadUserData()
|
||||
{
|
||||
// free any old filters
|
||||
if (m_pSavedData)
|
||||
{
|
||||
m_pSavedData->deleteThis();
|
||||
}
|
||||
|
||||
m_pSavedData = new KeyValues("Filters");
|
||||
if (!m_pSavedData->LoadFromFile( g_pFullFileSystem, "ServerBrowser.vdf", "CONFIG"))
|
||||
{
|
||||
// doesn't matter if the file is not found, defaults will work successfully and file will be created on exit
|
||||
}
|
||||
|
||||
KeyValues *filters = m_pSavedData->FindKey( "Filters", false );
|
||||
if ( filters )
|
||||
{
|
||||
m_pFilterData = filters->MakeCopy();
|
||||
m_pSavedData->RemoveSubKey( filters );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFilterData = new KeyValues( "Filters" );
|
||||
}
|
||||
|
||||
|
||||
// reload all the page settings if necessary
|
||||
if (m_pHistory)
|
||||
{
|
||||
// history
|
||||
m_pHistory->LoadHistoryList();
|
||||
if ( IsVisible() && m_pHistory->IsVisible() )
|
||||
m_pHistory->StartRefresh();
|
||||
}
|
||||
|
||||
if (m_pFavorites)
|
||||
{
|
||||
// favorites
|
||||
m_pFavorites->LoadFavoritesList();
|
||||
|
||||
// filters
|
||||
ReloadFilterSettings();
|
||||
|
||||
if ( IsVisible() && m_pFavorites->IsVisible() )
|
||||
m_pFavorites->StartRefresh();
|
||||
}
|
||||
|
||||
if ( m_pBlacklist )
|
||||
{
|
||||
m_pBlacklist->LoadBlacklistedList();
|
||||
}
|
||||
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::SaveUserData()
|
||||
{
|
||||
m_pSavedData->Clear();
|
||||
m_pSavedData->LoadFromFile( g_pFullFileSystem, "ServerBrowser.vdf", "CONFIG");
|
||||
|
||||
// set the current tab
|
||||
if (m_pGameList == m_pSpectateGames)
|
||||
{
|
||||
m_pSavedData->SetString("GameList", "spectate");
|
||||
}
|
||||
else if (m_pGameList == m_pFavorites)
|
||||
{
|
||||
m_pSavedData->SetString("GameList", "favorites");
|
||||
}
|
||||
else if (m_pGameList == m_pLanGames)
|
||||
{
|
||||
m_pSavedData->SetString("GameList", "lan");
|
||||
}
|
||||
else if (m_pGameList == m_pFriendsGames)
|
||||
{
|
||||
m_pSavedData->SetString("GameList", "friends");
|
||||
}
|
||||
else if (m_pGameList == m_pHistory)
|
||||
{
|
||||
m_pSavedData->SetString("GameList", "history");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSavedData->SetString("GameList", "internet");
|
||||
}
|
||||
|
||||
m_pSavedData->RemoveSubKey( m_pSavedData->FindKey( "Filters" ) ); // remove the saved subkey and add our subkey
|
||||
m_pSavedData->AddSubKey( m_pFilterData->MakeCopy() );
|
||||
m_pSavedData->SaveToFile( g_pFullFileSystem, "ServerBrowser.vdf", "CONFIG");
|
||||
|
||||
if ( m_pBlacklist )
|
||||
{
|
||||
m_pBlacklist->SaveBlacklistedList();
|
||||
}
|
||||
|
||||
// save per-page config
|
||||
SaveUserConfig();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: refreshes the page currently visible
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::RefreshCurrentPage()
|
||||
{
|
||||
if (m_pGameList)
|
||||
{
|
||||
m_pGameList->StartRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::BlacklistsChanged()
|
||||
{
|
||||
m_pInternetGames->ApplyGameFilters();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Updates status test at bottom of window
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::UpdateStatusText(const char *fmt, ...)
|
||||
{
|
||||
if ( !m_pStatusLabel )
|
||||
return;
|
||||
|
||||
if ( fmt && strlen(fmt) > 0 )
|
||||
{
|
||||
char str[ 1024 ];
|
||||
va_list argptr;
|
||||
va_start( argptr, fmt );
|
||||
_vsnprintf( str, sizeof(str), fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
m_pStatusLabel->SetText( str );
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear
|
||||
m_pStatusLabel->SetText( "" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Updates status test at bottom of window
|
||||
// Input : wchar_t* (unicode string) -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::UpdateStatusText(wchar_t *unicode)
|
||||
{
|
||||
if ( !m_pStatusLabel )
|
||||
return;
|
||||
|
||||
if ( unicode && wcslen(unicode) > 0 )
|
||||
{
|
||||
m_pStatusLabel->SetText( unicode );
|
||||
}
|
||||
else
|
||||
{
|
||||
// clear
|
||||
m_pStatusLabel->SetText( "" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::OnGameListChanged()
|
||||
{
|
||||
m_pGameList = dynamic_cast<IGameList *>(m_pTabPanel->GetActivePage());
|
||||
|
||||
UpdateStatusText("");
|
||||
|
||||
InvalidateLayout();
|
||||
Repaint();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns a pointer to a static instance of this dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerBrowserDialog *CServerBrowserDialog::GetInstance()
|
||||
{
|
||||
return s_InternetDlg;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a server to the list of favorites
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::AddServerToFavorites(gameserveritem_t &server)
|
||||
{
|
||||
if ( steamapicontext->SteamMatchmaking() )
|
||||
{
|
||||
steamapicontext->SteamMatchmaking()->AddFavoriteGame(
|
||||
server.m_nAppID,
|
||||
server.m_NetAdr.GetIP(),
|
||||
server.m_NetAdr.GetConnectionPort(),
|
||||
server.m_NetAdr.GetQueryPort(),
|
||||
k_unFavoriteFlagFavorite,
|
||||
time( NULL ) );
|
||||
|
||||
if ( GameSupportsReplay() )
|
||||
{
|
||||
// send command to propagate to the client so the client can send it on to the GC
|
||||
char command[ 256 ];
|
||||
Q_snprintf( command, Q_ARRAYSIZE( command ), "rfgc %s\n", server.m_NetAdr.GetConnectionAddressString() );
|
||||
g_pRunGameEngine->AddTextCommand( command );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a server to our list of blacklisted servers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::AddServerToBlacklist(gameserveritem_t &server)
|
||||
{
|
||||
if ( m_pBlacklist )
|
||||
{
|
||||
m_pBlacklist->AddServer( server );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowserDialog::IsServerBlacklisted(gameserveritem_t &server)
|
||||
{
|
||||
if ( m_pBlacklist )
|
||||
return m_pBlacklist->IsServerBlacklisted( server );
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerContextMenu *CServerBrowserDialog::GetContextMenu(vgui::Panel *pPanel)
|
||||
{
|
||||
// create a drop down for this object's states
|
||||
if (m_pContextMenu)
|
||||
delete m_pContextMenu;
|
||||
m_pContextMenu = new CServerContextMenu(this);
|
||||
m_pContextMenu->SetAutoDelete( false );
|
||||
|
||||
if (!pPanel)
|
||||
{
|
||||
m_pContextMenu->SetParent(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pContextMenu->SetParent(pPanel);
|
||||
}
|
||||
|
||||
m_pContextMenu->SetVisible(false);
|
||||
return m_pContextMenu;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: begins the process of joining a server from a game list
|
||||
// the game info dialog it opens will also update the game list
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo *CServerBrowserDialog::JoinGame(IGameList *gameList, unsigned int serverIndex)
|
||||
{
|
||||
// open the game info dialog, then mark it to attempt to connect right away
|
||||
CDialogGameInfo *gameDialog = OpenGameInfoDialog(gameList, serverIndex);
|
||||
|
||||
// set the dialog name to be the server name
|
||||
gameDialog->Connect();
|
||||
|
||||
return gameDialog;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: joins a game by a specified IP, not attached to any game list
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo *CServerBrowserDialog::JoinGame(int serverIP, int serverPort, const char *pszConnectCode)
|
||||
{
|
||||
// open the game info dialog, then mark it to attempt to connect right away
|
||||
CDialogGameInfo *gameDialog = OpenGameInfoDialog( serverIP, serverPort, serverPort, pszConnectCode );
|
||||
|
||||
// set the dialog name to be the server name
|
||||
gameDialog->Connect();
|
||||
|
||||
return gameDialog;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens a game info dialog from a game list
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo *CServerBrowserDialog::OpenGameInfoDialog( IGameList *gameList, unsigned int serverIndex )
|
||||
{
|
||||
gameserveritem_t *pServer = gameList->GetServer( serverIndex );
|
||||
if ( !pServer )
|
||||
return NULL;
|
||||
|
||||
CDialogGameInfo *gameDialog = new CDialogGameInfo( NULL, pServer->m_NetAdr.GetIP(), pServer->m_NetAdr.GetQueryPort(), pServer->m_NetAdr.GetConnectionPort(), gameList->GetConnectCode() );
|
||||
gameDialog->SetParent(GetVParent());
|
||||
gameDialog->AddActionSignalTarget(this);
|
||||
gameDialog->Run( pServer->GetName() );
|
||||
int i = m_GameInfoDialogs.AddToTail();
|
||||
m_GameInfoDialogs[i] = gameDialog;
|
||||
return gameDialog;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: opens a game info dialog by a specified IP, not attached to any game list
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo *CServerBrowserDialog::OpenGameInfoDialog( int serverIP, uint16 connPort, uint16 queryPort, const char *pszConnectCode )
|
||||
{
|
||||
CDialogGameInfo *gameDialog = new CDialogGameInfo(NULL, serverIP, queryPort, connPort, pszConnectCode);
|
||||
gameDialog->AddActionSignalTarget(this);
|
||||
gameDialog->SetParent(GetVParent());
|
||||
gameDialog->Run("");
|
||||
int i = m_GameInfoDialogs.AddToTail();
|
||||
m_GameInfoDialogs[i] = gameDialog;
|
||||
return gameDialog;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: closes all the game info dialogs
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::CloseAllGameInfoDialogs()
|
||||
{
|
||||
for (int i = 0; i < m_GameInfoDialogs.Count(); i++)
|
||||
{
|
||||
vgui::Panel *dlg = m_GameInfoDialogs[i];
|
||||
if (dlg)
|
||||
{
|
||||
vgui::ivgui()->PostMessage(dlg->GetVPanel(), new KeyValues("Close"), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: finds a dialog
|
||||
//-----------------------------------------------------------------------------
|
||||
CDialogGameInfo *CServerBrowserDialog::GetDialogGameInfoForFriend( uint64 ulSteamIDFriend )
|
||||
{
|
||||
FOR_EACH_VEC( m_GameInfoDialogs, i )
|
||||
{
|
||||
CDialogGameInfo *pDlg = m_GameInfoDialogs[i];
|
||||
if ( pDlg && pDlg->GetAssociatedFriend() == ulSteamIDFriend )
|
||||
{
|
||||
return pDlg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: accessor to the filter save data
|
||||
//-----------------------------------------------------------------------------
|
||||
KeyValues *CServerBrowserDialog::GetFilterSaveData(const char *filterSet)
|
||||
{
|
||||
return m_pFilterData->FindKey(filterSet, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the name of the mod directory we're restricted to accessing, NULL if none
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CServerBrowserDialog::GetActiveModName()
|
||||
{
|
||||
return m_szModDir[0] ? m_szModDir : NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the name of the mod directory we're restricted to accessing, NULL if none
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CServerBrowserDialog::GetActiveGameName()
|
||||
{
|
||||
return m_szGameName[0] ? m_szGameName : NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: return the app id to limit game queries to, set by Source/HL1 engines (NOT by filter settings, that is per page)
|
||||
//-----------------------------------------------------------------------------
|
||||
CGameID &CServerBrowserDialog::GetActiveAppID()
|
||||
{
|
||||
// !TEST! Un comment this to force a particular AppID
|
||||
//m_iLimitAppID = CGameID( 440 );
|
||||
return m_iLimitAppID;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: receives a specified game is active, so no other game types can be displayed in server list
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::OnActiveGameName( KeyValues *pKV )
|
||||
{
|
||||
Q_strncpy(m_szModDir, pKV->GetString( "name" ), sizeof(m_szModDir));
|
||||
Q_strncpy(m_szGameName, pKV->GetString( "game" ), sizeof(m_szGameName));
|
||||
m_iLimitAppID = CGameID( pKV->GetUint64( "appid", 0 ) );
|
||||
// reload filter settings (since they are no forced to be game specific)
|
||||
ReloadFilterSettings();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: resets all pages filter settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::ReloadFilterSettings()
|
||||
{
|
||||
m_pInternetGames->LoadFilterSettings();
|
||||
m_pSpectateGames->LoadFilterSettings();
|
||||
m_pFavorites->LoadFilterSettings();
|
||||
m_pLanGames->LoadFilterSettings();
|
||||
m_pFriendsGames->LoadFilterSettings();
|
||||
m_pHistory->LoadFilterSettings();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds server to the history, saves as currently connected server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::OnConnectToGame( KeyValues *pMessageValues )
|
||||
{
|
||||
int ip = pMessageValues->GetInt( "ip" );
|
||||
int connectionPort = pMessageValues->GetInt( "connectionport" );
|
||||
int queryPort = pMessageValues->GetInt( "queryport" );
|
||||
|
||||
if ( !ip || !queryPort )
|
||||
return;
|
||||
|
||||
uint32 unIP = htonl( ip );
|
||||
|
||||
memset( &m_CurrentConnection, 0, sizeof(gameserveritem_t) );
|
||||
m_CurrentConnection.m_NetAdr.SetIP( unIP );
|
||||
m_CurrentConnection.m_NetAdr.SetQueryPort( queryPort );
|
||||
m_CurrentConnection.m_NetAdr.SetConnectionPort( (unsigned short)connectionPort );
|
||||
|
||||
if (m_pHistory && steamapicontext->SteamMatchmaking() )
|
||||
{
|
||||
steamapicontext->SteamMatchmaking()->AddFavoriteGame( 0, unIP, connectionPort, queryPort, k_unFavoriteFlagHistory, time( NULL ) );
|
||||
m_pHistory->SetRefreshOnReload();
|
||||
}
|
||||
|
||||
// tell the game info dialogs, so they can cancel if we have connected
|
||||
// to a server they were auto-retrying
|
||||
for (int i = 0; i < m_GameInfoDialogs.Count(); i++)
|
||||
{
|
||||
vgui::Panel *dlg = m_GameInfoDialogs[i];
|
||||
if (dlg)
|
||||
{
|
||||
KeyValues *kv = new KeyValues("ConnectedToGame", "ip", unIP, "connectionport", connectionPort);
|
||||
kv->SetInt( "queryport", queryPort );
|
||||
vgui::ivgui()->PostMessage(dlg->GetVPanel(), kv, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// forward to favorites
|
||||
m_pFavorites->OnConnectToGame();
|
||||
if ( m_pBlacklist )
|
||||
{
|
||||
m_pBlacklist->OnConnectToGame();
|
||||
}
|
||||
|
||||
m_bCurrentlyConnected = true;
|
||||
|
||||
// Now we want to track which tabs have the quick list button checked
|
||||
int iQuickListBitField = 0;
|
||||
if ( m_pFriendsGames && m_pFriendsGames->IsQuickListButtonChecked() )
|
||||
{
|
||||
iQuickListBitField |= ( 1 << 0 );
|
||||
}
|
||||
if ( m_pLanGames && m_pLanGames->IsQuickListButtonChecked() )
|
||||
{
|
||||
iQuickListBitField |= ( 1 << 1 );
|
||||
}
|
||||
if ( m_pSpectateGames && m_pSpectateGames->IsQuickListButtonChecked() )
|
||||
{
|
||||
iQuickListBitField |= ( 1 << 2 );
|
||||
}
|
||||
if ( m_pHistory && m_pHistory->IsQuickListButtonChecked() )
|
||||
{
|
||||
iQuickListBitField |= ( 1 << 3 );
|
||||
}
|
||||
if ( m_pFavorites && m_pFavorites->IsQuickListButtonChecked() )
|
||||
{
|
||||
iQuickListBitField |= ( 1 << 4 );
|
||||
}
|
||||
if ( m_pInternetGames && m_pInternetGames->IsQuickListButtonChecked() )
|
||||
{
|
||||
iQuickListBitField |= ( 1 << 5 );
|
||||
}
|
||||
|
||||
// Set the value so that the client.dll can use it for gamestats
|
||||
sb_quick_list_bit_field.SetValue( iQuickListBitField );
|
||||
|
||||
// TF2 wants to close this dialog when the player connects to a game
|
||||
if ( GameSupportsReplay() )
|
||||
{
|
||||
ConVarRef sb_close_browser_on_connect( "sb_close_browser_on_connect" );
|
||||
if ( sb_close_browser_on_connect.IsValid() )
|
||||
{
|
||||
if ( sb_close_browser_on_connect.GetBool() == true )
|
||||
{
|
||||
OnClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Clears currently connected server
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::OnDisconnectFromGame( void )
|
||||
{
|
||||
m_bCurrentlyConnected = false;
|
||||
memset( &m_CurrentConnection, 0, sizeof(gameserveritem_t) );
|
||||
|
||||
// forward to favorites
|
||||
m_pFavorites->OnDisconnectFromGame();
|
||||
if ( m_pBlacklist )
|
||||
{
|
||||
m_pBlacklist->OnDisconnectFromGame();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when start start loading, so we can cease server browser activity
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::OnLoadingStarted( void )
|
||||
{
|
||||
m_pInternetGames->OnLoadingStarted();
|
||||
m_pSpectateGames->OnLoadingStarted();
|
||||
m_pFavorites->OnLoadingStarted();
|
||||
m_pLanGames->OnLoadingStarted();
|
||||
m_pFriendsGames->OnLoadingStarted();
|
||||
m_pHistory->OnLoadingStarted();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Passes build mode activation down into the pages
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerBrowserDialog::ActivateBuildMode()
|
||||
{
|
||||
// no subpanel, no build mode
|
||||
EditablePanel *panel = dynamic_cast<EditablePanel *>(m_pTabPanel->GetActivePage());
|
||||
if (!panel)
|
||||
return;
|
||||
|
||||
panel->ActivateBuildMode();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the default position and size on the screen to appear the first time
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerBrowserDialog::GetDefaultScreenPosition(int &x, int &y, int &wide, int &tall)
|
||||
{
|
||||
int wx, wy, ww, wt;
|
||||
surface()->GetWorkspaceBounds( wx, wy, ww, wt );
|
||||
x = wx + (int)(ww * 0.05);
|
||||
y = wy + (int)(wt * 0.4);
|
||||
wide = (int)(ww * 0.5);
|
||||
tall = (int)(wt * 0.55);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CServerBrowserDialog::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
// Handle close here, CBasePanel parent doesn't support "DialogClosing" command
|
||||
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
|
||||
|
||||
if ( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
|
||||
{
|
||||
OnCommand( "Close" );
|
||||
return;
|
||||
}
|
||||
else if ( nButtonCode == KEY_XBUTTON_A || nButtonCode == STEAMCONTROLLER_A )
|
||||
{
|
||||
//OnOK( false );
|
||||
//return;
|
||||
}
|
||||
else if ( nButtonCode == KEY_XBUTTON_UP ||
|
||||
nButtonCode == KEY_XSTICK1_UP ||
|
||||
nButtonCode == KEY_XSTICK2_UP ||
|
||||
nButtonCode == STEAMCONTROLLER_DPAD_UP ||
|
||||
nButtonCode == KEY_UP ||
|
||||
nButtonCode == KEY_XBUTTON_DOWN ||
|
||||
nButtonCode == KEY_XSTICK1_DOWN ||
|
||||
nButtonCode == KEY_XSTICK2_DOWN ||
|
||||
nButtonCode == STEAMCONTROLLER_DPAD_DOWN ||
|
||||
nButtonCode == KEY_DOWN )
|
||||
{
|
||||
CBaseGamesPage *pGamesPage = dynamic_cast< CBaseGamesPage* >( m_pTabPanel->GetActivePage() );
|
||||
if ( pGamesPage )
|
||||
{
|
||||
ListPanel *pListPanel = dynamic_cast< ListPanel * >( pGamesPage->GetActiveList() );
|
||||
if ( pListPanel )
|
||||
{
|
||||
if ( pListPanel->GetSelectedItem( 0 ) == -1 )
|
||||
{
|
||||
pListPanel->SetSingleSelectedItem( pListPanel->GetItemIDFromRow( 0 ) );
|
||||
pListPanel->RequestFocus();
|
||||
return;
|
||||
}
|
||||
else if ( !pListPanel->HasFocus() )
|
||||
{
|
||||
pListPanel->RequestFocus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
}
|
159
serverbrowser/ServerBrowserDialog.h
Normal file
159
serverbrowser/ServerBrowserDialog.h
Normal file
@ -0,0 +1,159 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVERBROWSERDIALOG_H
|
||||
#define SERVERBROWSERDIALOG_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
extern class IRunGameEngine *g_pRunGameEngine;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CServerBrowserDialog : public vgui::Frame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CServerBrowserDialog, vgui::Frame );
|
||||
|
||||
public:
|
||||
// Construction/destruction
|
||||
CServerBrowserDialog( vgui::Panel *parent );
|
||||
~CServerBrowserDialog( void );
|
||||
|
||||
void Initialize( void );
|
||||
|
||||
// displays the dialog, moves it into focus, updates if it has to
|
||||
void Open( void );
|
||||
|
||||
// gets server info
|
||||
gameserveritem_t *GetServer(unsigned int serverID);
|
||||
// called every frame
|
||||
virtual void OnTick();
|
||||
|
||||
// updates status text at bottom of window
|
||||
void UpdateStatusText(PRINTF_FORMAT_STRING const char *format, ...);
|
||||
|
||||
// updates status text at bottom of window
|
||||
void UpdateStatusText(wchar_t *unicode);
|
||||
|
||||
// context menu access
|
||||
CServerContextMenu *GetContextMenu(vgui::Panel *pParent);
|
||||
|
||||
// returns a pointer to a static instance of this dialog
|
||||
// valid for use only in sort functions
|
||||
static CServerBrowserDialog *GetInstance();
|
||||
|
||||
// Adds a server to the list of favorites
|
||||
void AddServerToFavorites(gameserveritem_t &server);
|
||||
// Adds a server to our list of blacklisted servers
|
||||
void AddServerToBlacklist(gameserveritem_t &server);
|
||||
bool IsServerBlacklisted(gameserveritem_t &server);
|
||||
|
||||
// begins the process of joining a server from a game list
|
||||
// the game info dialog it opens will also update the game list
|
||||
CDialogGameInfo *JoinGame(IGameList *gameList, unsigned int serverIndex);
|
||||
|
||||
// joins a game by a specified IP, not attached to any game list
|
||||
CDialogGameInfo *JoinGame(int serverIP, int serverPort, const char *pszConnectCode);
|
||||
|
||||
// opens a game info dialog from a game list
|
||||
CDialogGameInfo *OpenGameInfoDialog(IGameList *gameList, unsigned int serverIndex);
|
||||
|
||||
// opens a game info dialog by a specified IP, not attached to any game list
|
||||
CDialogGameInfo *OpenGameInfoDialog( int serverIP, uint16 connPort, uint16 queryPort, const char *pszConnectCode );
|
||||
|
||||
// closes all the game info dialogs
|
||||
void CloseAllGameInfoDialogs();
|
||||
CDialogGameInfo *GetDialogGameInfoForFriend( uint64 ulSteamIDFriend );
|
||||
|
||||
// accessor to the filter save data
|
||||
KeyValues *GetFilterSaveData(const char *filterSet);
|
||||
|
||||
// gets the name of the mod directory we're restricted to accessing, NULL if none
|
||||
const char *GetActiveModName();
|
||||
CGameID &GetActiveAppID();
|
||||
const char *GetActiveGameName();
|
||||
|
||||
// load/saves filter & favorites settings from disk
|
||||
void LoadUserData();
|
||||
void SaveUserData();
|
||||
|
||||
// forces the currently active page to refresh
|
||||
void RefreshCurrentPage();
|
||||
|
||||
virtual gameserveritem_t *GetCurrentConnectedServer()
|
||||
{
|
||||
return &m_CurrentConnection;
|
||||
}
|
||||
|
||||
void BlacklistsChanged();
|
||||
CBlacklistedServers *GetBlacklistPage( void ) { return m_pBlacklist; }
|
||||
|
||||
private:
|
||||
|
||||
// current game list change
|
||||
MESSAGE_FUNC( OnGameListChanged, "PageChanged" );
|
||||
void ReloadFilterSettings();
|
||||
|
||||
// receives a specified game is active, so no other game types can be displayed in server list
|
||||
MESSAGE_FUNC_PARAMS( OnActiveGameName, "ActiveGameName", name );
|
||||
|
||||
// notification that we connected / disconnected
|
||||
MESSAGE_FUNC_PARAMS( OnConnectToGame, "ConnectedToGame", kv );
|
||||
MESSAGE_FUNC( OnDisconnectFromGame, "DisconnectedFromGame" );
|
||||
MESSAGE_FUNC( OnLoadingStarted, "LoadingStarted" );
|
||||
|
||||
virtual bool GetDefaultScreenPosition(int &x, int &y, int &wide, int &tall);
|
||||
virtual void ActivateBuildMode();
|
||||
|
||||
void OnKeyCodePressed( vgui::KeyCode code );
|
||||
|
||||
private:
|
||||
// list of all open game info dialogs
|
||||
CUtlVector<vgui::DHANDLE<CDialogGameInfo> > m_GameInfoDialogs;
|
||||
|
||||
// pointer to current game list
|
||||
IGameList *m_pGameList;
|
||||
|
||||
// Status text
|
||||
vgui::Label *m_pStatusLabel;
|
||||
|
||||
// property sheet
|
||||
vgui::PropertySheet *m_pTabPanel;
|
||||
CFavoriteGames *m_pFavorites;
|
||||
CBlacklistedServers *m_pBlacklist;
|
||||
CHistoryGames *m_pHistory;
|
||||
CInternetGames *m_pInternetGames;
|
||||
CSpectateGames *m_pSpectateGames;
|
||||
CLanGames *m_pLanGames;
|
||||
CFriendsGames *m_pFriendsGames;
|
||||
|
||||
KeyValues *m_pSavedData;
|
||||
KeyValues *m_pFilterData;
|
||||
|
||||
// context menu
|
||||
CServerContextMenu *m_pContextMenu;
|
||||
|
||||
// active game
|
||||
char m_szGameName[128];
|
||||
char m_szModDir[128];
|
||||
CGameID m_iLimitAppID;
|
||||
|
||||
// currently connected game
|
||||
bool m_bCurrentlyConnected;
|
||||
gameserveritem_t m_CurrentConnection;
|
||||
};
|
||||
|
||||
// singleton accessor
|
||||
extern CServerBrowserDialog &ServerBrowserDialog();
|
||||
|
||||
// Used by the LAN tab and the add server dialog when trying to find servers without having
|
||||
// been given any ports to look for servers on.
|
||||
void GetMostCommonQueryPorts( CUtlVector<uint16> &ports );
|
||||
|
||||
#endif // SERVERBROWSERDIALOG_H
|
63
serverbrowser/ServerContextMenu.cpp
Normal file
63
serverbrowser/ServerContextMenu.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerContextMenu::CServerContextMenu(Panel *parent) : Menu(parent, "ServerContextMenu")
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CServerContextMenu::~CServerContextMenu()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Activates the menu
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerContextMenu::ShowMenu(
|
||||
Panel *target,
|
||||
unsigned int serverID,
|
||||
bool showConnect,
|
||||
bool showViewGameInfo,
|
||||
bool showRefresh,
|
||||
bool showAddToFavorites )
|
||||
{
|
||||
if (showConnect)
|
||||
{
|
||||
AddMenuItem("ConnectToServer", "#ServerBrowser_ConnectToServer", new KeyValues("ConnectToServer", "serverID", serverID), target);
|
||||
}
|
||||
|
||||
if (showViewGameInfo)
|
||||
{
|
||||
AddMenuItem("ViewGameInfo", "#ServerBrowser_ViewServerInfo", new KeyValues("ViewGameInfo", "serverID", serverID), target);
|
||||
}
|
||||
|
||||
if (showRefresh)
|
||||
{
|
||||
AddMenuItem("RefreshServer", "#ServerBrowser_RefreshServer", new KeyValues("RefreshServer", "serverID", serverID), target);
|
||||
}
|
||||
|
||||
if (showAddToFavorites)
|
||||
{
|
||||
AddMenuItem("AddToFavorites", "#ServerBrowser_AddServerToFavorites", new KeyValues("AddToFavorites", "serverID", serverID), target);
|
||||
AddMenuItem("AddToBlacklist", "#ServerBrowser_AddServerToBlacklist", new KeyValues("AddToBlacklist", "serverID", serverID), target);
|
||||
}
|
||||
|
||||
int x, y, gx, gy;
|
||||
input()->GetCursorPos(x, y);
|
||||
ipanel()->GetPos(surface()->GetEmbeddedPanel(), gx, gy);
|
||||
SetPos(x - gx, y - gy);
|
||||
SetVisible(true);
|
||||
}
|
34
serverbrowser/ServerContextMenu.h
Normal file
34
serverbrowser/ServerContextMenu.h
Normal file
@ -0,0 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVERCONTEXTMENU_H
|
||||
#define SERVERCONTEXTMENU_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Basic right-click context menu for servers
|
||||
//-----------------------------------------------------------------------------
|
||||
class CServerContextMenu : public vgui::Menu
|
||||
{
|
||||
public:
|
||||
CServerContextMenu(vgui::Panel *parent);
|
||||
~CServerContextMenu();
|
||||
|
||||
// call this to Activate the menu
|
||||
void ShowMenu(
|
||||
vgui::Panel *target,
|
||||
unsigned int serverID,
|
||||
bool showConnect,
|
||||
bool showViewGameInfo,
|
||||
bool showRefresh,
|
||||
bool showAddToFavorites);
|
||||
};
|
||||
|
||||
|
||||
#endif // SERVERCONTEXTMENU_H
|
289
serverbrowser/ServerListCompare.cpp
Normal file
289
serverbrowser/ServerListCompare.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
bool IsReplayServer( gameserveritem_t &server );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: List password column sort function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl PasswordCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1->m_bPassword < s2->m_bPassword )
|
||||
return 1;
|
||||
else if ( s1->m_bPassword > s2->m_bPassword )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: list column sort function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl BotsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1->m_nBotPlayers < s2->m_nBotPlayers )
|
||||
return 1;
|
||||
else if ( s1->m_nBotPlayers > s2->m_nBotPlayers )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: list column sort function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl SecureCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1->m_bSecure < s2->m_bSecure )
|
||||
return 1;
|
||||
else if ( s1->m_bSecure > s2->m_bSecure )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: list column sort function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl IPAddressCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
if ( s1->m_NetAdr < s2->m_NetAdr )
|
||||
return -1;
|
||||
else if ( s2->m_NetAdr < s1->m_NetAdr )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Ping comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl PingCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
int ping1 = s1->m_nPing;
|
||||
int ping2 = s2->m_nPing;
|
||||
|
||||
if ( ping1 < ping2 )
|
||||
return -1;
|
||||
else if ( ping1 > ping2 )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Map comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl MapCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
return Q_stricmp( s1->m_szMap, s2->m_szMap );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Game dir comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl GameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
// make sure we haven't added the same server to the list twice
|
||||
Assert( p1.userData != p2.userData );
|
||||
|
||||
return Q_stricmp( s1->m_szGameDescription, s2->m_szGameDescription );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Server name comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl ServerNameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
return Q_stricmp( s1->GetName(), s2->GetName() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Player number comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl PlayersCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
int s1p = max( 0, s1->m_nPlayers - s1->m_nBotPlayers );
|
||||
int s1m = max( 0, s1->m_nMaxPlayers - s1->m_nBotPlayers );
|
||||
int s2p = max( 0, s2->m_nPlayers - s2->m_nBotPlayers );
|
||||
int s2m = max( 0, s2->m_nMaxPlayers - s2->m_nBotPlayers );
|
||||
|
||||
// compare number of players
|
||||
if ( s1p > s2p )
|
||||
return -1;
|
||||
if ( s1p < s2p )
|
||||
return 1;
|
||||
|
||||
// compare max players if number of current players is equal
|
||||
if ( s1m > s2m )
|
||||
return -1;
|
||||
if ( s1m < s2m )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Player number comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl LastPlayedCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer( p1.userData );
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer( p2.userData );
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
// compare number of players
|
||||
if ( s1->m_ulTimeLastPlayed > s2->m_ulTimeLastPlayed )
|
||||
return -1;
|
||||
if ( s1->m_ulTimeLastPlayed < s2->m_ulTimeLastPlayed )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Tag comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl TagsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
return Q_stricmp( s1->m_szGameTags, s2->m_szGameTags );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Replay comparison function
|
||||
//-----------------------------------------------------------------------------
|
||||
int __cdecl ReplayCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2)
|
||||
{
|
||||
gameserveritem_t *s1 = ServerBrowserDialog().GetServer(p1.userData);
|
||||
gameserveritem_t *s2 = ServerBrowserDialog().GetServer(p2.userData);
|
||||
|
||||
if ( !s1 && s2 )
|
||||
return -1;
|
||||
if ( !s2 && s1 )
|
||||
return 1;
|
||||
if ( !s1 && !s2 )
|
||||
return 0;
|
||||
|
||||
bool s1_is_replay = IsReplayServer( *s1 );
|
||||
bool s2_is_replay = IsReplayServer( *s2 );
|
||||
|
||||
if ( s1_is_replay < s2_is_replay )
|
||||
return 1;
|
||||
else if ( s1_is_replay > s2_is_replay )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
32
serverbrowser/ServerListCompare.h
Normal file
32
serverbrowser/ServerListCompare.h
Normal file
@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SERVERLISTCOMPARE_H
|
||||
#define SERVERLISTCOMPARE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
using vgui::ListPanel;
|
||||
using vgui::ListPanelItem;
|
||||
|
||||
|
||||
// these functions are common to most server lists in sorts
|
||||
int __cdecl PasswordCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl BotsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl PingCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl PlayersCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl MapCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl GameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl ServerNameCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl SecureCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl IPAddressCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl LastPlayedCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl TagsCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
int __cdecl ReplayCompare(ListPanel *pPanel, const ListPanelItem &p1, const ListPanelItem &p2);
|
||||
|
||||
#endif // SERVERLISTCOMPARE_H
|
33
serverbrowser/SpectateGames.cpp
Normal file
33
serverbrowser/SpectateGames.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
|
||||
CSpectateGames::CSpectateGames( vgui::Panel *parent )
|
||||
: CInternetGames( parent, "SpectateGames", eSpectatorServer )
|
||||
{
|
||||
}
|
||||
|
||||
void CSpectateGames::GetNewServerList()
|
||||
{
|
||||
m_vecServerFilters.AddToTail( MatchMakingKeyValuePair_t( "proxy", "1" ) );
|
||||
BaseClass::GetNewServerList();
|
||||
}
|
||||
|
||||
void CSpectateGames::OnPageShow()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSpectateGames::CheckTagFilter( gameserveritem_t &server )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
38
serverbrowser/SpectateGames.h
Normal file
38
serverbrowser/SpectateGames.h
Normal file
@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef SPECTATEGAMES_H
|
||||
#define SPECTATEGAMES_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "InternetGames.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spectator games list
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSpectateGames : public CInternetGames
|
||||
{
|
||||
public:
|
||||
CSpectateGames(vgui::Panel *parent);
|
||||
|
||||
// property page handlers
|
||||
virtual void OnPageShow();
|
||||
|
||||
virtual bool CheckTagFilter( gameserveritem_t &server );
|
||||
|
||||
protected:
|
||||
// filters by spectator games
|
||||
virtual void GetNewServerList();
|
||||
|
||||
private:
|
||||
typedef CInternetGames BaseClass;
|
||||
};
|
||||
|
||||
|
||||
#endif // SPECTATEGAMES_H
|
22
serverbrowser/VACBannedConnRefusedDialog.cpp
Normal file
22
serverbrowser/VACBannedConnRefusedDialog.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CVACBannedConnRefusedDialog::CVACBannedConnRefusedDialog( VPANEL hVParent, const char *name ) : BaseClass( NULL, name )
|
||||
{
|
||||
SetParent( hVParent );
|
||||
SetSize( 480, 220 );
|
||||
SetSizeable( false );
|
||||
|
||||
LoadControlSettings( "servers/VACBannedConnRefusedDialog.res" );
|
||||
MoveToCenterOfScreen();
|
||||
}
|
29
serverbrowser/VACBannedConnRefusedDialog.h
Normal file
29
serverbrowser/VACBannedConnRefusedDialog.h
Normal file
@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VACBANNEDCONNREFUSED_H
|
||||
#define VACBANNEDCONNREFUSED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displays information about new VAC bans
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVACBannedConnRefusedDialog : public vgui::Frame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CVACBannedConnRefusedDialog, vgui::Frame );
|
||||
|
||||
public:
|
||||
CVACBannedConnRefusedDialog( vgui::VPANEL hVParent, const char *name );
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // VACBANNEDCONNREFUSED_H
|
91
serverbrowser/igamelist.h
Normal file
91
serverbrowser/igamelist.h
Normal file
@ -0,0 +1,91 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef IGAMELIST_H
|
||||
#define IGAMELIST_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class gameserveritem_t;
|
||||
#if defined( STEAM )
|
||||
#include "steam2common.h"
|
||||
#include "FindSteam2Servers.h"
|
||||
#else
|
||||
#include "steamcommon.h"
|
||||
#include "FindSteamServers.h"
|
||||
#endif
|
||||
#include "netadr.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SERVERVERSION_SAME_VERSION = 0,
|
||||
SERVERVERSION_SERVER_OLD,
|
||||
SERVERVERSION_SERVER_NEWER
|
||||
} SERVERVERSION;
|
||||
|
||||
struct serverdisplay_t
|
||||
{
|
||||
serverdisplay_t()
|
||||
{
|
||||
m_iListID = -1;
|
||||
m_iServerID = -1;
|
||||
m_bDoNotRefresh = true;
|
||||
}
|
||||
int m_iListID; // the VGUI2 list panel index for displaying this server
|
||||
int m_iServerID; // the matchmaking interface index for this server
|
||||
bool m_bDoNotRefresh;
|
||||
bool operator==( const serverdisplay_t &rhs ) const { return rhs.m_iServerID == m_iServerID; }
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Interface to accessing a game list
|
||||
//-----------------------------------------------------------------------------
|
||||
class IGameList
|
||||
{
|
||||
public:
|
||||
|
||||
enum InterfaceItem_e
|
||||
{
|
||||
FILTERS,
|
||||
GETNEWLIST,
|
||||
ADDSERVER,
|
||||
ADDCURRENTSERVER,
|
||||
};
|
||||
|
||||
// returns true if the game list supports the specified ui elements
|
||||
virtual bool SupportsItem(InterfaceItem_e item) = 0;
|
||||
|
||||
// starts the servers refreshing
|
||||
virtual void StartRefresh() = 0;
|
||||
|
||||
// gets a new server list
|
||||
virtual void GetNewServerList() = 0;
|
||||
|
||||
// stops current refresh/GetNewServerList()
|
||||
virtual void StopRefresh() = 0;
|
||||
|
||||
// returns true if the list is currently refreshing servers
|
||||
virtual bool IsRefreshing() = 0;
|
||||
|
||||
// gets information about specified server
|
||||
virtual gameserveritem_t *GetServer(unsigned int serverID) = 0;
|
||||
|
||||
// called when Connect button is pressed
|
||||
virtual void OnBeginConnect() = 0;
|
||||
|
||||
// invalid server index
|
||||
virtual int GetInvalidServerListID() = 0;
|
||||
|
||||
// Get code to use for tracking how people are connecting to servers
|
||||
virtual const char *GetConnectCode() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // IGAMELIST_H
|
7
serverbrowser/pch_serverbrowser.cpp
Normal file
7
serverbrowser/pch_serverbrowser.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "pch_serverbrowser.h"
|
86
serverbrowser/pch_serverbrowser.h
Normal file
86
serverbrowser/pch_serverbrowser.h
Normal file
@ -0,0 +1,86 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include <winlite.h>
|
||||
#undef CreateDialog
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "vstdlib/pch_vstdlib.h"
|
||||
#include "tier0/memdbgoff.h"
|
||||
#include "vgui_controls/pch_vgui_controls.h"
|
||||
#include "vgui_controls/Frame.h"
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#include "tier3/tier3.h"
|
||||
|
||||
// steam3 API
|
||||
//#include "steam/steam_querypackets.h"
|
||||
#include "steam/steam_api.h"
|
||||
#include "steam/isteamuser.h"
|
||||
#include "steam/isteammatchmaking.h"
|
||||
#include "steam/isteamfriends.h"
|
||||
|
||||
#include "ServerBrowser/IServerBrowser.h"
|
||||
#include "IVguiModule.h"
|
||||
#include "vgui_controls/Controls.h"
|
||||
|
||||
#include "netadr.h"
|
||||
#include "filesystem.h"
|
||||
#include "proto_oob.h"
|
||||
#include "ModList.h"
|
||||
#include "IRunGameEngine.h"
|
||||
|
||||
#include "OfflineMode.h"
|
||||
|
||||
// serverbrowser files
|
||||
|
||||
#include "igamelist.h"
|
||||
#include "ServerListCompare.h"
|
||||
#include "ServerBrowser.h"
|
||||
#include "VACBannedConnRefusedDialog.h"
|
||||
#include "DialogGameInfo.h"
|
||||
#include "ServerContextMenu.h"
|
||||
#include "DialogServerPassword.h"
|
||||
#include "DialogAddServer.h"
|
||||
|
||||
// game list
|
||||
#include "BaseGamesPage.h"
|
||||
#include "BlacklistedServers.h"
|
||||
#include "InternetGames.h"
|
||||
#include "FavoriteGames.h"
|
||||
#include "SpectateGames.h"
|
||||
#include "LanGames.h"
|
||||
#include "FriendsGames.h"
|
||||
#include "HistoryGames.h"
|
||||
#include "SpectateGames.h"
|
||||
#include "CustomGames.h"
|
||||
#include "ServerBrowserDialog.h"
|
||||
#include "QuickListPanel.h"
|
||||
#include "vgui_controls/PanelListPanel.h"
|
||||
|
||||
#include "replay/ienginereplay.h"
|
||||
|
||||
extern bool GameSupportsReplay();
|
||||
extern bool IsReplayServer( gameserveritem_t &server );
|
||||
|
||||
#pragma warning( disable: 4355 ) // warning C4355: 'this' : used in base member initializer list
|
||||
|
||||
#if defined( STEAM )
|
||||
#define IsSteam() true
|
||||
#else
|
||||
#define IsSteam() false
|
||||
#endif
|
||||
|
||||
using namespace vgui;
|
15
serverbrowser/resource.h
Normal file
15
serverbrowser/resource.h
Normal file
@ -0,0 +1,15 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by ServerBrowser.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
3
serverbrowser/xbox/xbox.def
Normal file
3
serverbrowser/xbox/xbox.def
Normal file
@ -0,0 +1,3 @@
|
||||
LIBRARY serverbrowser_360.dll
|
||||
EXPORTS
|
||||
CreateInterface @1
|
Reference in New Issue
Block a user