2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2011-11-29 21:18:40 +00:00
# include <algorithm> // sort TODO: remove this
2010-05-29 07:25:38 +00:00
2019-04-06 00:46:56 +00:00
# include <base/hash_ctxt.h>
2011-01-19 14:54:50 +00:00
# include <base/math.h>
2010-05-29 07:25:38 +00:00
# include <base/system.h>
2011-03-23 12:06:35 +00:00
2010-05-29 07:25:38 +00:00
# include <engine/shared/config.h>
2020-01-01 19:07:04 +00:00
# include <engine/shared/json.h>
2010-05-29 07:25:38 +00:00
# include <engine/shared/memheap.h>
2011-03-23 12:06:35 +00:00
# include <engine/shared/network.h>
# include <engine/shared/protocol.h>
2010-05-29 07:25:38 +00:00
# include <engine/config.h>
2011-03-23 12:06:35 +00:00
# include <engine/console.h>
# include <engine/friends.h>
# include <engine/masterserver.h>
2014-09-13 14:36:25 +00:00
# include <engine/storage.h>
2010-05-29 07:25:38 +00:00
# include <mastersrv/mastersrv.h>
2014-09-18 14:13:06 +00:00
# include <engine/external/json-parser/json.h>
2011-03-27 16:00:54 +00:00
# include "serverbrowser.h"
2010-05-29 07:25:38 +00:00
class SortWrap
{
typedef bool ( CServerBrowser : : * SortFunc ) ( int , int ) const ;
SortFunc m_pfnSort ;
CServerBrowser * m_pThis ;
2020-09-26 19:41:58 +00:00
2010-05-29 07:25:38 +00:00
public :
2020-09-26 19:41:58 +00:00
SortWrap ( CServerBrowser * t , SortFunc f ) :
m_pfnSort ( f ) , m_pThis ( t ) { }
2011-11-29 21:34:47 +00:00
bool operator ( ) ( int a , int b ) { return ( g_Config . m_BrSortOrder ? ( m_pThis - > * m_pfnSort ) ( b , a ) : ( m_pThis - > * m_pfnSort ) ( a , b ) ) ; }
2010-05-29 07:25:38 +00:00
} ;
CServerBrowser : : CServerBrowser ( )
{
m_pMasterServer = 0 ;
m_ppServerlist = 0 ;
m_pSortedServerlist = 0 ;
m_NumFavoriteServers = 0 ;
mem_zero ( m_aServerlistIp , sizeof ( m_aServerlistIp ) ) ;
m_pFirstReqServer = 0 ; // request list
m_pLastReqServer = 0 ;
m_NumRequests = 0 ;
m_NeedRefresh = 0 ;
m_NumSortedServers = 0 ;
m_NumSortedServersCapacity = 0 ;
m_NumServers = 0 ;
m_NumServerCapacity = 0 ;
m_Sorthash = 0 ;
m_aFilterString [ 0 ] = 0 ;
m_aFilterGametypeString [ 0 ] = 0 ;
m_ServerlistType = 0 ;
m_BroadcastTime = 0 ;
2017-10-14 19:58:23 +00:00
secure_random_fill ( m_aTokenSeed , sizeof ( m_aTokenSeed ) ) ;
m_RequestNumber = 0 ;
2017-08-30 19:34:01 +00:00
2017-09-03 15:36:51 +00:00
m_pDDNetInfo = 0 ;
}
CServerBrowser : : ~ CServerBrowser ( )
{
2020-10-13 16:05:59 +00:00
if ( m_ppServerlist )
free ( m_ppServerlist ) ;
if ( m_pSortedServerlist )
free ( m_pSortedServerlist ) ;
2017-09-03 15:36:51 +00:00
if ( m_pDDNetInfo )
json_value_free ( m_pDDNetInfo ) ;
2010-05-29 07:25:38 +00:00
}
void CServerBrowser : : SetBaseInfo ( class CNetClient * pClient , const char * pNetVersion )
{
m_pNetClient = pClient ;
str_copy ( m_aNetVersion , pNetVersion , sizeof ( m_aNetVersion ) ) ;
m_pMasterServer = Kernel ( ) - > RequestInterface < IMasterServer > ( ) ;
2010-08-17 22:06:00 +00:00
m_pConsole = Kernel ( ) - > RequestInterface < IConsole > ( ) ;
2011-03-23 12:06:35 +00:00
m_pFriends = Kernel ( ) - > RequestInterface < IFriends > ( ) ;
2010-05-29 07:25:38 +00:00
IConfig * pConfig = Kernel ( ) - > RequestInterface < IConfig > ( ) ;
if ( pConfig )
pConfig - > RegisterCallback ( ConfigSaveCallback , this ) ;
}
const CServerInfo * CServerBrowser : : SortedGet ( int Index ) const
{
if ( Index < 0 | | Index > = m_NumSortedServers )
return 0 ;
return & m_ppServerlist [ m_pSortedServerlist [ Index ] ] - > m_Info ;
}
2017-10-14 19:58:23 +00:00
int CServerBrowser : : GenerateToken ( const NETADDR & Addr ) const
{
2019-04-06 00:47:00 +00:00
SHA256_CTX Sha256 ;
sha256_init ( & Sha256 ) ;
sha256_update ( & Sha256 , m_aTokenSeed , sizeof ( m_aTokenSeed ) ) ;
sha256_update ( & Sha256 , ( unsigned char * ) & Addr , sizeof ( Addr ) ) ;
SHA256_DIGEST Digest = sha256_finish ( & Sha256 ) ;
2019-04-06 00:46:56 +00:00
return ( Digest . data [ 0 ] < < 16 ) | ( Digest . data [ 1 ] < < 8 ) | Digest . data [ 2 ] ;
2017-10-14 19:58:23 +00:00
}
int CServerBrowser : : GetBasicToken ( int Token )
{
return Token & 0xff ;
}
int CServerBrowser : : GetExtraToken ( int Token )
{
return Token > > 8 ;
}
2010-05-29 07:25:38 +00:00
bool CServerBrowser : : SortCompareName ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
2010-08-12 17:29:59 +00:00
// make sure empty entries are listed last
2011-04-13 18:37:12 +00:00
return ( a - > m_GotInfo & & b - > m_GotInfo ) | | ( ! a - > m_GotInfo & & ! b - > m_GotInfo ) ? str_comp ( a - > m_Info . m_aName , b - > m_Info . m_aName ) < 0 :
2020-09-26 19:41:58 +00:00
a - > m_GotInfo ? true : false ;
2010-05-29 07:25:38 +00:00
}
bool CServerBrowser : : SortCompareMap ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
return str_comp ( a - > m_Info . m_aMap , b - > m_Info . m_aMap ) < 0 ;
}
bool CServerBrowser : : SortComparePing ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
return a - > m_Info . m_Latency < b - > m_Info . m_Latency ;
}
bool CServerBrowser : : SortCompareGametype ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
return str_comp ( a - > m_Info . m_aGameType , b - > m_Info . m_aGameType ) < 0 ;
}
bool CServerBrowser : : SortCompareNumPlayers ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
2020-08-25 00:26:36 +00:00
return a - > m_Info . m_NumFilteredPlayers > b - > m_Info . m_NumFilteredPlayers ;
2010-05-29 07:25:38 +00:00
}
2011-03-20 14:33:49 +00:00
bool CServerBrowser : : SortCompareNumClients ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
2020-08-25 00:26:36 +00:00
return a - > m_Info . m_NumClients > b - > m_Info . m_NumClients ;
2011-03-20 14:33:49 +00:00
}
2020-08-24 21:23:37 +00:00
bool CServerBrowser : : SortCompareNumPlayersAndPing ( int Index1 , int Index2 ) const
{
CServerEntry * a = m_ppServerlist [ Index1 ] ;
CServerEntry * b = m_ppServerlist [ Index2 ] ;
if ( a - > m_Info . m_NumFilteredPlayers = = b - > m_Info . m_NumFilteredPlayers )
return a - > m_Info . m_Latency > b - > m_Info . m_Latency ;
2020-10-23 23:17:03 +00:00
else if ( a - > m_Info . m_NumFilteredPlayers = = 0 | | b - > m_Info . m_NumFilteredPlayers = = 0 | | a - > m_Info . m_Latency / 100 = = b - > m_Info . m_Latency / 100 )
return a - > m_Info . m_NumFilteredPlayers < b - > m_Info . m_NumFilteredPlayers ;
2020-08-24 21:23:37 +00:00
else
2020-10-23 23:17:03 +00:00
return a - > m_Info . m_Latency > b - > m_Info . m_Latency ;
2020-08-24 21:23:37 +00:00
}
2010-05-29 07:25:38 +00:00
void CServerBrowser : : Filter ( )
{
int i = 0 , p = 0 ;
m_NumSortedServers = 0 ;
// allocate the sorted list
if ( m_NumSortedServersCapacity < m_NumServers )
{
if ( m_pSortedServerlist )
2018-04-09 09:56:39 +00:00
free ( m_pSortedServerlist ) ;
2010-05-29 07:25:38 +00:00
m_NumSortedServersCapacity = m_NumServers ;
2018-04-09 09:56:39 +00:00
m_pSortedServerlist = ( int * ) calloc ( m_NumSortedServersCapacity , sizeof ( int ) ) ;
2010-05-29 07:25:38 +00:00
}
// filter the servers
for ( i = 0 ; i < m_NumServers ; i + + )
{
int Filtered = 0 ;
2018-10-29 21:03:57 +00:00
if ( g_Config . m_BrFilterEmpty & & m_ppServerlist [ i ] - > m_Info . m_NumFilteredPlayers = = 0 )
2011-06-26 15:10:13 +00:00
Filtered = 1 ;
2018-08-21 07:03:29 +00:00
else if ( g_Config . m_BrFilterFull & & Players ( m_ppServerlist [ i ] - > m_Info ) = = Max ( m_ppServerlist [ i ] - > m_Info ) )
2011-06-26 15:10:13 +00:00
Filtered = 1 ;
2020-09-26 19:41:58 +00:00
else if ( g_Config . m_BrFilterPw & & m_ppServerlist [ i ] - > m_Info . m_Flags & SERVER_FLAG_PASSWORD )
2011-06-26 15:10:13 +00:00
Filtered = 1 ;
2020-09-02 16:26:26 +00:00
else if ( g_Config . m_BrFilterPing & & g_Config . m_BrFilterPing < m_ppServerlist [ i ] - > m_Info . m_Latency )
2011-06-26 15:10:13 +00:00
Filtered = 1 ;
else if ( g_Config . m_BrFilterCompatversion & & str_comp_num ( m_ppServerlist [ i ] - > m_Info . m_aVersion , m_aNetVersion , 3 ) ! = 0 )
Filtered = 1 ;
else if ( g_Config . m_BrFilterServerAddress [ 0 ] & & ! str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aAddress , g_Config . m_BrFilterServerAddress ) )
Filtered = 1 ;
else if ( g_Config . m_BrFilterGametypeStrict & & g_Config . m_BrFilterGametype [ 0 ] & & str_comp_nocase ( m_ppServerlist [ i ] - > m_Info . m_aGameType , g_Config . m_BrFilterGametype ) )
Filtered = 1 ;
else if ( ! g_Config . m_BrFilterGametypeStrict & & g_Config . m_BrFilterGametype [ 0 ] & & ! str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aGameType , g_Config . m_BrFilterGametype ) )
Filtered = 1 ;
2019-05-11 11:45:41 +00:00
else if ( g_Config . m_BrFilterUnfinishedMap & & m_ppServerlist [ i ] - > m_Info . m_HasRank = = 1 )
2017-08-30 19:34:01 +00:00
Filtered = 1 ;
2011-06-29 20:27:32 +00:00
else
2011-06-26 15:10:13 +00:00
{
2011-06-29 20:27:32 +00:00
if ( g_Config . m_BrFilterCountry )
2011-06-26 15:10:13 +00:00
{
2011-06-29 20:27:32 +00:00
Filtered = 1 ;
// match against player country
2020-10-18 16:41:18 +00:00
for ( p = 0 ; p < minimum ( m_ppServerlist [ i ] - > m_Info . m_NumClients , ( int ) MAX_CLIENTS ) ; p + + )
2011-06-29 20:27:32 +00:00
{
if ( m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_Country = = g_Config . m_BrFilterCountryIndex )
{
Filtered = 0 ;
break ;
}
}
2011-06-26 15:10:13 +00:00
}
2011-03-18 18:03:13 +00:00
2011-06-29 20:27:32 +00:00
if ( ! Filtered & & g_Config . m_BrFilterString [ 0 ] ! = 0 )
2011-06-26 15:10:13 +00:00
{
2016-08-06 22:52:00 +00:00
int MatchFound = 0 ;
2011-06-29 20:27:32 +00:00
m_ppServerlist [ i ] - > m_Info . m_QuickSearchHit = 0 ;
2016-08-06 22:52:00 +00:00
// match against server name
if ( str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aName , g_Config . m_BrFilterString ) )
2011-03-23 12:06:35 +00:00
{
2016-08-06 22:52:00 +00:00
MatchFound = 1 ;
m_ppServerlist [ i ] - > m_Info . m_QuickSearchHit | = IServerBrowser : : QUICK_SERVERNAME ;
}
2016-08-02 20:16:02 +00:00
2016-08-06 22:52:00 +00:00
// match against players
2020-10-18 16:41:18 +00:00
for ( p = 0 ; p < minimum ( m_ppServerlist [ i ] - > m_Info . m_NumClients , ( int ) MAX_CLIENTS ) ; p + + )
2016-08-06 22:52:00 +00:00
{
if ( str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_aName , g_Config . m_BrFilterString ) | |
str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_aClan , g_Config . m_BrFilterString ) )
2016-08-02 20:16:02 +00:00
{
MatchFound = 1 ;
2016-08-06 22:52:00 +00:00
m_ppServerlist [ i ] - > m_Info . m_QuickSearchHit | = IServerBrowser : : QUICK_PLAYER ;
break ;
2016-08-02 20:16:02 +00:00
}
2016-08-06 22:52:00 +00:00
}
2011-06-29 20:27:32 +00:00
2016-08-06 22:52:00 +00:00
// match against map
if ( str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aMap , g_Config . m_BrFilterString ) )
{
MatchFound = 1 ;
m_ppServerlist [ i ] - > m_Info . m_QuickSearchHit | = IServerBrowser : : QUICK_MAPNAME ;
2016-08-02 20:16:02 +00:00
}
2016-08-06 22:52:00 +00:00
if ( ! MatchFound )
Filtered = 1 ;
2011-06-29 20:27:32 +00:00
}
2014-12-10 03:49:16 +00:00
if ( ! Filtered & & g_Config . m_BrExcludeString [ 0 ] ! = 0 )
{
2016-08-06 22:52:00 +00:00
int MatchFound = 0 ;
2014-12-10 03:49:16 +00:00
2016-08-06 22:52:00 +00:00
// match against server name
if ( str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aName , g_Config . m_BrExcludeString ) )
2014-12-10 03:49:16 +00:00
{
2016-08-06 22:52:00 +00:00
MatchFound = 1 ;
}
2014-12-10 03:49:16 +00:00
2016-08-06 22:52:00 +00:00
// match against map
if ( str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aMap , g_Config . m_BrExcludeString ) )
{
MatchFound = 1 ;
2016-08-02 20:16:02 +00:00
}
2019-03-05 09:46:29 +00:00
2017-08-30 21:55:02 +00:00
// match against gametype
if ( str_find_nocase ( m_ppServerlist [ i ] - > m_Info . m_aGameType , g_Config . m_BrExcludeString ) )
{
MatchFound = 1 ;
}
2016-08-06 22:52:00 +00:00
if ( MatchFound )
Filtered = 1 ;
2014-12-10 03:49:16 +00:00
}
2010-05-29 07:25:38 +00:00
}
if ( Filtered = = 0 )
2011-06-26 15:10:13 +00:00
{
// check for friend
m_ppServerlist [ i ] - > m_Info . m_FriendState = IFriends : : FRIEND_NO ;
2020-10-10 11:02:24 +00:00
for ( p = 0 ; p < minimum ( m_ppServerlist [ i ] - > m_Info . m_NumClients , ( int ) MAX_CLIENTS ) ; p + + )
2011-06-26 15:10:13 +00:00
{
m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_FriendState = m_pFriends - > GetFriendState ( m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_aName ,
m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_aClan ) ;
2019-04-26 19:36:49 +00:00
m_ppServerlist [ i ] - > m_Info . m_FriendState = maximum ( m_ppServerlist [ i ] - > m_Info . m_FriendState , m_ppServerlist [ i ] - > m_Info . m_aClients [ p ] . m_FriendState ) ;
2011-06-26 15:10:13 +00:00
}
if ( ! g_Config . m_BrFilterFriends | | m_ppServerlist [ i ] - > m_Info . m_FriendState ! = IFriends : : FRIEND_NO )
m_pSortedServerlist [ m_NumSortedServers + + ] = i ;
}
2010-05-29 07:25:38 +00:00
}
}
int CServerBrowser : : SortHash ( ) const
{
2020-09-26 19:33:36 +00:00
int i = g_Config . m_BrSort & 0xff ;
i | = g_Config . m_BrFilterEmpty < < 4 ;
i | = g_Config . m_BrFilterFull < < 5 ;
i | = g_Config . m_BrFilterSpectators < < 6 ;
i | = g_Config . m_BrFilterFriends < < 7 ;
i | = g_Config . m_BrFilterPw < < 8 ;
i | = g_Config . m_BrSortOrder < < 9 ;
i | = g_Config . m_BrFilterCompatversion < < 11 ;
i | = g_Config . m_BrFilterGametypeStrict < < 12 ;
i | = g_Config . m_BrFilterUnfinishedMap < < 13 ;
i | = g_Config . m_BrFilterCountry < < 14 ;
i | = g_Config . m_BrFilterConnectingPlayers < < 15 ;
2010-05-29 07:25:38 +00:00
return i ;
}
2018-10-29 21:03:57 +00:00
void SetFilteredPlayers ( const CServerInfo & Item )
{
2020-09-26 19:41:58 +00:00
if ( g_Config . m_BrFilterSpectators )
2019-10-31 13:16:35 +00:00
Item . m_NumFilteredPlayers = Item . m_NumPlayers ;
else
Item . m_NumFilteredPlayers = Item . m_NumClients ;
2020-09-26 19:41:58 +00:00
if ( g_Config . m_BrFilterConnectingPlayers )
2018-10-29 21:03:57 +00:00
{
2020-09-26 19:41:58 +00:00
for ( int i = 0 ; i < MAX_CLIENTS ; i + + )
2019-10-31 13:16:35 +00:00
{
const CServerInfo : : CClient & Client = Item . m_aClients [ i ] ;
2018-10-29 21:03:57 +00:00
2020-09-26 19:41:58 +00:00
if ( str_comp ( Client . m_aName , " (connecting) " ) = = 0 & & Client . m_aClan [ 0 ] = = ' \0 ' & & Client . m_Country = = - 1 & & Client . m_Score = = 0 )
2019-10-31 13:16:35 +00:00
Item . m_NumFilteredPlayers - - ;
}
2018-10-29 21:03:57 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CServerBrowser : : Sort ( )
{
int i ;
2018-10-29 21:03:57 +00:00
// fill m_NumFilteredPlayers
for ( i = 0 ; i < m_NumServers ; i + + )
{
SetFilteredPlayers ( m_ppServerlist [ i ] - > m_Info ) ;
}
2010-05-29 07:25:38 +00:00
// create filtered list
Filter ( ) ;
// sort
2020-09-26 19:41:58 +00:00
if ( g_Config . m_BrSortOrder = = 2 & & ( g_Config . m_BrSort = = IServerBrowser : : SORT_NUMPLAYERS | | g_Config . m_BrSort = = IServerBrowser : : SORT_PING ) )
std : : stable_sort ( m_pSortedServerlist , m_pSortedServerlist + m_NumSortedServers , SortWrap ( this , & CServerBrowser : : SortCompareNumPlayersAndPing ) ) ;
2020-08-24 21:23:37 +00:00
else if ( g_Config . m_BrSort = = IServerBrowser : : SORT_NAME )
2020-09-26 19:41:58 +00:00
std : : stable_sort ( m_pSortedServerlist , m_pSortedServerlist + m_NumSortedServers , SortWrap ( this , & CServerBrowser : : SortCompareName ) ) ;
2010-05-29 07:25:38 +00:00
else if ( g_Config . m_BrSort = = IServerBrowser : : SORT_PING )
2020-09-26 19:41:58 +00:00
std : : stable_sort ( m_pSortedServerlist , m_pSortedServerlist + m_NumSortedServers , SortWrap ( this , & CServerBrowser : : SortComparePing ) ) ;
2010-05-29 07:25:38 +00:00
else if ( g_Config . m_BrSort = = IServerBrowser : : SORT_MAP )
2020-09-26 19:41:58 +00:00
std : : stable_sort ( m_pSortedServerlist , m_pSortedServerlist + m_NumSortedServers , SortWrap ( this , & CServerBrowser : : SortCompareMap ) ) ;
2010-05-29 07:25:38 +00:00
else if ( g_Config . m_BrSort = = IServerBrowser : : SORT_NUMPLAYERS )
2020-09-26 19:41:58 +00:00
std : : stable_sort ( m_pSortedServerlist , m_pSortedServerlist + m_NumSortedServers , SortWrap ( this , & CServerBrowser : : SortCompareNumPlayers ) ) ;
2010-05-29 07:25:38 +00:00
else if ( g_Config . m_BrSort = = IServerBrowser : : SORT_GAMETYPE )
2020-09-26 19:41:58 +00:00
std : : stable_sort ( m_pSortedServerlist , m_pSortedServerlist + m_NumSortedServers , SortWrap ( this , & CServerBrowser : : SortCompareGametype ) ) ;
2010-05-29 07:25:38 +00:00
// set indexes
for ( i = 0 ; i < m_NumSortedServers ; i + + )
m_ppServerlist [ m_pSortedServerlist [ i ] ] - > m_Info . m_SortedIndex = i ;
str_copy ( m_aFilterGametypeString , g_Config . m_BrFilterGametype , sizeof ( m_aFilterGametypeString ) ) ;
str_copy ( m_aFilterString , g_Config . m_BrFilterString , sizeof ( m_aFilterString ) ) ;
m_Sorthash = SortHash ( ) ;
}
void CServerBrowser : : RemoveRequest ( CServerEntry * pEntry )
{
if ( pEntry - > m_pPrevReq | | pEntry - > m_pNextReq | | m_pFirstReqServer = = pEntry )
{
if ( pEntry - > m_pPrevReq )
pEntry - > m_pPrevReq - > m_pNextReq = pEntry - > m_pNextReq ;
else
m_pFirstReqServer = pEntry - > m_pNextReq ;
if ( pEntry - > m_pNextReq )
pEntry - > m_pNextReq - > m_pPrevReq = pEntry - > m_pPrevReq ;
else
m_pLastReqServer = pEntry - > m_pPrevReq ;
pEntry - > m_pPrevReq = 0 ;
pEntry - > m_pNextReq = 0 ;
m_NumRequests - - ;
}
}
CServerBrowser : : CServerEntry * CServerBrowser : : Find ( const NETADDR & Addr )
{
CServerEntry * pEntry = m_aServerlistIp [ Addr . ip [ 0 ] ] ;
for ( ; pEntry ; pEntry = pEntry - > m_pNextIp )
{
if ( net_addr_comp ( & pEntry - > m_Addr , & Addr ) = = 0 )
return pEntry ;
}
2020-09-26 19:41:58 +00:00
return ( CServerEntry * ) 0 ;
2010-05-29 07:25:38 +00:00
}
void CServerBrowser : : QueueRequest ( CServerEntry * pEntry )
{
// add it to the list of servers that we should request info from
pEntry - > m_pPrevReq = m_pLastReqServer ;
if ( m_pLastReqServer )
m_pLastReqServer - > m_pNextReq = pEntry ;
else
m_pFirstReqServer = pEntry ;
m_pLastReqServer = pEntry ;
2013-12-31 01:34:33 +00:00
pEntry - > m_pNextReq = 0 ;
2010-05-29 07:25:38 +00:00
m_NumRequests + + ;
}
void CServerBrowser : : SetInfo ( CServerEntry * pEntry , const CServerInfo & Info )
{
2019-03-19 06:46:48 +00:00
bool Fav = pEntry - > m_Info . m_Favorite ;
bool Off = pEntry - > m_Info . m_Official ;
2010-05-29 07:25:38 +00:00
pEntry - > m_Info = Info ;
pEntry - > m_Info . m_Favorite = Fav ;
2019-03-19 06:46:48 +00:00
pEntry - > m_Info . m_Official = Off ;
2010-05-29 07:25:38 +00:00
pEntry - > m_Info . m_NetAddr = pEntry - > m_Addr ;
2018-02-04 15:00:47 +00:00
// all these are just for nice compatibility
2010-05-29 07:25:38 +00:00
if ( pEntry - > m_Info . m_aGameType [ 0 ] = = ' 0 ' & & pEntry - > m_Info . m_aGameType [ 1 ] = = 0 )
str_copy ( pEntry - > m_Info . m_aGameType , " DM " , sizeof ( pEntry - > m_Info . m_aGameType ) ) ;
else if ( pEntry - > m_Info . m_aGameType [ 0 ] = = ' 1 ' & & pEntry - > m_Info . m_aGameType [ 1 ] = = 0 )
str_copy ( pEntry - > m_Info . m_aGameType , " TDM " , sizeof ( pEntry - > m_Info . m_aGameType ) ) ;
else if ( pEntry - > m_Info . m_aGameType [ 0 ] = = ' 2 ' & & pEntry - > m_Info . m_aGameType [ 1 ] = = 0 )
str_copy ( pEntry - > m_Info . m_aGameType , " CTF " , sizeof ( pEntry - > m_Info . m_aGameType ) ) ;
/*if(!request)
{
pEntry - > m_Info . latency = ( time_get ( ) - pEntry - > request_time ) * 1000 / time_freq ( ) ;
RemoveRequest ( pEntry ) ;
} */
pEntry - > m_GotInfo = 1 ;
}
CServerBrowser : : CServerEntry * CServerBrowser : : Add ( const NETADDR & Addr )
{
int Hash = Addr . ip [ 0 ] ;
CServerEntry * pEntry = 0 ;
int i ;
// create new pEntry
pEntry = ( CServerEntry * ) m_ServerlistHeap . Allocate ( sizeof ( CServerEntry ) ) ;
mem_zero ( pEntry , sizeof ( CServerEntry ) ) ;
// set the info
pEntry - > m_Addr = Addr ;
pEntry - > m_Info . m_NetAddr = Addr ;
pEntry - > m_Info . m_Latency = 999 ;
2017-08-30 19:34:01 +00:00
pEntry - > m_Info . m_HasRank = - 1 ;
2011-12-29 22:36:53 +00:00
net_addr_str ( & Addr , pEntry - > m_Info . m_aAddress , sizeof ( pEntry - > m_Info . m_aAddress ) , true ) ;
2011-03-30 10:08:33 +00:00
str_copy ( pEntry - > m_Info . m_aName , pEntry - > m_Info . m_aAddress , sizeof ( pEntry - > m_Info . m_aName ) ) ;
2010-05-29 07:25:38 +00:00
// check if it's a favorite
for ( i = 0 ; i < m_NumFavoriteServers ; i + + )
{
if ( net_addr_comp ( & Addr , & m_aFavoriteServers [ i ] ) = = 0 )
2019-03-19 06:46:48 +00:00
{
pEntry - > m_Info . m_Favorite = true ;
break ;
}
}
// check if it's an official server
2019-03-24 22:15:38 +00:00
for ( int Network = 0 ; Network < NUM_NETWORKS ; Network + + )
2019-03-19 06:46:48 +00:00
{
2019-03-24 22:15:38 +00:00
for ( int i = 0 ; i < m_aNetworks [ Network ] . m_NumCountries ; i + + )
2019-03-19 06:46:48 +00:00
{
2019-03-24 22:15:38 +00:00
CNetworkCountry * pCntr = & m_aNetworks [ Network ] . m_aCountries [ i ] ;
for ( int j = 0 ; j < pCntr - > m_NumServers ; j + + )
2019-03-19 06:46:48 +00:00
{
2019-03-24 22:15:38 +00:00
if ( net_addr_comp ( & Addr , & pCntr - > m_aServers [ j ] ) = = 0 )
{
pEntry - > m_Info . m_Official = true ;
break ;
}
2019-03-19 06:46:48 +00:00
}
}
2010-05-29 07:25:38 +00:00
}
// add to the hash list
pEntry - > m_pNextIp = m_aServerlistIp [ Hash ] ;
m_aServerlistIp [ Hash ] = pEntry ;
if ( m_NumServers = = m_NumServerCapacity )
{
CServerEntry * * ppNewlist ;
m_NumServerCapacity + = 100 ;
2018-04-09 09:56:39 +00:00
ppNewlist = ( CServerEntry * * ) calloc ( m_NumServerCapacity , sizeof ( CServerEntry * ) ) ;
2020-10-10 10:17:40 +00:00
if ( m_NumServers > 0 )
mem_copy ( ppNewlist , m_ppServerlist , m_NumServers * sizeof ( CServerEntry * ) ) ;
2018-04-09 09:56:39 +00:00
free ( m_ppServerlist ) ;
2010-05-29 07:25:38 +00:00
m_ppServerlist = ppNewlist ;
}
// add to list
m_ppServerlist [ m_NumServers ] = pEntry ;
pEntry - > m_Info . m_ServerIndex = m_NumServers ;
m_NumServers + + ;
return pEntry ;
}
void CServerBrowser : : Set ( const NETADDR & Addr , int Type , int Token , const CServerInfo * pInfo )
{
CServerEntry * pEntry = 0 ;
if ( Type = = IServerBrowser : : SET_MASTER_ADD )
{
if ( m_ServerlistType ! = IServerBrowser : : TYPE_INTERNET )
return ;
2013-12-31 01:34:33 +00:00
m_LastPacketTick = 0 ;
2010-05-29 07:25:38 +00:00
if ( ! Find ( Addr ) )
{
pEntry = Add ( Addr ) ;
QueueRequest ( pEntry ) ;
}
}
else if ( Type = = IServerBrowser : : SET_FAV_ADD )
{
if ( m_ServerlistType ! = IServerBrowser : : TYPE_FAVORITES )
return ;
if ( ! Find ( Addr ) )
{
pEntry = Add ( Addr ) ;
QueueRequest ( pEntry ) ;
}
}
2014-09-13 14:36:25 +00:00
else if ( Type = = IServerBrowser : : SET_DDNET_ADD )
{
if ( m_ServerlistType ! = IServerBrowser : : TYPE_DDNET )
return ;
if ( ! Find ( Addr ) )
{
pEntry = Add ( Addr ) ;
QueueRequest ( pEntry ) ;
}
}
2019-03-24 22:15:38 +00:00
else if ( Type = = IServerBrowser : : SET_KOG_ADD )
{
if ( m_ServerlistType ! = IServerBrowser : : TYPE_KOG )
return ;
if ( ! Find ( Addr ) )
{
pEntry = Add ( Addr ) ;
QueueRequest ( pEntry ) ;
}
}
2010-05-29 07:25:38 +00:00
else if ( Type = = IServerBrowser : : SET_TOKEN )
{
2017-10-14 19:58:23 +00:00
int BasicToken = Token ;
int ExtraToken = 0 ;
2017-03-29 10:56:13 +00:00
if ( pInfo - > m_Type = = SERVERINFO_EXTENDED )
{
2017-10-14 19:58:23 +00:00
BasicToken = Token & 0xff ;
ExtraToken = Token > > 8 ;
2017-03-29 10:56:13 +00:00
}
2010-05-29 07:25:38 +00:00
pEntry = Find ( Addr ) ;
2020-09-26 19:41:58 +00:00
2020-09-02 23:51:33 +00:00
if ( m_ServerlistType = = IServerBrowser : : TYPE_LAN )
{
NETADDR Broadcast ;
mem_zero ( & Broadcast , sizeof ( Broadcast ) ) ;
2020-09-26 19:41:58 +00:00
Broadcast . type = m_pNetClient - > NetType ( ) | NETTYPE_LINK_BROADCAST ;
2020-09-02 23:51:33 +00:00
int Token = GenerateToken ( Broadcast ) ;
bool Drop = false ;
Drop = Drop | | BasicToken ! = GetBasicToken ( Token ) ;
Drop = Drop | | ( pInfo - > m_Type = = SERVERINFO_EXTENDED & & ExtraToken ! = GetExtraToken ( Token ) ) ;
if ( Drop )
{
return ;
}
if ( ! pEntry )
pEntry = Add ( Addr ) ;
}
else
2017-03-29 10:56:13 +00:00
{
2017-10-14 19:58:23 +00:00
if ( ! pEntry )
{
return ;
}
int Token = GenerateToken ( Addr ) ;
bool Drop = false ;
Drop = Drop | | BasicToken ! = GetBasicToken ( Token ) ;
Drop = Drop | | ( pInfo - > m_Type = = SERVERINFO_EXTENDED & & ExtraToken ! = GetExtraToken ( Token ) ) ;
if ( Drop )
2017-03-29 10:56:13 +00:00
{
return ;
}
}
2020-09-26 19:41:58 +00:00
2020-09-02 23:51:33 +00:00
SetInfo ( pEntry , * pInfo ) ;
2020-09-26 19:41:58 +00:00
if ( m_ServerlistType = = IServerBrowser : : TYPE_LAN )
pEntry - > m_Info . m_Latency = minimum ( static_cast < int > ( ( time_get ( ) - m_BroadcastTime ) * 1000 / time_freq ( ) ) , 999 ) ;
else if ( pEntry - > m_RequestTime > 0 )
2010-05-29 07:25:38 +00:00
{
2020-09-26 19:41:58 +00:00
pEntry - > m_Info . m_Latency = minimum ( static_cast < int > ( ( time_get ( ) - pEntry - > m_RequestTime ) * 1000 / time_freq ( ) ) , 999 ) ;
2020-09-02 23:51:33 +00:00
pEntry - > m_RequestTime = - 1 ; // Request has been answered
2010-05-29 07:25:38 +00:00
}
2020-09-02 23:51:33 +00:00
RemoveRequest ( pEntry ) ;
2010-05-29 07:25:38 +00:00
}
Sort ( ) ;
}
void CServerBrowser : : Refresh ( int Type )
{
// clear out everything
m_ServerlistHeap . Reset ( ) ;
m_NumServers = 0 ;
m_NumSortedServers = 0 ;
mem_zero ( m_aServerlistIp , sizeof ( m_aServerlistIp ) ) ;
m_pFirstReqServer = 0 ;
m_pLastReqServer = 0 ;
m_NumRequests = 0 ;
2013-12-31 02:18:37 +00:00
m_CurrentMaxRequests = g_Config . m_BrMaxRequests ;
2017-10-14 19:58:23 +00:00
m_RequestNumber + + ;
2010-05-29 07:25:38 +00:00
m_ServerlistType = Type ;
2020-09-03 00:03:22 +00:00
secure_random_fill ( m_aTokenSeed , sizeof ( m_aTokenSeed ) ) ;
2010-05-29 07:25:38 +00:00
if ( Type = = IServerBrowser : : TYPE_LAN )
{
2020-09-26 19:41:58 +00:00
unsigned char Buffer [ sizeof ( SERVERBROWSE_GETINFO ) + 1 ] ;
2010-05-29 07:25:38 +00:00
CNetChunk Packet ;
int i ;
2011-03-28 18:11:28 +00:00
/* do the broadcast version */
2010-05-29 07:25:38 +00:00
Packet . m_ClientID = - 1 ;
mem_zero ( & Packet , sizeof ( Packet ) ) ;
2020-09-26 19:41:58 +00:00
Packet . m_Address . type = m_pNetClient - > NetType ( ) | NETTYPE_LINK_BROADCAST ;
Packet . m_Flags = NETSENDFLAG_CONNLESS | NETSENDFLAG_EXTENDED ;
2010-05-29 07:25:38 +00:00
Packet . m_DataSize = sizeof ( Buffer ) ;
Packet . m_pData = Buffer ;
2017-03-29 10:56:13 +00:00
mem_zero ( & Packet . m_aExtraData , sizeof ( Packet . m_aExtraData ) ) ;
2017-10-14 19:58:23 +00:00
int Token = GenerateToken ( Packet . m_Address ) ;
mem_copy ( Buffer , SERVERBROWSE_GETINFO , sizeof ( SERVERBROWSE_GETINFO ) ) ;
Buffer [ sizeof ( SERVERBROWSE_GETINFO ) ] = GetBasicToken ( Token ) ;
Packet . m_aExtraData [ 0 ] = GetExtraToken ( Token ) > > 8 ;
Packet . m_aExtraData [ 1 ] = GetExtraToken ( Token ) & 0xff ;
2010-05-29 07:25:38 +00:00
m_BroadcastTime = time_get ( ) ;
for ( i = 8303 ; i < = 8310 ; i + + )
{
Packet . m_Address . port = i ;
m_pNetClient - > Send ( & Packet ) ;
}
if ( g_Config . m_Debug )
2010-08-17 22:06:00 +00:00
m_pConsole - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " client_srvbrowse " , " broadcasting for servers " ) ;
2010-05-29 07:25:38 +00:00
}
else if ( Type = = IServerBrowser : : TYPE_INTERNET )
m_NeedRefresh = 1 ;
else if ( Type = = IServerBrowser : : TYPE_FAVORITES )
{
for ( int i = 0 ; i < m_NumFavoriteServers ; i + + )
Set ( m_aFavoriteServers [ i ] , IServerBrowser : : SET_FAV_ADD , - 1 , 0 ) ;
}
2014-09-13 14:36:25 +00:00
else if ( Type = = IServerBrowser : : TYPE_DDNET )
{
2014-09-19 21:52:09 +00:00
// remove unknown elements of exclude list
2019-03-24 22:15:38 +00:00
CountryFilterClean ( NETWORK_DDNET ) ;
TypeFilterClean ( NETWORK_DDNET ) ;
2014-12-14 15:45:18 +00:00
2020-08-30 10:24:13 +00:00
int MaxServers = 0 ;
2019-03-24 22:15:38 +00:00
for ( int i = 0 ; i < m_aNetworks [ NETWORK_DDNET ] . m_NumCountries ; i + + )
2014-09-19 21:52:09 +00:00
{
2019-03-24 22:15:38 +00:00
CNetworkCountry * pCntr = & m_aNetworks [ NETWORK_DDNET ] . m_aCountries [ i ] ;
2020-08-30 10:24:13 +00:00
MaxServers = maximum ( MaxServers , pCntr - > m_NumServers ) ;
}
2014-09-19 21:52:09 +00:00
2020-08-30 10:24:13 +00:00
for ( int g = 0 ; g < MaxServers ; g + + )
{
for ( int i = 0 ; i < m_aNetworks [ NETWORK_DDNET ] . m_NumCountries ; i + + )
2014-12-14 15:45:18 +00:00
{
2020-08-30 10:24:13 +00:00
CNetworkCountry * pCntr = & m_aNetworks [ NETWORK_DDNET ] . m_aCountries [ i ] ;
// check for filter
if ( DDNetFiltered ( g_Config . m_BrFilterExcludeCountries , pCntr - > m_aName ) )
continue ;
if ( g > = pCntr - > m_NumServers )
continue ;
2014-12-14 15:45:18 +00:00
if ( ! DDNetFiltered ( g_Config . m_BrFilterExcludeTypes , pCntr - > m_aTypes [ g ] ) )
Set ( pCntr - > m_aServers [ g ] , IServerBrowser : : SET_DDNET_ADD , - 1 , 0 ) ;
}
2014-09-19 21:52:09 +00:00
}
2014-09-13 14:36:25 +00:00
}
2019-03-24 22:15:38 +00:00
else if ( Type = = IServerBrowser : : TYPE_KOG )
{
// remove unknown elements of exclude list
CountryFilterClean ( NETWORK_KOG ) ;
TypeFilterClean ( NETWORK_KOG ) ;
2020-08-30 10:24:13 +00:00
int MaxServers = 0 ;
2019-03-24 22:15:38 +00:00
for ( int i = 0 ; i < m_aNetworks [ NETWORK_KOG ] . m_NumCountries ; i + + )
{
CNetworkCountry * pCntr = & m_aNetworks [ NETWORK_KOG ] . m_aCountries [ i ] ;
2020-08-30 10:24:13 +00:00
MaxServers = maximum ( MaxServers , pCntr - > m_NumServers ) ;
}
2019-03-24 22:15:38 +00:00
2020-08-30 10:24:13 +00:00
for ( int g = 0 ; g < MaxServers ; g + + )
{
for ( int i = 0 ; i < m_aNetworks [ NETWORK_KOG ] . m_NumCountries ; i + + )
2019-03-24 22:15:38 +00:00
{
2020-08-30 10:24:13 +00:00
CNetworkCountry * pCntr = & m_aNetworks [ NETWORK_KOG ] . m_aCountries [ i ] ;
// check for filter
if ( DDNetFiltered ( g_Config . m_BrFilterExcludeCountriesKoG , pCntr - > m_aName ) )
continue ;
if ( g > = pCntr - > m_NumServers )
continue ;
2019-03-24 22:15:38 +00:00
if ( ! DDNetFiltered ( g_Config . m_BrFilterExcludeTypesKoG , pCntr - > m_aTypes [ g ] ) )
Set ( pCntr - > m_aServers [ g ] , IServerBrowser : : SET_KOG_ADD , - 1 , 0 ) ;
}
}
}
2010-05-29 07:25:38 +00:00
}
void CServerBrowser : : RequestImpl ( const NETADDR & Addr , CServerEntry * pEntry ) const
{
2020-09-26 19:41:58 +00:00
unsigned char Buffer [ sizeof ( SERVERBROWSE_GETINFO ) + 1 ] ;
2010-05-29 07:25:38 +00:00
CNetChunk Packet ;
if ( g_Config . m_Debug )
{
2011-03-30 10:08:33 +00:00
char aAddrStr [ NETADDR_MAXSTRSIZE ] ;
2011-12-29 22:36:53 +00:00
net_addr_str ( & Addr , aAddrStr , sizeof ( aAddrStr ) , true ) ;
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2020-09-26 19:41:58 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " requesting server info from %s " , aAddrStr ) ;
2010-08-17 22:06:00 +00:00
m_pConsole - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " client_srvbrowse " , aBuf ) ;
2010-05-29 07:25:38 +00:00
}
2017-10-14 19:58:23 +00:00
int Token = GenerateToken ( Addr ) ;
2010-12-26 01:37:22 +00:00
mem_copy ( Buffer , SERVERBROWSE_GETINFO , sizeof ( SERVERBROWSE_GETINFO ) ) ;
2017-10-14 19:58:23 +00:00
Buffer [ sizeof ( SERVERBROWSE_GETINFO ) ] = GetBasicToken ( Token ) ;
2010-05-29 07:25:38 +00:00
Packet . m_ClientID = - 1 ;
Packet . m_Address = Addr ;
2020-09-26 19:41:58 +00:00
Packet . m_Flags = NETSENDFLAG_CONNLESS | NETSENDFLAG_EXTENDED ;
2010-12-26 01:37:22 +00:00
Packet . m_DataSize = sizeof ( Buffer ) ;
Packet . m_pData = Buffer ;
2017-03-29 10:56:13 +00:00
mem_zero ( & Packet . m_aExtraData , sizeof ( Packet . m_aExtraData ) ) ;
2017-10-14 19:58:23 +00:00
Packet . m_aExtraData [ 0 ] = GetExtraToken ( Token ) > > 8 ;
Packet . m_aExtraData [ 1 ] = GetExtraToken ( Token ) & 0xff ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
m_pNetClient - > Send ( & Packet ) ;
if ( pEntry )
pEntry - > m_RequestTime = time_get ( ) ;
}
2014-01-08 05:15:56 +00:00
void CServerBrowser : : RequestImpl64 ( const NETADDR & Addr , CServerEntry * pEntry ) const
{
2020-09-26 19:41:58 +00:00
unsigned char Buffer [ sizeof ( SERVERBROWSE_GETINFO_64_LEGACY ) + 1 ] ;
2014-01-08 05:15:56 +00:00
CNetChunk Packet ;
if ( g_Config . m_Debug )
{
char aAddrStr [ NETADDR_MAXSTRSIZE ] ;
net_addr_str ( & Addr , aAddrStr , sizeof ( aAddrStr ) , true ) ;
char aBuf [ 256 ] ;
2020-09-26 19:41:58 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " requesting server info 64 from %s " , aAddrStr ) ;
2014-01-08 05:15:56 +00:00
m_pConsole - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " client_srvbrowse " , aBuf ) ;
}
2017-03-29 10:56:13 +00:00
mem_copy ( Buffer , SERVERBROWSE_GETINFO_64_LEGACY , sizeof ( SERVERBROWSE_GETINFO_64_LEGACY ) ) ;
2017-10-14 19:58:23 +00:00
Buffer [ sizeof ( SERVERBROWSE_GETINFO_64_LEGACY ) ] = GetBasicToken ( GenerateToken ( Addr ) ) ;
2014-01-08 05:15:56 +00:00
Packet . m_ClientID = - 1 ;
Packet . m_Address = Addr ;
Packet . m_Flags = NETSENDFLAG_CONNLESS ;
Packet . m_DataSize = sizeof ( Buffer ) ;
Packet . m_pData = Buffer ;
m_pNetClient - > Send ( & Packet ) ;
if ( pEntry )
pEntry - > m_RequestTime = time_get ( ) ;
}
2017-03-29 10:56:13 +00:00
void CServerBrowser : : RequestCurrentServer ( const NETADDR & Addr ) const
2010-05-29 07:25:38 +00:00
{
2014-01-11 02:53:50 +00:00
RequestImpl ( Addr , 0 ) ;
2010-05-29 07:25:38 +00:00
}
2011-03-18 18:03:13 +00:00
void CServerBrowser : : Update ( bool ForceResort )
2015-07-09 00:08:14 +00:00
{
2011-03-30 10:08:33 +00:00
int64 Timeout = time_freq ( ) ;
2010-05-29 07:25:38 +00:00
int64 Now = time_get ( ) ;
int Count ;
CServerEntry * pEntry , * pNext ;
2015-07-09 00:08:14 +00:00
2010-05-29 07:25:38 +00:00
// do server list requests
if ( m_NeedRefresh & & ! m_pMasterServer - > IsRefreshing ( ) )
{
NETADDR Addr ;
2015-07-09 00:08:14 +00:00
CNetChunk Packet ;
2013-12-31 01:34:33 +00:00
int i = 0 ;
2010-05-29 07:25:38 +00:00
m_NeedRefresh = 0 ;
2013-12-31 01:34:33 +00:00
m_MasterServerCount = - 1 ;
mem_zero ( & Packet , sizeof ( Packet ) ) ;
Packet . m_ClientID = - 1 ;
Packet . m_Flags = NETSENDFLAG_CONNLESS ;
Packet . m_DataSize = sizeof ( SERVERBROWSE_GETCOUNT ) ;
Packet . m_pData = SERVERBROWSE_GETCOUNT ;
for ( i = 0 ; i < IMasterServer : : MAX_MASTERSERVERS ; i + + )
{
if ( ! m_pMasterServer - > IsValid ( i ) )
continue ;
2010-05-29 07:25:38 +00:00
2013-12-31 01:34:33 +00:00
Addr = m_pMasterServer - > GetAddr ( i ) ;
m_pMasterServer - > SetCount ( i , - 1 ) ;
Packet . m_Address = Addr ;
2014-01-03 15:14:41 +00:00
m_pNetClient - > Send ( & Packet ) ;
2013-12-31 02:18:37 +00:00
if ( g_Config . m_Debug )
2014-12-14 15:45:18 +00:00
{
2016-05-02 19:35:32 +00:00
dbg_msg ( " client_srvbrowse " , " count-request sent to %d " , i ) ;
2014-12-14 15:45:18 +00:00
}
2013-12-31 01:34:33 +00:00
}
2014-12-14 15:45:18 +00:00
}
2013-12-31 01:34:33 +00:00
//Check if all server counts arrived
if ( m_MasterServerCount = = - 1 )
2015-07-09 00:08:14 +00:00
{
2013-12-31 01:34:33 +00:00
m_MasterServerCount = 0 ;
for ( int i = 0 ; i < IMasterServer : : MAX_MASTERSERVERS ; i + + )
2020-09-26 19:41:58 +00:00
{
if ( ! m_pMasterServer - > IsValid ( i ) )
continue ;
int Count = m_pMasterServer - > GetCount ( i ) ;
if ( Count = = - 1 )
2015-07-09 00:08:14 +00:00
{
2014-01-03 15:14:41 +00:00
/* ignore Server
2013-12-31 01:34:33 +00:00
m_MasterServerCount = - 1 ;
2014-01-03 15:14:41 +00:00
return ;
// we don't have the required server information
*/
2013-12-31 01:34:33 +00:00
}
2020-09-26 19:41:58 +00:00
else
m_MasterServerCount + = Count ;
}
2013-12-31 01:34:33 +00:00
//request Server-List
NETADDR Addr ;
2014-05-17 14:15:01 +00:00
CNetChunk Packet ;
2010-05-29 07:25:38 +00:00
mem_zero ( & Packet , sizeof ( Packet ) ) ;
Packet . m_ClientID = - 1 ;
Packet . m_Flags = NETSENDFLAG_CONNLESS ;
Packet . m_DataSize = sizeof ( SERVERBROWSE_GETLIST ) ;
Packet . m_pData = SERVERBROWSE_GETLIST ;
2013-12-31 01:34:33 +00:00
for ( int i = 0 ; i < IMasterServer : : MAX_MASTERSERVERS ; i + + )
2010-05-29 07:25:38 +00:00
{
2011-03-30 10:08:33 +00:00
if ( ! m_pMasterServer - > IsValid ( i ) )
2010-05-29 07:25:38 +00:00
continue ;
2011-03-30 10:08:33 +00:00
Addr = m_pMasterServer - > GetAddr ( i ) ;
2010-05-29 07:25:38 +00:00
Packet . m_Address = Addr ;
m_pNetClient - > Send ( & Packet ) ;
}
if ( g_Config . m_Debug )
2013-12-31 02:18:37 +00:00
{
2016-05-02 19:35:32 +00:00
dbg_msg ( " client_srvbrowse " , " servercount: %d, requesting server list " , m_MasterServerCount ) ;
2013-12-31 02:18:37 +00:00
}
2013-12-31 01:34:33 +00:00
m_LastPacketTick = 0 ;
2014-01-03 15:14:41 +00:00
}
else if ( m_MasterServerCount > - 1 )
{
m_MasterServerCount = 0 ;
for ( int i = 0 ; i < IMasterServer : : MAX_MASTERSERVERS ; i + + )
2020-09-26 19:41:58 +00:00
{
if ( ! m_pMasterServer - > IsValid ( i ) )
continue ;
int Count = m_pMasterServer - > GetCount ( i ) ;
if ( Count = = - 1 )
2015-07-09 00:08:14 +00:00
{
2014-01-03 15:14:41 +00:00
/* ignore Server
m_MasterServerCount = - 1 ;
return ;
// we don't have the required server information
*/
}
2020-09-26 19:41:58 +00:00
else
m_MasterServerCount + = Count ;
}
//if(g_Config.m_Debug)
//{
// dbg_msg("client_srvbrowse", "ServerCount2: %d", m_MasterServerCount);
//}
2014-01-03 15:14:41 +00:00
}
2020-09-26 19:41:58 +00:00
if ( m_MasterServerCount > m_NumRequests + m_LastPacketTick )
2010-05-29 07:25:38 +00:00
{
2013-12-31 01:34:33 +00:00
+ + m_LastPacketTick ;
return ; //wait for more packets
2010-05-29 07:25:38 +00:00
}
pEntry = m_pFirstReqServer ;
Count = 0 ;
while ( 1 )
{
if ( ! pEntry ) // no more entries
break ;
2020-09-26 19:41:58 +00:00
if ( pEntry - > m_RequestTime & & pEntry - > m_RequestTime + Timeout < Now )
2013-12-31 01:34:33 +00:00
{
pEntry = pEntry - > m_pNextReq ;
continue ;
}
2020-09-17 15:41:13 +00:00
// no more than 10 concurrent requests
2013-12-31 01:34:33 +00:00
if ( Count = = m_CurrentMaxRequests )
2010-05-29 07:25:38 +00:00
break ;
if ( pEntry - > m_RequestTime = = 0 )
2014-01-08 05:15:56 +00:00
{
2020-09-26 19:41:58 +00:00
if ( pEntry - > m_Request64Legacy )
2014-01-11 20:38:50 +00:00
RequestImpl64 ( pEntry - > m_Addr , pEntry ) ;
2014-01-14 20:40:55 +00:00
else
RequestImpl ( pEntry - > m_Addr , pEntry ) ;
2014-01-08 05:15:56 +00:00
}
2010-05-29 07:25:38 +00:00
Count + + ;
pEntry = pEntry - > m_pNextReq ;
}
2015-07-09 00:08:14 +00:00
2013-12-31 01:34:33 +00:00
if ( m_pFirstReqServer & & Count = = 0 & & m_CurrentMaxRequests > 1 ) //NO More current Server Requests
{
//reset old ones
pEntry = m_pFirstReqServer ;
while ( 1 )
{
if ( ! pEntry ) // no more entries
break ;
2015-07-09 00:08:14 +00:00
pEntry - > m_RequestTime = 0 ;
pEntry = pEntry - > m_pNextReq ;
2013-12-31 01:34:33 +00:00
}
2015-07-09 00:08:14 +00:00
2013-12-31 01:34:33 +00:00
//update max-requests
2020-09-26 19:41:58 +00:00
m_CurrentMaxRequests = m_CurrentMaxRequests / 2 ;
2013-12-31 02:18:37 +00:00
if ( m_CurrentMaxRequests < 1 )
m_CurrentMaxRequests = 1 ;
2013-12-31 01:34:33 +00:00
}
else if ( Count = = 0 & & m_CurrentMaxRequests = = 1 ) //we reached the limit, just release all left requests. IF a server sends us a packet, a new request will be added automatically, so we can delete all
2015-07-09 00:08:14 +00:00
{
2013-12-31 01:34:33 +00:00
pEntry = m_pFirstReqServer ;
while ( 1 )
{
if ( ! pEntry ) // no more entries
2015-07-09 00:08:14 +00:00
break ;
pNext = pEntry - > m_pNextReq ;
2020-09-26 19:41:58 +00:00
RemoveRequest ( pEntry ) ; //release request
2013-12-31 01:34:33 +00:00
pEntry = pNext ;
2014-01-03 15:14:41 +00:00
}
}
2015-07-09 00:08:14 +00:00
2010-05-29 07:25:38 +00:00
// check if we need to resort
2011-03-18 18:03:13 +00:00
if ( m_Sorthash ! = SortHash ( ) | | ForceResort )
2010-05-29 07:25:38 +00:00
Sort ( ) ;
}
bool CServerBrowser : : IsFavorite ( const NETADDR & Addr ) const
{
// search for the address
int i ;
for ( i = 0 ; i < m_NumFavoriteServers ; i + + )
{
if ( net_addr_comp ( & Addr , & m_aFavoriteServers [ i ] ) = = 0 )
return true ;
}
return false ;
}
void CServerBrowser : : AddFavorite ( const NETADDR & Addr )
{
CServerEntry * pEntry ;
if ( m_NumFavoriteServers = = MAX_FAVORITES )
return ;
// make sure that we don't already have the server in our list
for ( int i = 0 ; i < m_NumFavoriteServers ; i + + )
{
if ( net_addr_comp ( & Addr , & m_aFavoriteServers [ i ] ) = = 0 )
return ;
}
// add the server to the list
m_aFavoriteServers [ m_NumFavoriteServers + + ] = Addr ;
pEntry = Find ( Addr ) ;
if ( pEntry )
2019-03-19 06:46:48 +00:00
pEntry - > m_Info . m_Favorite = true ;
2010-05-29 07:25:38 +00:00
2011-04-13 18:37:12 +00:00
if ( g_Config . m_Debug )
2010-08-17 22:06:00 +00:00
{
2011-03-30 10:08:33 +00:00
char aAddrStr [ NETADDR_MAXSTRSIZE ] ;
2011-12-29 22:36:53 +00:00
net_addr_str ( & Addr , aAddrStr , sizeof ( aAddrStr ) , true ) ;
2010-08-17 22:06:00 +00:00
char aBuf [ 256 ] ;
2011-03-30 10:08:33 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " added fav, %s " , aAddrStr ) ;
2010-08-17 22:06:00 +00:00
m_pConsole - > Print ( IConsole : : OUTPUT_LEVEL_DEBUG , " client_srvbrowse " , aBuf ) ;
}
2010-05-29 07:25:38 +00:00
}
void CServerBrowser : : RemoveFavorite ( const NETADDR & Addr )
{
int i ;
CServerEntry * pEntry ;
for ( i = 0 ; i < m_NumFavoriteServers ; i + + )
{
if ( net_addr_comp ( & Addr , & m_aFavoriteServers [ i ] ) = = 0 )
{
2020-09-26 19:41:58 +00:00
mem_move ( & m_aFavoriteServers [ i ] , & m_aFavoriteServers [ i + 1 ] , sizeof ( NETADDR ) * ( m_NumFavoriteServers - ( i + 1 ) ) ) ;
2010-05-29 07:25:38 +00:00
m_NumFavoriteServers - - ;
pEntry = Find ( Addr ) ;
if ( pEntry )
2019-03-19 06:46:48 +00:00
pEntry - > m_Info . m_Favorite = false ;
2010-05-29 07:25:38 +00:00
return ;
}
}
}
2017-08-30 19:34:01 +00:00
void CServerBrowser : : LoadDDNetServers ( )
2014-09-13 14:36:25 +00:00
{
2020-09-26 19:41:58 +00:00
if ( ! m_pDDNetInfo )
2017-09-03 15:36:51 +00:00
return ;
2014-09-18 14:13:06 +00:00
// reset servers / countries
2020-09-26 19:41:58 +00:00
for ( int Network = 0 ; Network < NUM_NETWORKS ; Network + + )
2017-09-03 15:36:51 +00:00
{
2019-03-24 22:15:38 +00:00
CNetwork * pNet = & m_aNetworks [ Network ] ;
2015-07-09 00:08:14 +00:00
2019-03-24 22:15:38 +00:00
// parse JSON
const json_value * pServers = json_object_get ( m_pDDNetInfo , Network = = NETWORK_DDNET ? " servers " : " servers-kog " ) ;
2014-09-13 14:36:25 +00:00
2020-09-26 19:41:58 +00:00
if ( ! pServers | | pServers - > type ! = json_array )
2019-03-24 22:15:38 +00:00
return ;
2014-09-13 14:36:25 +00:00
2019-03-24 22:15:38 +00:00
pNet - > m_NumCountries = 0 ;
pNet - > m_NumTypes = 0 ;
2017-09-03 15:36:51 +00:00
2020-09-26 19:41:58 +00:00
for ( int i = 0 ; i < json_array_length ( pServers ) & & pNet - > m_NumCountries < MAX_COUNTRIES ; i + + )
2014-09-13 14:36:25 +00:00
{
2019-03-24 22:15:38 +00:00
// pSrv - { name, flagId, servers }
const json_value * pSrv = json_array_get ( pServers , i ) ;
const json_value * pTypes = json_object_get ( pSrv , " servers " ) ;
const json_value * pName = json_object_get ( pSrv , " name " ) ;
const json_value * pFlagID = json_object_get ( pSrv , " flagId " ) ;
2017-07-08 11:38:27 +00:00
2020-09-26 19:41:58 +00:00
if ( pSrv - > type ! = json_object | | pTypes - > type ! = json_object | | pName - > type ! = json_string | | pFlagID - > type ! = json_integer )
2014-09-13 14:36:25 +00:00
{
2017-07-08 11:38:27 +00:00
dbg_msg ( " client_srvbrowse " , " invalid attributes " ) ;
continue ;
}
2014-09-19 21:52:09 +00:00
2019-03-24 22:15:38 +00:00
// build structure
CNetworkCountry * pCntr = & pNet - > m_aCountries [ pNet - > m_NumCountries ] ;
pCntr - > Reset ( ) ;
str_copy ( pCntr - > m_aName , json_string_get ( pName ) , sizeof ( pCntr - > m_aName ) ) ;
pCntr - > m_FlagID = json_int_get ( pFlagID ) ;
// add country
2020-09-26 19:41:58 +00:00
for ( unsigned int t = 0 ; t < pTypes - > u . object . length ; t + + )
2017-07-08 11:38:27 +00:00
{
2019-03-24 22:15:38 +00:00
const char * pType = pTypes - > u . object . values [ t ] . name ;
const json_value * pAddrs = pTypes - > u . object . values [ t ] . value ;
2020-09-26 19:41:58 +00:00
if ( pAddrs - > type ! = json_array )
2014-09-18 14:13:06 +00:00
{
2019-03-24 22:15:38 +00:00
dbg_msg ( " client_srvbrowse " , " invalid attributes " ) ;
continue ;
2014-09-18 14:13:06 +00:00
}
2019-03-24 22:15:38 +00:00
// add type
if ( json_array_length ( pAddrs ) > 0 & & pNet - > m_NumTypes < MAX_TYPES )
2017-07-08 11:38:27 +00:00
{
2019-03-24 22:15:38 +00:00
int Pos ;
for ( Pos = 0 ; Pos < pNet - > m_NumTypes ; Pos + + )
{
if ( ! str_comp ( pNet - > m_aTypes [ Pos ] , pType ) )
break ;
}
if ( Pos = = pNet - > m_NumTypes )
{
str_copy ( pNet - > m_aTypes [ pNet - > m_NumTypes ] , pType , sizeof ( pNet - > m_aTypes [ pNet - > m_NumTypes ] ) ) ;
pNet - > m_NumTypes + + ;
}
2017-07-08 11:38:27 +00:00
}
2014-12-02 12:36:27 +00:00
2019-03-24 22:15:38 +00:00
// add addresses
2020-09-26 19:41:58 +00:00
for ( int g = 0 ; g < json_array_length ( pAddrs ) ; g + + , pCntr - > m_NumServers + + )
2017-09-03 15:36:51 +00:00
{
2019-03-24 22:15:38 +00:00
const json_value * pAddr = json_array_get ( pAddrs , g ) ;
2020-09-26 19:41:58 +00:00
if ( pAddr - > type ! = json_string )
2019-03-24 22:15:38 +00:00
{
dbg_msg ( " client_srvbrowse " , " invalid attributes " ) ;
continue ;
}
const char * pStr = json_string_get ( pAddr ) ;
net_addr_from_str ( & pCntr - > m_aServers [ pCntr - > m_NumServers ] , pStr ) ;
str_copy ( pCntr - > m_aTypes [ pCntr - > m_NumServers ] , pType , sizeof ( pCntr - > m_aTypes [ pCntr - > m_NumServers ] ) ) ;
2017-09-03 15:36:51 +00:00
}
}
2017-07-08 11:38:27 +00:00
2019-03-24 22:15:38 +00:00
pNet - > m_NumCountries + + ;
}
2017-09-03 15:36:51 +00:00
}
2014-09-13 14:36:25 +00:00
}
2019-03-19 06:57:09 +00:00
void CServerBrowser : : RecheckOfficial ( )
{
2019-03-24 22:15:38 +00:00
for ( int Network = 0 ; Network < NUM_NETWORKS ; Network + + )
2019-03-19 06:57:09 +00:00
{
2019-03-24 22:15:38 +00:00
for ( int i = 0 ; i < m_aNetworks [ Network ] . m_NumCountries ; i + + )
2019-03-19 06:57:09 +00:00
{
2019-03-24 22:15:38 +00:00
CNetworkCountry * pCntr = & m_aNetworks [ Network ] . m_aCountries [ i ] ;
for ( int j = 0 ; j < pCntr - > m_NumServers ; j + + )
2019-03-19 06:57:09 +00:00
{
2019-03-24 22:15:38 +00:00
CServerEntry * pEntry = Find ( pCntr - > m_aServers [ j ] ) ;
if ( pEntry )
{
pEntry - > m_Info . m_Official = true ;
}
2019-03-19 06:57:09 +00:00
}
}
}
}
2017-08-30 19:34:01 +00:00
void CServerBrowser : : LoadDDNetRanks ( )
{
2017-09-03 15:36:51 +00:00
for ( int i = 0 ; i < m_NumServers ; i + + )
{
if ( m_ppServerlist [ i ] - > m_Info . m_aMap [ 0 ] )
m_ppServerlist [ i ] - > m_Info . m_HasRank = HasRank ( m_ppServerlist [ i ] - > m_Info . m_aMap ) ;
}
}
int CServerBrowser : : HasRank ( const char * pMap )
{
if ( m_ServerlistType ! = IServerBrowser : : TYPE_DDNET | | ! m_pDDNetInfo )
return - 1 ;
const json_value * pDDNetRanks = json_object_get ( m_pDDNetInfo , " maps " ) ;
if ( ! pDDNetRanks | | pDDNetRanks - > type ! = json_array )
return - 1 ;
2020-09-26 19:41:58 +00:00
for ( int i = 0 ; i < json_array_length ( pDDNetRanks ) ; i + + )
2017-09-03 15:36:51 +00:00
{
const json_value * pJson = json_array_get ( pDDNetRanks , i ) ;
if ( ! pJson | | pJson - > type ! = json_string )
continue ;
const char * pStr = json_string_get ( pJson ) ;
if ( str_comp ( pMap , pStr ) = = 0 )
return 1 ;
}
return 0 ;
}
void CServerBrowser : : LoadDDNetInfoJson ( )
{
2017-08-30 19:34:01 +00:00
IStorage * pStorage = Kernel ( ) - > RequestInterface < IStorage > ( ) ;
2018-08-23 07:57:35 +00:00
IOHANDLE File = pStorage - > OpenFile ( DDNET_INFO , IOFLAG_READ , IStorage : : TYPE_SAVE ) ;
2017-08-30 19:34:01 +00:00
if ( ! File )
return ;
const int Length = io_length ( File ) ;
2017-08-30 22:07:59 +00:00
if ( Length < = 0 )
{
io_close ( File ) ;
return ;
}
2018-04-09 09:56:39 +00:00
char * pBuf = ( char * ) malloc ( Length ) ;
2017-08-30 19:34:01 +00:00
pBuf [ 0 ] = ' \0 ' ;
io_read ( File , pBuf , Length ) ;
io_close ( File ) ;
2017-09-03 15:36:51 +00:00
if ( m_pDDNetInfo )
json_value_free ( m_pDDNetInfo ) ;
m_pDDNetInfo = json_parse ( pBuf , Length ) ;
2017-08-30 19:34:01 +00:00
2018-04-09 09:56:39 +00:00
free ( pBuf ) ;
2017-08-30 19:34:01 +00:00
2017-09-20 20:25:55 +00:00
if ( m_pDDNetInfo & & m_pDDNetInfo - > type ! = json_object )
2017-08-30 19:34:01 +00:00
{
2017-09-03 15:36:51 +00:00
json_value_free ( m_pDDNetInfo ) ;
m_pDDNetInfo = 0 ;
2017-08-30 19:34:01 +00:00
}
}
2017-09-03 15:36:51 +00:00
const json_value * CServerBrowser : : LoadDDNetInfo ( )
2017-08-30 19:34:01 +00:00
{
2017-09-03 15:36:51 +00:00
LoadDDNetInfoJson ( ) ;
LoadDDNetServers ( ) ;
2017-08-30 19:34:01 +00:00
2017-09-03 15:36:51 +00:00
if ( m_NumServers = = 0 )
2019-03-19 06:57:09 +00:00
{
2017-09-03 15:36:51 +00:00
Refresh ( m_ServerlistType ) ;
2019-03-19 06:57:09 +00:00
}
2017-09-03 15:36:51 +00:00
else
2019-03-19 06:57:09 +00:00
{
RecheckOfficial ( ) ;
2017-09-03 15:36:51 +00:00
LoadDDNetRanks ( ) ;
2019-03-19 06:57:09 +00:00
}
2017-08-30 19:34:01 +00:00
2017-09-03 15:36:51 +00:00
return m_pDDNetInfo ;
2017-08-30 19:34:01 +00:00
}
2010-11-17 11:43:24 +00:00
bool CServerBrowser : : IsRefreshing ( ) const
{
return m_pFirstReqServer ! = 0 ;
}
2010-05-29 07:25:38 +00:00
bool CServerBrowser : : IsRefreshingMasters ( ) const
{
return m_pMasterServer - > IsRefreshing ( ) ;
}
2010-10-30 16:56:57 +00:00
int CServerBrowser : : LoadingProgression ( ) const
{
if ( m_NumServers = = 0 )
return 0 ;
2011-04-13 18:37:12 +00:00
2010-10-30 16:56:57 +00:00
int Servers = m_NumServers ;
2020-09-26 19:41:58 +00:00
int Loaded = m_NumServers - m_NumRequests ;
return 100.0f * Loaded / Servers ;
2010-10-30 16:56:57 +00:00
}
2010-05-29 07:25:38 +00:00
void CServerBrowser : : ConfigSaveCallback ( IConfig * pConfig , void * pUserData )
{
CServerBrowser * pSelf = ( CServerBrowser * ) pUserData ;
char aAddrStr [ 128 ] ;
char aBuffer [ 256 ] ;
2011-12-29 22:36:53 +00:00
for ( int i = 0 ; i < pSelf - > m_NumFavoriteServers ; i + + )
2010-05-29 07:25:38 +00:00
{
2011-12-29 22:36:53 +00:00
net_addr_str ( & pSelf - > m_aFavoriteServers [ i ] , aAddrStr , sizeof ( aAddrStr ) , true ) ;
2010-05-29 07:25:38 +00:00
str_format ( aBuffer , sizeof ( aBuffer ) , " add_favorite %s " , aAddrStr ) ;
pConfig - > WriteLine ( aBuffer ) ;
}
}
2014-09-19 21:52:09 +00:00
2014-12-14 15:45:18 +00:00
void CServerBrowser : : DDNetFilterAdd ( char * pFilter , const char * pName )
2014-09-19 21:52:09 +00:00
{
2020-09-26 19:41:58 +00:00
if ( DDNetFiltered ( pFilter , pName ) )
2014-09-19 21:52:09 +00:00
return ;
2015-07-09 00:08:14 +00:00
2014-12-14 15:45:18 +00:00
char aBuf [ 128 ] ;
2014-09-19 21:52:09 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " ,%s " , pName ) ;
2014-12-14 15:45:18 +00:00
str_append ( pFilter , aBuf , 128 ) ;
2014-09-19 21:52:09 +00:00
}
2014-12-14 15:45:18 +00:00
void CServerBrowser : : DDNetFilterRem ( char * pFilter , const char * pName )
2014-09-19 21:52:09 +00:00
{
2020-09-26 19:41:58 +00:00
if ( ! DDNetFiltered ( pFilter , pName ) )
2014-09-19 21:52:09 +00:00
return ;
// rewrite exclude/filter list
2014-12-14 15:45:18 +00:00
char aBuf [ 128 ] ;
2014-09-19 21:52:09 +00:00
2014-12-14 15:45:18 +00:00
str_copy ( aBuf , pFilter , sizeof ( aBuf ) ) ;
pFilter [ 0 ] = ' \0 ' ;
2014-09-19 21:52:09 +00:00
2019-03-05 09:46:29 +00:00
char aToken [ 128 ] ;
2019-03-11 11:54:31 +00:00
for ( const char * tok = aBuf ; ( tok = str_next_token ( tok , " , " , aToken , sizeof ( aToken ) ) ) ; )
2014-09-19 21:52:09 +00:00
{
2019-03-05 09:46:29 +00:00
if ( str_comp_nocase ( pName , aToken ) ! = 0 )
2014-09-19 21:52:09 +00:00
{
2014-12-14 15:45:18 +00:00
char aBuf2 [ 128 ] ;
2019-03-05 09:46:29 +00:00
str_format ( aBuf2 , sizeof ( aBuf2 ) , " ,%s " , aToken ) ;
2014-12-14 15:45:18 +00:00
str_append ( pFilter , aBuf2 , 128 ) ;
2014-09-19 21:52:09 +00:00
}
2019-03-11 11:39:54 +00:00
}
2014-09-19 21:52:09 +00:00
}
2014-12-14 15:45:18 +00:00
bool CServerBrowser : : DDNetFiltered ( char * pFilter , const char * pName )
2014-09-19 21:52:09 +00:00
{
2019-03-05 09:46:29 +00:00
return str_in_list ( pFilter , " , " , pName ) ; // country not excluded
2014-09-19 21:52:09 +00:00
}
2019-03-24 22:15:38 +00:00
void CServerBrowser : : CountryFilterClean ( int Network )
2014-09-19 21:52:09 +00:00
{
2019-03-24 22:15:38 +00:00
char * pExcludeCountries = Network = = NETWORK_KOG ? g_Config . m_BrFilterExcludeCountriesKoG : g_Config . m_BrFilterExcludeCountries ;
2014-12-14 15:45:18 +00:00
char aNewList [ 128 ] ;
2016-05-19 13:54:52 +00:00
aNewList [ 0 ] = ' \0 ' ;
2015-07-09 00:08:14 +00:00
2019-03-24 22:15:38 +00:00
for ( int Network = 0 ; Network < NUM_NETWORKS ; Network + + )
2014-09-19 21:52:09 +00:00
{
2019-03-24 22:15:38 +00:00
for ( int i = 0 ; i < m_aNetworks [ Network ] . m_NumCountries ; i + + )
2014-09-19 21:52:09 +00:00
{
2019-03-24 22:15:38 +00:00
const char * pName = m_aNetworks [ Network ] . m_aCountries [ i ] . m_aName ;
if ( DDNetFiltered ( pExcludeCountries , pName ) )
{
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " ,%s " , pName ) ;
str_append ( aNewList , aBuf , sizeof ( aNewList ) ) ;
}
2014-09-19 21:52:09 +00:00
}
}
2019-03-24 22:15:38 +00:00
str_copy ( pExcludeCountries , aNewList , sizeof ( g_Config . m_BrFilterExcludeCountries ) ) ;
2014-09-19 21:52:09 +00:00
}
2014-12-14 15:45:18 +00:00
2019-03-24 22:15:38 +00:00
void CServerBrowser : : TypeFilterClean ( int Network )
2014-12-14 15:45:18 +00:00
{
2019-03-24 22:15:38 +00:00
char * pExcludeTypes = Network = = NETWORK_KOG ? g_Config . m_BrFilterExcludeTypesKoG : g_Config . m_BrFilterExcludeTypes ;
2014-12-14 15:45:18 +00:00
char aNewList [ 128 ] ;
2016-05-19 13:54:52 +00:00
aNewList [ 0 ] = ' \0 ' ;
2015-07-09 00:08:14 +00:00
2019-03-24 22:15:38 +00:00
for ( int i = 0 ; i < m_aNetworks [ Network ] . m_NumTypes ; i + + )
2014-12-14 15:45:18 +00:00
{
2019-03-24 22:15:38 +00:00
const char * pName = m_aNetworks [ Network ] . m_aTypes [ i ] ;
if ( DDNetFiltered ( pExcludeTypes , pName ) )
2014-12-14 15:45:18 +00:00
{
char aBuf [ 128 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " ,%s " , pName ) ;
str_append ( aNewList , aBuf , sizeof ( aNewList ) ) ;
}
}
2019-03-24 22:15:38 +00:00
str_copy ( pExcludeTypes , aNewList , sizeof ( g_Config . m_BrFilterExcludeTypes ) ) ;
2014-12-14 15:45:18 +00:00
}