Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1227 lines
19 KiB

9 years ago
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// hud_servers.cpp
#include "hud.h"
#include "cl_util.h"
#include "hud_servers_priv.h"
#include "hud_servers.h"
#include "net_api.h"
#include <string.h>
#include <winsock.h>
static int context_id;
// Default master server address in case we can't read any from woncomm.lst file
#define VALVE_MASTER_ADDRESS "half-life.east.won.net"
#define PORT_MASTER 27010
#define PORT_SERVER 27015
// File where we really should look for master servers
#define MASTER_PARSE_FILE "woncomm.lst"
#define MAX_QUERIES 20
#define NET_API gEngfuncs.pNetAPI
static CHudServers *g_pServers = NULL;
/*
===================
ListResponse
Callback from engine
===================
*/
void NET_CALLBACK ListResponse( struct net_response_s *response )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->ListResponse( response );
}
}
/*
===================
ServerResponse
Callback from engine
===================
*/
void NET_CALLBACK ServerResponse( struct net_response_s *response )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->ServerResponse( response );
}
}
/*
===================
PingResponse
Callback from engine
===================
*/
void NET_CALLBACK PingResponse( struct net_response_s *response )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->PingResponse( response );
}
}
/*
===================
RulesResponse
Callback from engine
===================
*/
void NET_CALLBACK RulesResponse( struct net_response_s *response )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->RulesResponse( response );
}
}
9 years ago
9 years ago
/*
===================
PlayersResponse
Callback from engine
===================
*/
void NET_CALLBACK PlayersResponse( struct net_response_s *response )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->PlayersResponse( response );
}
}
9 years ago
9 years ago
/*
===================
ListResponse
===================
*/
void CHudServers::ListResponse( struct net_response_s *response )
{
request_t *list;
request_t *p;
int c = 0;
9 years ago
if( !( response->error == NET_SUCCESS ) )
9 years ago
return;
9 years ago
if( response->type != NETAPI_REQUEST_SERVERLIST )
9 years ago
return;
9 years ago
if( response->response )
9 years ago
{
list = ( request_t * ) response->response;
while ( list )
{
c++;
9 years ago
//if( c < 40 )
9 years ago
{
// Copy from parsed stuff
p = new request_t;
p->context = -1;
p->remote_address = list->remote_address;
p->next = m_pServerList;
m_pServerList = p;
}
// Move on
list = list->next;
}
}
gEngfuncs.Con_Printf( "got list\n" );
m_nQuerying = 1;
m_nActiveQueries = 0;
}
/*
===================
ServerResponse
===================
*/
void CHudServers::ServerResponse( struct net_response_s *response )
{
char *szresponse;
request_t *p;
server_t *browser;
int len;
9 years ago
char sz[32];
9 years ago
// Remove from active list
p = FindRequest( response->context, m_pActiveList );
9 years ago
if( p )
9 years ago
{
RemoveServerFromList( &m_pActiveList, p );
m_nActiveQueries--;
}
9 years ago
if( response->error != NET_SUCCESS )
9 years ago
return;
9 years ago
9 years ago
switch ( response->type )
{
case NETAPI_REQUEST_DETAILS:
9 years ago
if( response->response )
9 years ago
{
szresponse = (char *)response->response;
len = strlen( szresponse ) + 100 + 1;
sprintf( sz, "%i", (int)( 1000.0 * response->ping ) );
browser = new server_t;
browser->remote_address = response->remote_address;
9 years ago
browser->info = new char[len];
9 years ago
browser->ping = (int)( 1000.0 * response->ping );
strcpy( browser->info, szresponse );
NET_API->SetValueForKey( browser->info, "address", gEngfuncs.pNetAPI->AdrToString( &response->remote_address ), len );
NET_API->SetValueForKey( browser->info, "ping", sz, len );
9 years ago
9 years ago
AddServer( &m_pServers, browser );
}
break;
default:
break;
}
}
/*
===================
PingResponse
===================
*/
void CHudServers::PingResponse( struct net_response_s *response )
{
9 years ago
char sz[32];
9 years ago
9 years ago
if( response->error != NET_SUCCESS )
9 years ago
return;
9 years ago
switch( response->type )
9 years ago
{
case NETAPI_REQUEST_PING:
sprintf( sz, "%.2f", 1000.0 * response->ping );
gEngfuncs.Con_Printf( "ping == %s\n", sz );
break;
default:
break;
}
}
/*
===================
RulesResponse
===================
*/
void CHudServers::RulesResponse( struct net_response_s *response )
{
char *szresponse;
9 years ago
if( response->error != NET_SUCCESS )
9 years ago
return;
9 years ago
switch( response->type )
9 years ago
{
case NETAPI_REQUEST_RULES:
9 years ago
if( response->response )
9 years ago
{
szresponse = (char *)response->response;
gEngfuncs.Con_Printf( "rules %s\n", szresponse );
}
break;
default:
break;
}
}
/*
===================
PlayersResponse
===================
*/
void CHudServers::PlayersResponse( struct net_response_s *response )
{
char *szresponse;
9 years ago
if( response->error != NET_SUCCESS )
9 years ago
return;
9 years ago
switch( response->type )
9 years ago
{
case NETAPI_REQUEST_PLAYERS:
9 years ago
if( response->response )
9 years ago
{
szresponse = (char *)response->response;
gEngfuncs.Con_Printf( "players %s\n", szresponse );
}
break;
default:
break;
}
}
/*
===================
CompareServers
Return 1 if p1 is "less than" p2, 0 otherwise
===================
*/
9 years ago
int CHudServers::CompareServers( server_t *p1, server_t *p2 )
9 years ago
{
const char *n1, *n2;
9 years ago
if( p1->ping < p2->ping )
9 years ago
return 1;
9 years ago
if( p1->ping == p2->ping )
9 years ago
{
// Pings equal, sort by second key: hostname
9 years ago
if( p1->info && p2->info )
9 years ago
{
n1 = NET_API->ValueForKey( p1->info, "hostname" );
n2 = NET_API->ValueForKey( p2->info, "hostname" );
9 years ago
if( n1 && n2 )
9 years ago
{
9 years ago
if( stricmp( n1, n2 ) < 0 )
9 years ago
return 1;
}
}
}
return 0;
}
/*
===================
AddServer
===================
*/
void CHudServers::AddServer( server_t **ppList, server_t *p )
{
9 years ago
server_t *list;
9 years ago
9 years ago
if( !ppList || ! p )
9 years ago
return;
m_nServerCount++;
// What sort key? Ping?
list = *ppList;
// Head of list?
9 years ago
if( !list )
9 years ago
{
p->next = NULL;
*ppList = p;
return;
}
// Put on head of list
9 years ago
if( CompareServers( p, list ) )
9 years ago
{
p->next = *ppList;
*ppList = p;
}
else
{
9 years ago
while( list->next )
9 years ago
{
// Insert before list next
9 years ago
if( CompareServers( p, list->next ) )
9 years ago
{
p->next = list->next->next;
list->next = p;
return;
}
list = list->next;
}
// Just add at end
p->next = NULL;
list->next = p;
}
}
/*
===================
Think
===================
*/
void CHudServers::Think( double time )
{
m_fElapsed += time;
9 years ago
if( !m_nRequesting )
9 years ago
return;
9 years ago
if( !m_nQuerying )
9 years ago
return;
QueryThink();
9 years ago
if( ServerListSize() > 0 )
9 years ago
return;
m_dStarted = 0.0;
m_nRequesting = 0;
m_nDone = 0;
m_nQuerying = 0;
m_nActiveQueries = 0;
}
/*
===================
QueryThink
===================
*/
void CHudServers::QueryThink( void )
{
request_t *p;
9 years ago
if( !m_nRequesting || m_nDone )
9 years ago
return;
9 years ago
if( !m_nQuerying )
9 years ago
return;
9 years ago
if( m_nActiveQueries > MAX_QUERIES )
9 years ago
return;
// Nothing left
9 years ago
if( !m_pServerList )
9 years ago
return;
9 years ago
while( 1 )
9 years ago
{
p = m_pServerList;
// No more in list?
9 years ago
if( !p )
9 years ago
break;
// Move to next
m_pServerList = m_pServerList->next;
// Setup context_id
p->context = context_id;
// Start up query on this one
NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, 0, 2.0, &p->remote_address, ::ServerResponse );
// Increment active list
m_nActiveQueries++;
// Add to active list
p->next = m_pActiveList;
m_pActiveList = p;
// Too many active?
9 years ago
if( m_nActiveQueries > MAX_QUERIES )
9 years ago
break;
}
}
/*
==================
ServerListSize
# of servers in active query and in pending to be queried lists
==================
*/
9 years ago
int CHudServers::ServerListSize( void )
9 years ago
{
int c = 0;
request_t *p;
p = m_pServerList;
9 years ago
while( p )
9 years ago
{
c++;
p = p->next;
}
p = m_pActiveList;
9 years ago
while( p )
9 years ago
{
c++;
p = p->next;
}
return c;
}
/*
===================
FindRequest
Look up a request by context id
===================
*/
CHudServers::request_t *CHudServers::FindRequest( int context, request_t *pList )
{
request_t *p;
p = pList;
9 years ago
while( p )
9 years ago
{
9 years ago
if( context == p->context )
9 years ago
return p;
p = p->next;
}
return NULL;
}
/*
===================
RemoveServerFromList
Remote, but don't delete, item from *ppList
===================
*/
void CHudServers::RemoveServerFromList( request_t **ppList, request_t *item )
{
request_t *p, *n;
request_t *newlist = NULL;
9 years ago
if( !ppList )
9 years ago
return;
p = *ppList;
9 years ago
while( p )
9 years ago
{
n = p->next;
9 years ago
if( p != item )
9 years ago
{
p->next = newlist;
newlist = p;
}
p = n;
}
*ppList = newlist;
}
/*
===================
ClearRequestList
===================
*/
void CHudServers::ClearRequestList( request_t **ppList )
{
request_t *p, *n;
9 years ago
if( !ppList )
9 years ago
return;
p = *ppList;
9 years ago
while( p )
9 years ago
{
n = p->next;
delete p;
p = n;
}
*ppList = NULL;
}
/*
===================
ClearServerList
===================
*/
void CHudServers::ClearServerList( server_t **ppList )
{
server_t *p, *n;
9 years ago
if( !ppList )
9 years ago
return;
p = *ppList;
9 years ago
while( p )
9 years ago
{
n = p->next;
delete[] p->info;
delete p;
p = n;
}
*ppList = NULL;
}
int CompareField( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname, int iSortOrder )
{
const char *sz1, *sz2;
float fv1, fv2;
sz1 = NET_API->ValueForKey( p1->info, fieldname );
sz2 = NET_API->ValueForKey( p2->info, fieldname );
fv1 = atof( sz1 );
fv2 = atof( sz2 );
9 years ago
if( fv1 && fv2 )
9 years ago
{
9 years ago
if( fv1 > fv2 )
9 years ago
return iSortOrder;
9 years ago
else if( fv1 < fv2 )
9 years ago
return -iSortOrder;
else
return 0;
}
// String compare
return stricmp( sz1, sz2 );
}
int CALLBACK ServerListCompareFunc( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname )
{
9 years ago
if(!p1 || !p2) // No meaningful comparison
9 years ago
return 0;
int iSortOrder = 1;
int retval = 0;
retval = CompareField( p1, p2, fieldname, iSortOrder );
return retval;
}
9 years ago
static char g_fieldname[256];
int __cdecl FnServerCompare( const void *elem1, const void *elem2 )
9 years ago
{
CHudServers::server_t *list1, *list2;
list1 = *(CHudServers::server_t **)elem1;
list2 = *(CHudServers::server_t **)elem2;
return ServerListCompareFunc( list1, list2, g_fieldname );
}
void CHudServers::SortServers( const char *fieldname )
{
server_t *p;
// Create a list
9 years ago
if( !m_pServers )
9 years ago
return;
strcpy( g_fieldname, fieldname );
int i;
int c = 0;
p = m_pServers;
9 years ago
while( p )
9 years ago
{
c++;
p = p->next;
}
server_t **pSortArray;
9 years ago
pSortArray = new server_t *[c];
memset( pSortArray, 0, c * sizeof(server_t*) );
9 years ago
// Now copy the list into the pSortArray:
p = m_pServers;
i = 0;
9 years ago
while( p )
9 years ago
{
9 years ago
pSortArray[i++] = p;
9 years ago
p = p->next;
}
// Now do that actual sorting.
size_t nCount = c;
9 years ago
size_t nSize = sizeof(server_t*);
9 years ago
qsort(
pSortArray,
(size_t)nCount,
(size_t)nSize,
FnServerCompare
);
// Now rebuild the list.
m_pServers = pSortArray[0];
9 years ago
for( i = 0; i < c - 1; i++ )
9 years ago
{
9 years ago
pSortArray[i]->next = pSortArray[i + 1];
9 years ago
}
9 years ago
pSortArray[c - 1]->next = NULL;
9 years ago
// Clean Up.
delete[] pSortArray;
}
/*
===================
GetServer
Return particular server
===================
*/
CHudServers::server_t *CHudServers::GetServer( int server )
{
int c = 0;
server_t *p;
p = m_pServers;
9 years ago
while( p )
9 years ago
{
9 years ago
if( c == server )
9 years ago
return p;
c++;
p = p->next;
}
return NULL;
}
/*
===================
GetServerInfo
Return info ( key/value ) string for particular server
===================
*/
char *CHudServers::GetServerInfo( int server )
{
server_t *p = GetServer( server );
9 years ago
if( p )
9 years ago
{
return p->info;
}
return NULL;
}
/*
===================
CancelRequest
Kill all pending requests in engine
===================
*/
void CHudServers::CancelRequest( void )
{
m_nRequesting = 0;
9 years ago
m_nQuerying = 0;
m_nDone = 1;
9 years ago
NET_API->CancelAllRequests();
}
/*
==================
LoadMasterAddresses
Loads the master server addresses from file and into the passed in array
==================
*/
int CHudServers::LoadMasterAddresses( int maxservers, int *count, netadr_t *padr )
{
int i;
9 years ago
char szMaster[256];
9 years ago
char szMasterFile[256];
char *pbuffer = NULL;
char *pstart = NULL ;
netadr_t adr;
char szAdr[64];
9 years ago
int nPort;
int nCount = 0;
9 years ago
bool bIgnore;
9 years ago
int nDefaultPort;
9 years ago
// Assume default master and master file
strcpy( szMaster, VALVE_MASTER_ADDRESS ); // IP:PORT string
strcpy( szMasterFile, MASTER_PARSE_FILE );
// See if there is a command line override
i = gEngfuncs.CheckParm( "-comm", &pstart );
9 years ago
if( i && pstart )
9 years ago
{
9 years ago
strcpy( szMasterFile, pstart );
9 years ago
}
// Read them in from proper file
pbuffer = (char *)gEngfuncs.COM_LoadFile( szMasterFile, 5, NULL ); // Use malloc
9 years ago
if( !pbuffer )
9 years ago
{
goto finish_master;
}
pstart = pbuffer;
9 years ago
while( nCount < maxservers )
9 years ago
{
pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken );
9 years ago
if( strlen( m_szToken ) <= 0)
9 years ago
break;
bIgnore = true;
9 years ago
if( !stricmp( m_szToken, "Master" ) )
9 years ago
{
nDefaultPort = PORT_MASTER;
bIgnore = FALSE;
}
// Now parse all addresses between { }
pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken );
9 years ago
if( strlen( m_szToken ) <= 0 )
9 years ago
break;
9 years ago
if( stricmp( m_szToken, "{" ) )
9 years ago
break;
// Parse addresses until we get to "}"
9 years ago
while( nCount < maxservers )
9 years ago
{
char base[256];
// Now parse all addresses between { }
pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken );
9 years ago
if( strlen( m_szToken ) <= 0 )
9 years ago
break;
9 years ago
if( !stricmp ( m_szToken, "}" ) )
9 years ago
break;
9 years ago
9 years ago
sprintf( base, "%s", m_szToken );
pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken );
9 years ago
if( strlen( m_szToken ) <= 0 )
9 years ago
break;
9 years ago
if( stricmp( m_szToken, ":" ) )
9 years ago
break;
pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken );
9 years ago
if( strlen( m_szToken ) <= 0 )
9 years ago
break;
9 years ago
nPort = atoi( m_szToken );
if( !nPort )
9 years ago
nPort = nDefaultPort;
sprintf( szAdr, "%s:%i", base, nPort );
// Can we resolve it any better
9 years ago
if( !NET_API->StringToAdr( szAdr, &adr ) )
9 years ago
bIgnore = true;
9 years ago
if( !bIgnore )
9 years ago
{
9 years ago
padr[nCount++] = adr;
9 years ago
}
}
}
finish_master:
9 years ago
if( !nCount )
9 years ago
{
sprintf( szMaster, VALVE_MASTER_ADDRESS ); // IP:PORT string
// Convert to netadr_t
9 years ago
if( NET_API->StringToAdr( szMaster, &adr ) )
9 years ago
{
9 years ago
padr[nCount++] = adr;
9 years ago
}
}
*count = nCount;
9 years ago
if( pbuffer )
9 years ago
{
gEngfuncs.COM_FreeFile( pbuffer );
}
return ( nCount > 0 ) ? 1 : 0;
}
/*
===================
RequestList
Request list of game servers from master
===================
*/
void CHudServers::RequestList( void )
{
9 years ago
m_nRequesting = 1;
m_nDone = 0;
m_dStarted = m_fElapsed;
9 years ago
int count = 0;
netadr_t adr;
9 years ago
if( !LoadMasterAddresses( 1, &count, &adr ) )
9 years ago
{
gEngfuncs.Con_DPrintf( "SendRequest: Unable to read master server addresses\n" );
return;
}
ClearRequestList( &m_pActiveList );
ClearRequestList( &m_pServerList );
ClearServerList( &m_pServers );
m_nServerCount = 0;
// Make sure networking system has started.
NET_API->InitNetworking();
// Kill off left overs if any
NET_API->CancelAllRequests();
// Request Server List from master
NET_API->SendRequest( context_id++, NETAPI_REQUEST_SERVERLIST, 0, 5.0, &adr, ::ListResponse );
}
void CHudServers::RequestBroadcastList( int clearpending )
{
9 years ago
m_nRequesting = 1;
m_nDone = 0;
m_dStarted = m_fElapsed;
9 years ago
netadr_t adr = {0};
9 years ago
9 years ago
if( clearpending )
9 years ago
{
ClearRequestList( &m_pActiveList );
ClearRequestList( &m_pServerList );
ClearServerList( &m_pServers );
m_nServerCount = 0;
}
// Make sure to byte swap server if necessary ( using "host" to "net" conversion
adr.port = htons( PORT_SERVER );
// Make sure networking system has started.
NET_API->InitNetworking();
9 years ago
if( clearpending )
9 years ago
{
// Kill off left overs if any
NET_API->CancelAllRequests();
}
adr.type = NA_BROADCAST;
// Request Servers from LAN via IP
NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, FNETAPI_MULTIPLE_RESPONSE, 5.0, &adr, ::ServerResponse );
adr.type = NA_BROADCAST_IPX;
// Request Servers from LAN via IPX ( if supported )
NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, FNETAPI_MULTIPLE_RESPONSE, 5.0, &adr, ::ServerResponse );
}
void CHudServers::ServerPing( int server )
{
server_t *p;
9 years ago
9 years ago
p = GetServer( server );
9 years ago
if( !p )
9 years ago
return;
// Make sure networking system has started.
NET_API->InitNetworking();
// Request Server List from master
NET_API->SendRequest( context_id++, NETAPI_REQUEST_PING, 0, 5.0, &p->remote_address, ::PingResponse );
}
void CHudServers::ServerRules( int server )
{
server_t *p;
9 years ago
9 years ago
p = GetServer( server );
9 years ago
if( !p )
9 years ago
return;
// Make sure networking system has started.
NET_API->InitNetworking();
// Request Server List from master
NET_API->SendRequest( context_id++, NETAPI_REQUEST_RULES, 0, 5.0, &p->remote_address, ::RulesResponse );
}
void CHudServers::ServerPlayers( int server )
{
server_t *p;
9 years ago
9 years ago
p = GetServer( server );
9 years ago
if( !p )
9 years ago
return;
// Make sure networking system has started.
NET_API->InitNetworking();
// Request Server List from master
NET_API->SendRequest( context_id++, NETAPI_REQUEST_PLAYERS, 0, 5.0, &p->remote_address, ::PlayersResponse );
}
int CHudServers::isQuerying()
{
return m_nRequesting ? 1 : 0;
}
/*
===================
GetServerCount
Return number of servers in browser list
===================
*/
int CHudServers::GetServerCount( void )
{
return m_nServerCount;
}
/*
===================
CHudServers
===================
*/
CHudServers::CHudServers( void )
{
m_nRequesting = 0;
9 years ago
m_dStarted = 0.0;
m_nDone = 0;
9 years ago
m_pServerList = NULL;
9 years ago
m_pServers = NULL;
9 years ago
m_pActiveList = NULL;
9 years ago
m_nQuerying = 0;
9 years ago
m_nActiveQueries = 0;
9 years ago
m_fElapsed = 0.0;
9 years ago
m_pPingRequest = NULL;
m_pRulesRequest = NULL;
m_pPlayersRequest = NULL;
}
/*
===================
~CHudServers
===================
*/
CHudServers::~CHudServers( void )
{
ClearRequestList( &m_pActiveList );
ClearRequestList( &m_pServerList );
ClearServerList( &m_pServers );
m_nServerCount = 0;
9 years ago
if( m_pPingRequest )
9 years ago
{
delete m_pPingRequest;
m_pPingRequest = NULL;
}
9 years ago
if( m_pRulesRequest )
9 years ago
{
delete m_pRulesRequest;
m_pRulesRequest = NULL;
}
9 years ago
if( m_pPlayersRequest )
9 years ago
{
delete m_pPlayersRequest;
m_pPlayersRequest = NULL;
}
}
///////////////////////////////
//
// PUBLIC APIs
//
///////////////////////////////
/*
===================
ServersGetCount
===================
*/
9 years ago
int ServersGetCount( void )
9 years ago
{
9 years ago
if( g_pServers )
9 years ago
{
return g_pServers->GetServerCount();
}
return 0;
}
9 years ago
int ServersIsQuerying( void )
9 years ago
{
9 years ago
if( g_pServers )
9 years ago
{
return g_pServers->isQuerying();
}
return 0;
}
/*
===================
ServersGetInfo
===================
*/
const char *ServersGetInfo( int server )
{
9 years ago
if( g_pServers )
9 years ago
{
return g_pServers->GetServerInfo( server );
}
9 years ago
9 years ago
return NULL;
}
void SortServers( const char *fieldname )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->SortServers( fieldname );
}
}
/*
===================
ServersShutdown
===================
*/
void ServersShutdown( void )
{
9 years ago
if( g_pServers )
9 years ago
{
delete g_pServers;
g_pServers = NULL;
}
}
/*
===================
ServersInit
===================
*/
void ServersInit( void )
{
// Kill any previous instance
ServersShutdown();
9 years ago
9 years ago
g_pServers = new CHudServers();
}
/*
===================
ServersThink
===================
*/
void ServersThink( double time )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->Think( time );
}
}
/*
===================
ServersCancel
===================
*/
void ServersCancel( void )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->CancelRequest();
}
}
// Requests
/*
===================
ServersList
===================
*/
void ServersList( void )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->RequestList();
}
}
void BroadcastServersList( int clearpending )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->RequestBroadcastList( clearpending );
}
}
void ServerPing( int server )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->ServerPing( server );
}
}
void ServerRules( int server )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->ServerRules( server );
}
}
void ServerPlayers( int server )
{
9 years ago
if( g_pServers )
9 years ago
{
g_pServers->ServerPlayers( server );
}
9 years ago
}