void ServerList_LoadStoredList(int source) { ServerStorageList* list = NULL; int* sCount = NULL; serverInfo_t* servers = NULL; switch (source) { case 0: list = &historyList; sCount = &cls.numhistoryservers; servers = &cls.historyServers[0]; break; case 2: list = &favoritesList; sCount = &cls.numfavoriteservers; servers = &cls.favoriteServers[0]; break; } int count = ServerStorage_GetNumEntries(list); int si = 0; for (int i = 0; i < count; i++) { // build net address ServerStorageEntry* entry = ServerStorage_GetEntry(list, i); // older versions of the code stored non-NA_IP servers; to not error out we skip those here if (entry->address.type != NA_IP) { continue; } serverInfo_t* server = &servers[si]; serverAddress_t adr; adr.ip[0] = entry->address.ip[0]; adr.ip[1] = entry->address.ip[1]; adr.ip[2] = entry->address.ip[2]; adr.ip[3] = entry->address.ip[3]; adr.port = entry->address.port; CL_InitServerInfo(server, &adr); si++; } *sCount = si; }
/* ================== CL_UpdateVisiblePings_f ================== */ qbool CL_UpdateVisiblePings_f(int source) { int slots, i; char buff[MAX_STRING_CHARS]; int pingTime; int max; qbool status = qfalse; if (source < 0 || source > AS_FAVORITES) { return qfalse; } cls.pingUpdateSource = source; slots = CL_GetPingQueueCount(); if (slots < MAX_PINGREQUESTS) { serverInfo_t *server = NULL; max = (source == AS_GLOBAL) ? MAX_GLOBAL_SERVERS : MAX_OTHER_SERVERS; switch (source) { case AS_LOCAL : server = &cls.localServers[0]; max = cls.numlocalservers; break; case AS_MPLAYER : server = &cls.mplayerServers[0]; max = cls.nummplayerservers; break; case AS_GLOBAL : server = &cls.globalServers[0]; max = cls.numglobalservers; break; case AS_FAVORITES : server = &cls.favoriteServers[0]; max = cls.numfavoriteservers; break; } for (i = 0; i < max; i++) { if (server[i].visible) { if (server[i].ping == -1) { int j; if (slots >= MAX_PINGREQUESTS) { break; } for (j = 0; j < MAX_PINGREQUESTS; j++) { if (!cl_pinglist[j].adr.port) { continue; } if (NET_CompareAdr( cl_pinglist[j].adr, server[i].adr)) { // already on the list break; } } if (j >= MAX_PINGREQUESTS) { status = qtrue; for (j = 0; j < MAX_PINGREQUESTS; j++) { if (!cl_pinglist[j].adr.port) { break; } } memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t)); cl_pinglist[j].start = cls.realtime; cl_pinglist[j].time = 0; NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" ); slots++; } } // if the server has a ping higher than cl_maxPing or // the ping packet got lost else if (server[i].ping == 0) { // if we are updating global servers if (source == AS_GLOBAL) { // if ( cls.numGlobalServerAddresses > 0 ) { // overwrite this server with one from the additional global servers cls.numGlobalServerAddresses--; CL_InitServerInfo(&server[i], &cls.globalServerAddresses[cls.numGlobalServerAddresses]); // NOTE: the server[i].visible flag stays untouched } } } } } } if (slots) { status = qtrue; } for (i = 0; i < MAX_PINGREQUESTS; i++) { if (!cl_pinglist[i].adr.port) { continue; } CL_GetPing( i, buff, MAX_STRING_CHARS, &pingTime ); if (pingTime != 0) { CL_ClearPing(i); status = qtrue; } } return status; }
void CL_ServersResponsePacket( const netadr_t& from, msg_t *msg ) { int i, count, max, total; serverAddress_t addresses[MAX_SERVERSPERPACKET]; int numservers; byte* buffptr; byte* buffend; Com_Printf("CL_ServersResponsePacket\n"); if (cls.numglobalservers == -1) { // state to detect lack of servers or lack of response cls.numglobalservers = 0; 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) { // advance to initial token do { if (*buffptr++ == '\\') break; } while (buffptr < buffend); if ( buffptr >= buffend - 6 ) { break; } // parse out ip addresses[numservers].ip[0] = *buffptr++; addresses[numservers].ip[1] = *buffptr++; addresses[numservers].ip[2] = *buffptr++; addresses[numservers].ip[3] = *buffptr++; // parse out port addresses[numservers].port = (*buffptr++)<<8; addresses[numservers].port += *buffptr++; addresses[numservers].port = BigShort( addresses[numservers].port ); // syntax check if (*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) { break; } // parse out EOT 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; } for (i = 0; i < numservers && count < max; i++) { // build net address serverInfo_t *server = (cls.masterNum == 0) ? &cls.globalServers[count] : &cls.mplayerServers[count]; CL_InitServerInfo( server, &addresses[i] ); // advance to next slot count++; } // 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 (cls.masterNum == 0) { cls.numglobalservers = count; total = count + cls.numGlobalServerAddresses; } else { cls.nummplayerservers = count; total = count; } Com_Printf("%d servers parsed (total %d)\n", numservers, total); }
/* =================== CL_ServersResponsePacket =================== */ void CL_ServersResponsePacket( msg_t *msg ) { int i, count, max, total; serverAddress_t addresses[MAX_SERVERSPERPACKET]; int numservers; char* buffptr; char* buffend; Com_Printf(0, "CL_ServersResponsePacket\n"); if (cls.numglobalservers == -1) { // state to detect lack of servers or lack of response cls.numglobalservers = 0; cls.numGlobalServerAddresses = 0; } // parse through server response string numservers = 0; buffptr = msg->data; buffend = buffptr + msg->cursize; while (buffptr+1 < buffend) { // advance to initial token do { if (*buffptr++ == '\\') break; } while (buffptr < buffend); if ( buffptr >= buffend - 6 ) { break; } // parse out ip addresses[numservers].ip[0] = *buffptr++; addresses[numservers].ip[1] = *buffptr++; addresses[numservers].ip[2] = *buffptr++; addresses[numservers].ip[3] = *buffptr++; // parse out port addresses[numservers].port = (*(buffptr++))<<8; addresses[numservers].port += (*(buffptr++)) & 0xFF; addresses[numservers].port = ntohs( addresses[numservers].port ); // syntax check if (*buffptr != '\\') { break; } /*Com_DPrintf( 0, "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], ntohs(addresses[numservers].port) );*/ numservers++; if (numservers >= MAX_SERVERSPERPACKET) { break; } // parse out EOT if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') { break; } } count = cls.numglobalservers; max = MAX_GLOBAL_SERVERS; for (i = 0; i < numservers && count < max; i++) { // check if this server already exists netadr_t address; address.type = NA_IP; address.ip[0] = addresses[i].ip[0]; address.ip[1] = addresses[i].ip[1]; address.ip[2] = addresses[i].ip[2]; address.ip[3] = addresses[i].ip[3]; address.port = addresses[i].port; bool alreadyExists = false; for (int j = 0; j < cls.numglobalservers; j++) { if (NET_CompareAdr(cls.globalServers[j].adr, address)) { alreadyExists = true; break; } } if (alreadyExists) { continue; } // build net address serverInfo_t *server = &cls.globalServers[count]; CL_InitServerInfo( server, &addresses[i] ); // advance to next slot count++; } // 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; } } } cls.numglobalservers = count; total = count + cls.numGlobalServerAddresses; Com_Printf(0, "%d servers parsed (total %d)\n", numservers, total); }
qboolean CL_UpdateVisiblePings_f(int source) { int slots, i; char buff[8192]; int pingTime; int max; qboolean status = false; cls.pingUpdateSource = source; slots = CL_GetPingQueueCount(); if (slots < MAX_PINGREQUESTS) { serverInfo_t *server = NULL; switch (source) { case 0: server = &cls.historyServers[0]; max = cls.numhistoryservers; break; case 1: server = &cls.globalServers[0]; max = cls.numglobalservers; break; case 2: server = &cls.favoriteServers[0]; max = cls.numfavoriteservers; break; } for (i = 0; i < max; i++) { if (server[i].visible) { if (server[i].adr.type != NA_IP) { continue;; } if (server[i].ping == -1) { int j; if (slots >= MAX_PINGREQUESTS) { break; } for (j = 0; j < MAX_PINGREQUESTS; j++) { if (!cl_pinglist[j].adr.port) { continue; } if (NET_CompareAdr( cl_pinglist[j].adr, server[i].adr)) { // already on the list break; } } if (j >= MAX_PINGREQUESTS) { status = true; for (j = 0; j < MAX_PINGREQUESTS; j++) { if (!cl_pinglist[j].adr.port) { break; } } memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t)); cl_pinglist[j].start = timeGetTime(); cl_pinglist[j].time = 0; NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" ); slots++; } } // if the server has a ping higher than cl_maxPing or // the ping packet got lost else if (server[i].ping == 0) { // if we are updating global servers if ( source == 1 && cls.numGlobalServerAddresses > 0 ) { // overwrite this server with one from the additional global servers cls.numGlobalServerAddresses--; CL_InitServerInfo(&server[i], &cls.globalServerAddresses[cls.numGlobalServerAddresses]); // NOTE: the server[i].visible flag stays untouched } } } } } if (slots) { status = true; } for (i = 0; i < MAX_PINGREQUESTS; i++) { if (!cl_pinglist[i].adr.port) { continue; } CL_GetPing( i, buff, 8192, &pingTime ); if (pingTime != 0) { CL_ClearPing(i); status = true; } } return status; }