/* ================= ArenaServers_Insert ================= */ static void ArenaServers_Insert( char* adrstr, char* info, int pingtime ) { servernode_t* servernodeptr; if ((pingtime >= ArenaServers_MaxPing()) && (g_servertype != UIAS_FAVORITES)) { // slow global or local servers do not get entered return; } if (*g_arenaservers.numservers >= g_arenaservers.maxservers) { // list full; servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers)-1; } else { // next slot servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers); (*g_arenaservers.numservers)++; } Q_strncpyz( servernodeptr->adrstr, adrstr, MAX_ADDRESSLENGTH ); Q_strncpyz( servernodeptr->hostname, Info_ValueForKey( info, "hostname"), MAX_HOSTNAMELENGTH ); Q_CleanStr( servernodeptr->hostname ); Q_strupr( servernodeptr->hostname ); Q_strncpyz( servernodeptr->mapname, Info_ValueForKey( info, "mapname"), MAX_MAPNAMELENGTH ); Q_CleanStr( servernodeptr->mapname ); servernodeptr->numclients = atoi( Info_ValueForKey( info, "clients") ); servernodeptr->humanplayers = atoi( Info_ValueForKey( info, "g_humanplayers") ); servernodeptr->maxclients = atoi( Info_ValueForKey( info, "sv_maxclients") ); servernodeptr->pingtime = pingtime; servernodeptr->minPing = atoi( Info_ValueForKey( info, "minPing") ); servernodeptr->maxPing = atoi( Info_ValueForKey( info, "maxPing") ); /* s = Info_ValueForKey( info, "nettype" ); for (i=0; ;i++) { if (!netnames[i]) { servernodeptr->nettype = 0; break; } else if (!Q_stricmp( netnames[i], s )) { servernodeptr->nettype = i; break; } } */ servernodeptr->nettype = atoi(Info_ValueForKey(info, "nettype")); if (servernodeptr->nettype < 0 || servernodeptr->nettype >= ARRAY_LEN(netnames) - 1) { servernodeptr->nettype = 0; } Q_strncpyz( servernodeptr->gametypeName, Info_ValueForKey( info, "gametype"), sizeof(servernodeptr->gametypeName) ); Q_CleanStr( servernodeptr->gametypeName ); }
/* ================= ArenaServers_InsertFavorites Insert nonresponsive address book entries into display lists. ================= */ void ArenaServers_InsertFavorites( void ) { int i; int j; char info[MAX_INFO_STRING]; // resync existing results with new or deleted cvars info[0] = '\0'; Info_SetValueForKey( info, "hostname", "No Response" ); for (i=0; i<g_arenaservers.numfavoriteaddresses; i++) { // find favorite address in refresh list for (j=0; j<g_numfavoriteservers; j++) if (!Q_stricmp(g_arenaservers.favoriteaddresses[i],g_favoriteserverlist[j].adrstr)) break; if ( j >= g_numfavoriteservers) { // not in list, add it ArenaServers_Insert( g_arenaservers.favoriteaddresses[i], info, ArenaServers_MaxPing() ); } } }
/* ================= ArenaServers_DoRefresh ================= */ static void ArenaServers_DoRefresh( void ) { int i; int j; int time; int maxPing; char adrstr[MAX_ADDRESSLENGTH]; char info[MAX_INFO_STRING]; if (uis.realtime < g_arenaservers.refreshtime) { if (g_servertype != UIAS_FAVORITES) { if (g_servertype == UIAS_LOCAL) { if (!trap->LAN_GetServerCount(AS_LOCAL)) { return; } } if (trap->LAN_GetServerCount(ArenaServers_SourceForLAN()) < 0) { // still waiting for response return; } } } if (uis.realtime < g_arenaservers.nextpingtime) { // wait for time trigger return; } // trigger at 10Hz intervals g_arenaservers.nextpingtime = uis.realtime + 10; // process ping results maxPing = ArenaServers_MaxPing(); for (i=0; i<MAX_PINGREQUESTS; i++) { trap->LAN_GetPing( i, adrstr, MAX_ADDRESSLENGTH, &time ); if (!adrstr[0]) { // ignore empty or pending pings continue; } // find ping result in our local list for (j=0; j<MAX_PINGREQUESTS; j++) if (!Q_stricmp( adrstr, g_arenaservers.pinglist[j].adrstr )) break; if (j < MAX_PINGREQUESTS) { // found it if (!time) { time = uis.realtime - g_arenaservers.pinglist[j].start; if (time < maxPing) { // still waiting continue; } } if (time > maxPing) { // stale it out info[0] = '\0'; time = maxPing; } else { trap->LAN_GetPingInfo( i, info, MAX_INFO_STRING ); } // insert ping results ArenaServers_Insert( adrstr, info, time ); // clear this query from internal list g_arenaservers.pinglist[j].adrstr[0] = '\0'; } // clear this query from external list trap->LAN_ClearPing( i ); } // get results of servers query // counts can increase as servers respond if (g_servertype == UIAS_FAVORITES) { g_arenaservers.numqueriedservers = g_arenaservers.numfavoriteaddresses; } else { g_arenaservers.numqueriedservers = trap->LAN_GetServerCount(ArenaServers_SourceForLAN()); } // if (g_arenaservers.numqueriedservers > g_arenaservers.maxservers) // g_arenaservers.numqueriedservers = g_arenaservers.maxservers; // send ping requests in reasonable bursts // iterate ping through all found servers for (i=0; i<MAX_PINGREQUESTS && g_arenaservers.currentping < g_arenaservers.numqueriedservers; i++) { if (trap->LAN_GetPingQueueCount() >= MAX_PINGREQUESTS) { // ping queue is full break; } // find empty slot for (j=0; j<MAX_PINGREQUESTS; j++) if (!g_arenaservers.pinglist[j].adrstr[0]) break; if (j >= MAX_PINGREQUESTS) // no empty slots available yet - wait for timeout break; // get an address to ping if (g_servertype == UIAS_FAVORITES) { strcpy( adrstr, g_arenaservers.favoriteaddresses[g_arenaservers.currentping] ); } else { trap->LAN_GetServerAddressString(ArenaServers_SourceForLAN(), g_arenaservers.currentping, adrstr, MAX_ADDRESSLENGTH ); } strcpy( g_arenaservers.pinglist[j].adrstr, adrstr ); g_arenaservers.pinglist[j].start = uis.realtime; trap->Cmd_ExecuteText( EXEC_NOW, va( "ping %s\n", adrstr ) ); // advance to next server g_arenaservers.currentping++; } if (!trap->LAN_GetPingQueueCount()) { // all pings completed ArenaServers_StopRefresh(); return; } // update the user interface with ping status ArenaServers_UpdateMenu(); }
/* ================= ArenaServers_LoadFavorites Load cvar address book entries into local lists. ================= */ void ArenaServers_LoadFavorites( void ) { int i; int j; int numtempitems; char adrstr[MAX_ADDRESSLENGTH]; servernode_t templist[MAX_FAVORITESERVERS]; bool found; found = false; // copy the old memcpy( templist, g_favoriteserverlist, sizeof(servernode_t)*MAX_FAVORITESERVERS ); numtempitems = g_numfavoriteservers; // clear the current for sync memset( g_favoriteserverlist, 0, sizeof(servernode_t)*MAX_FAVORITESERVERS ); g_numfavoriteservers = 0; // resync existing results with new or deleted cvars for (i=0; i<MAX_FAVORITESERVERS; i++) { cvarSystem->VariableStringBuffer( va("server%d",i+1), adrstr, MAX_ADDRESSLENGTH ); if (!adrstr[0]) continue; // favorite server addresses must be maintained outside refresh list // this mimics local and global netadr's stored in client // these can be fetched to fill ping list strcpy( g_arenaservers.favoriteaddresses[g_numfavoriteservers], adrstr ); // find this server in the old list for (j=0; j<numtempitems; j++) if (!Q_stricmp( templist[j].adrstr, adrstr )) break; if (j < numtempitems) { // found server - add exisiting results memcpy( &g_favoriteserverlist[g_numfavoriteservers], &templist[j], sizeof(servernode_t) ); found = true; } else { // add new server Q_strncpyz( g_favoriteserverlist[g_numfavoriteservers].adrstr, adrstr, MAX_ADDRESSLENGTH ); g_favoriteserverlist[g_numfavoriteservers].pingtime = ArenaServers_MaxPing(); } g_numfavoriteservers++; } g_arenaservers.numfavoriteaddresses = g_numfavoriteservers; if (!found) { // no results were found, reset server list // list will be automatically refreshed when selected g_numfavoriteservers = 0; } }
/* ================= ArenaServers_Insert ================= */ static void ArenaServers_Insert( char* adrstr, char* info, int pingtime ) { servernode_t* servernodeptr; char* s; int i; if ((pingtime >= ArenaServers_MaxPing()) && (g_servertype != AS_FAVORITES)) { // slow global or local servers do not get entered return; } if (*g_arenaservers.numservers >= g_arenaservers.maxservers) { // list full; servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers)-1; } else { // next slot servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers); (*g_arenaservers.numservers)++; } Q_strncpyz( servernodeptr->adrstr, adrstr, MAX_ADDRESSLENGTH ); Q_strncpyz( servernodeptr->hostname, Info_ValueForKey( info, "hostname"), MAX_HOSTNAMELENGTH ); Q_CleanStr( servernodeptr->hostname ); Q_strupr( servernodeptr->hostname ); Q_strncpyz( servernodeptr->mapname, Info_ValueForKey( info, "mapname"), MAX_MAPNAMELENGTH ); Q_CleanStr( servernodeptr->mapname ); Q_strupr( servernodeptr->mapname ); servernodeptr->numclients = atoi( Info_ValueForKey( info, "clients") ); servernodeptr->maxclients = atoi( Info_ValueForKey( info, "sv_maxclients") ); servernodeptr->pingtime = pingtime; servernodeptr->minPing = atoi( Info_ValueForKey( info, "minPing") ); servernodeptr->maxPing = atoi( Info_ValueForKey( info, "maxPing") ); servernodeptr->bPB = (qboolean)atoi( Info_ValueForKey( info, "punkbuster") ); // ***GREGS_VC9_PORT_MOD*** -- added typecast(s) /* s = Info_ValueForKey( info, "nettype" ); for (i=0; ;i++) { if (!netnames[i]) { servernodeptr->nettype = 0; break; } else if (!Q_stricmp( netnames[i], s )) { servernodeptr->nettype = i; break; } } */ servernodeptr->nettype = atoi(Info_ValueForKey(info, "nettype")); s = Info_ValueForKey( info, "game"); i = atoi( Info_ValueForKey( info, "gametype") ); if( i < 0 ) { i = 0; } else if( i > 11 ) { i = 12; } if( *s ) { servernodeptr->gametype = i;//-1; Q_strncpyz( servernodeptr->gamename, s, sizeof(servernodeptr->gamename) ); } else { servernodeptr->gametype = i; Q_strncpyz( servernodeptr->gamename, gamenames[i], sizeof(servernodeptr->gamename) ); } }