From 3bf9df6b2785fa6d951086978a3e66f49427166a Mon Sep 17 00:00:00 2001 From: FluorescentCIAAfricanAmerican <0934gj3049fk@protonmail.com> Date: Wed, 22 Apr 2020 12:56:21 -0400 Subject: 1 --- serverbrowser/CustomGames.cpp | 448 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 serverbrowser/CustomGames.cpp (limited to 'serverbrowser/CustomGames.cpp') diff --git a/serverbrowser/CustomGames.cpp b/serverbrowser/CustomGames.cpp new file mode 100644 index 0000000..26ebb55 --- /dev/null +++ b/serverbrowser/CustomGames.cpp @@ -0,0 +1,448 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "pch_serverbrowser.h" +#include +#include + +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 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 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 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 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(); +} -- cgit v1.2.3