From a957b652bae5d1a5320eb01c349437bc7197b91a Mon Sep 17 00:00:00 2001 From: thilo Date: Fri, 11 Apr 2008 18:39:03 +0000 Subject: - Revamp in-game server browser: you can now scan for games on multiple master servers, while retaining compatibility with old QVMs. - Make Master server reporting/server queries ipv6 capable. git-svn-id: svn://svn.icculus.org/quake3/trunk@1311 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/client/cl_main.c | 196 +++++++++++++++++++++++--------------------------- 1 file changed, 90 insertions(+), 106 deletions(-) (limited to 'code/client/cl_main.c') diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 589907d..c2edd02 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -36,7 +36,6 @@ cvar_t *rconAddress; cvar_t *cl_timeout; cvar_t *cl_maxpackets; cvar_t *cl_packetdup; -cvar_t *cl_master; cvar_t *cl_timeNudge; cvar_t *cl_showTimeDelta; cvar_t *cl_freezeDemo; @@ -1817,13 +1816,8 @@ void CL_MotdPacket( netadr_t from ) { CL_InitServerInfo =================== */ -void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) { - server->adr.type = NA_IP; - server->adr.ip[0] = address->ip[0]; - server->adr.ip[1] = address->ip[1]; - server->adr.ip[2] = address->ip[2]; - server->adr.ip[3] = address->ip[3]; - server->adr.port = address->port; +void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) { + server->adr = *address; server->clients = 0; server->hostName[0] = '\0'; server->mapName[0] = '\0'; @@ -1844,11 +1838,12 @@ CL_ServersResponsePacket =================== */ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) { - int i, count, max, total; - serverAddress_t addresses[MAX_SERVERSPERPACKET]; + int i, count, total; + netadr_t addresses[MAX_SERVERSPERPACKET]; int numservers; byte* buffptr; byte* buffend; + netadrtype_t family; Com_Printf("CL_ServersResponsePacket\n"); @@ -1858,71 +1853,74 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) { cls.numGlobalServerAddresses = 0; } - if (cls.nummplayerservers == -1) { - cls.nummplayerservers = 0; - } - // parse through server response string numservers = 0; buffptr = msg->data; buffend = buffptr + msg->cursize; - while (buffptr+1 < buffend) { + while (buffptr+1 < buffend) + { // advance to initial token - do { - if (*buffptr++ == '\\') - break; + do + { + if (*buffptr == '\\') + { + family = NA_IP; + break; + } + else if(*buffptr == '/') + { + family = NA_IP6; + break; + } + + buffptr++; } while (buffptr < buffend); - if ( buffptr >= buffend - 6 ) { - break; + buffptr++; + + if(family == NA_IP) + { + if (buffend - buffptr < sizeof(addresses[numservers].ip) + sizeof(addresses[numservers].port) + sizeof("\\EOT") - 1) + break; + + for(i = 0; i < sizeof(addresses[numservers].ip); i++) + addresses[numservers].ip[i] = *buffptr++; + } + else + { + if (buffend - buffptr < sizeof(addresses[numservers].ip6) + sizeof(addresses[numservers].port) + sizeof("\\EOT") - 1) + break; + + for(i = 0; i < sizeof(addresses[numservers].ip6); i++) + addresses[numservers].ip6[i] = *buffptr++; } - // parse out ip - addresses[numservers].ip[0] = *buffptr++; - addresses[numservers].ip[1] = *buffptr++; - addresses[numservers].ip[2] = *buffptr++; - addresses[numservers].ip[3] = *buffptr++; + addresses[numservers].type = family; // parse out port - addresses[numservers].port = (*buffptr++)<<8; + addresses[numservers].port = (*buffptr++) << 8; addresses[numservers].port += *buffptr++; addresses[numservers].port = BigShort( addresses[numservers].port ); // syntax check - if (*buffptr != '\\') { + if (*buffptr != '\\' && *buffptr != '/') break; - } - - Com_DPrintf( "server: %d ip: %d.%d.%d.%d:%d\n",numservers, - addresses[numservers].ip[0], - addresses[numservers].ip[1], - addresses[numservers].ip[2], - addresses[numservers].ip[3], - addresses[numservers].port ); - + numservers++; - if (numservers >= MAX_SERVERSPERPACKET) { + if (numservers >= MAX_SERVERSPERPACKET) break; - } // parse out EOT - if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') { + if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') break; - } } - if (cls.masterNum == 0) { - count = cls.numglobalservers; - max = MAX_GLOBAL_SERVERS; - } else { - count = cls.nummplayerservers; - max = MAX_OTHER_SERVERS; - } + count = cls.numglobalservers; - for (i = 0; i < numservers && count < max; i++) { + for (i = 0; i < numservers && count < MAX_GLOBAL_SERVERS; i++) { // build net address - serverInfo_t *server = (cls.masterNum == 0) ? &cls.globalServers[count] : &cls.mplayerServers[count]; + serverInfo_t *server = &cls.globalServers[count]; CL_InitServerInfo( server, &addresses[i] ); // advance to next slot @@ -1930,29 +1928,18 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) { } // if getting the global list - if (cls.masterNum == 0) { - if ( cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) { - // if we couldn't store the servers in the main list anymore - for (; i < numservers && count >= max; i++) { - serverAddress_t *addr; - // just store the addresses in an additional list - addr = &cls.globalServerAddresses[cls.numGlobalServerAddresses++]; - addr->ip[0] = addresses[i].ip[0]; - addr->ip[1] = addresses[i].ip[1]; - addr->ip[2] = addresses[i].ip[2]; - addr->ip[3] = addresses[i].ip[3]; - addr->port = addresses[i].port; - } + if ( count >= MAX_GLOBAL_SERVERS && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) + { + // if we couldn't store the servers in the main list anymore + for (; i < numservers && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS; i++) + { + // just store the addresses in an additional list + cls.globalServerAddresses[cls.numGlobalServerAddresses++] = addresses[i]; } } - if (cls.masterNum == 0) { - cls.numglobalservers = count; - total = count + cls.numGlobalServerAddresses; - } else { - cls.nummplayerservers = count; - total = count; - } + cls.numglobalservers = count; + total = count + cls.numGlobalServerAddresses; Com_Printf("%d servers parsed (total %d)\n", numservers, total); } @@ -2672,7 +2659,6 @@ void CL_Init( void ) { cl_timeout = Cvar_Get ("cl_timeout", "200", 0); - cl_master = Cvar_Get ("cl_master", MASTER_SERVER_NAME, CVAR_ARCHIVE); cl_timeNudge = Cvar_Get ("cl_timeNudge", "0", CVAR_TEMP ); cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_TEMP ); cl_showSend = Cvar_Get ("cl_showSend", "0", CVAR_TEMP ); @@ -2898,12 +2884,6 @@ static void CL_SetServerInfoByAddress(netadr_t from, const char *info, int ping) } } - for (i = 0; i < MAX_OTHER_SERVERS; i++) { - if (NET_CompareAdr(from, cls.mplayerServers[i].adr)) { - CL_SetServerInfo(&cls.mplayerServers[i], info, ping); - } - } - for (i = 0; i < MAX_GLOBAL_SERVERS; i++) { if (NET_CompareAdr(from, cls.globalServers[i].adr)) { CL_SetServerInfo(&cls.globalServers[i], info, ping); @@ -3260,43 +3240,49 @@ CL_GlobalServers_f */ void CL_GlobalServers_f( void ) { netadr_t to; - int i; - int count; - char *buffptr; - char command[1024]; + int count, i, masterNum; + char command[1024], *masteraddress; - if ( Cmd_Argc() < 3) { - Com_Printf( "usage: globalservers [keywords]\n"); + if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > 4) + { + Com_Printf( "usage: globalservers [keywords]\n"); return; } - cls.masterNum = atoi( Cmd_Argv(1) ); - - Com_Printf( "Requesting servers from the master...\n"); + sprintf(command, "sv_master%d", masterNum + 1); + masteraddress = Cvar_VariableString(command); + + if(!*masteraddress) + { + Com_Printf( "CL_GlobalServers_f: Error: No master server address given.\n"); + return; + } // reset the list, waiting for response // -1 is used to distinguish a "no response" - NET_StringToAdr( cl_master->string, &to, NA_IP ); - - if( cls.masterNum == 1 ) { - cls.nummplayerservers = -1; - cls.pingUpdateSource = AS_MPLAYER; - } - else { - cls.numglobalservers = -1; - cls.pingUpdateSource = AS_GLOBAL; + i = NET_StringToAdr(masteraddress, &to, NA_UNSPEC); + + if(!i) + { + Com_Printf( "CL_GlobalServers_f: Error: could not resolve address of master %s\n", masteraddress); + return; } - to.type = NA_IP; - to.port = BigShort(PORT_MASTER); + else if(i == 2) + to.port = BigShort(PORT_MASTER); + + Com_Printf("Requesting servers from master %s...\n", masteraddress); + + cls.numglobalservers = -1; + cls.pingUpdateSource = AS_GLOBAL; - sprintf( command, "getservers %s", Cmd_Argv(2) ); + Com_sprintf( command, sizeof(command), "getservers %s", Cmd_Argv(2) ); - // tack on keywords - buffptr = command + strlen( command ); - count = Cmd_Argc(); - for (i=3; i