/* * CL_MasterAddressCache_Init */ static void CL_MasterAddressCache_Init( void ) { char *master; const char *mlist; serverlist_masters_head = NULL; Trie_Create( TRIE_CASE_INSENSITIVE, &serverlist_masters_trie ); // synchronous DNS queries cause interruption of sounds, background music, etc // so precache results of resolution queries for all master servers mlist = Cvar_String( "masterservers" ); while( mlist ) { master = COM_Parse( &mlist ); if( !*master ) break; CL_ResolveMasterAddress( master, NULL ); } }
/* * CL_MasterResolverThreadEntry */ static void *CL_MasterResolverThreadEntry( void *pmlist ) { CL_ResolveMasterAddress( ( char * )pmlist ); free( pmlist ); return NULL; }
/* * CL_GetServers_f */ void CL_GetServers_f( void ) { netadr_t adr; char *requeststring; int i; char *modname, *master; filter_allow_full = qfalse; filter_allow_empty = qfalse; for( i = 2; i < Cmd_Argc(); i++ ) { if( !Q_stricmp( "full", Cmd_Argv( i ) ) ) filter_allow_full = qtrue; if( !Q_stricmp( "empty", Cmd_Argv( i ) ) ) filter_allow_empty = qtrue; } if( !Q_stricmp( Cmd_Argv( 1 ), "local" ) ) { if( localQueryTimeStamp + LAN_SERVER_PINGING_TIMEOUT > Sys_Milliseconds() ) { return; } localQueryTimeStamp = Sys_Milliseconds(); // send a broadcast packet Com_Printf( "pinging broadcast...\n" ); // erm... modname isn't sent in local queries? requeststring = va( "info %i %s %s", SERVERBROWSER_PROTOCOL_VERSION, filter_allow_full ? "full" : "", filter_allow_empty ? "empty" : "" ); for( i = 0; i < NUM_BROADCAST_PORTS; i++ ) { NET_BroadcastAddress( &adr, PORT_SERVER + i ); Netchan_OutOfBandPrint( &cls.socket_udp, &adr, requeststring ); } return; } //get what master master = Cmd_Argv( 2 ); if( !master || !( *master ) ) return; modname = Cmd_Argv( 3 ); // never allow anyone to use DEFAULT_BASEGAME as mod name if( !modname || !modname[0] || !Q_stricmp( modname, DEFAULT_BASEGAME ) ) modname = APPLICATION; assert( modname[0] ); // fetch from cache or query DNS server CL_ResolveMasterAddress( master, &adr ); if( adr.type == NA_IP || adr.type == NA_IP6 ) { const char *cmdname; socket_t *socket; if ( adr.type == NA_IP ) { cmdname = "getservers"; socket = &cls.socket_udp; } else { cmdname = "getserversExt"; socket = &cls.socket_udp6; } // create the message requeststring = va( "%s %c%s %i %s %s", cmdname, toupper( modname[0] ), modname+1, SERVERBROWSER_PROTOCOL_VERSION, filter_allow_full ? "full" : "", filter_allow_empty ? "empty" : "" ); if( NET_GetAddressPort( &adr ) == 0 ) NET_SetAddressPort( &adr, PORT_MASTER ); Netchan_OutOfBandPrint( socket, &adr, requeststring ); Com_DPrintf( "quering %s...%s: %s\n", master, NET_AddressToString( &adr), requeststring ); } else { Com_Printf( "Bad address: %s\n", master ); } }