/* ================== SV_WriteDownloadToClient Check to see if the client wants a file, open it if needed and start pumping the client Fill up msg with data ================== */ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) { int curindex; int rate; int blockspersnap; int idPack = 0, missionPack = 0, unreferenced = 1; char errorMessage[1024]; char pakbuf[MAX_QPATH], *pakptr; int numRefPaks; if (!*cl->downloadName) return; // Nothing being downloaded if (!cl->download) { // Chop off filename extension. Com_sprintf(pakbuf, sizeof(pakbuf), "%s", cl->downloadName); pakptr = Q_strrchr(pakbuf, '.'); if(pakptr) { *pakptr = '\0'; // Check for pk3 filename extension if(!Q_stricmp(pakptr + 1, "pk3")) { const char *referencedPaks = FS_ReferencedPakNames(); // Check whether the file appears in the list of referenced // paks to prevent downloading of arbitrary files. Cmd_TokenizeStringIgnoreQuotes(referencedPaks); numRefPaks = Cmd_Argc(); for(curindex = 0; curindex < numRefPaks; curindex++) { if(!FS_FilenameCompare(Cmd_Argv(curindex), pakbuf)) { unreferenced = 0; // now that we know the file is referenced, // check whether it's legal to download it. missionPack = FS_idPak(pakbuf, "missionpack"); idPack = missionPack || FS_idPak(pakbuf, BASEGAME); break; } } } } cl->download = 0; // We open the file here if ( !(sv_allowDownload->integer & DLF_ENABLE) || (sv_allowDownload->integer & DLF_NO_UDP) || idPack || unreferenced || ( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) < 0 ) { // cannot auto-download file if(unreferenced) { Com_Printf("clientDownload: %d : \"%s\" is not referenced and cannot be downloaded.\n", (int) (cl - svs.clients), cl->downloadName); Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" is not referenced and cannot be downloaded.", cl->downloadName); } else if (idPack) { Com_Printf("clientDownload: %d : \"%s\" cannot download id pk3 files\n", (int) (cl - svs.clients), cl->downloadName); if (missionPack) { Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload Team Arena file \"%s\"\n" "The Team Arena mission pack can be found in your local game store.", cl->downloadName); } else { Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload id pk3 file \"%s\"", cl->downloadName); } } else if ( !(sv_allowDownload->integer & DLF_ENABLE) || (sv_allowDownload->integer & DLF_NO_UDP) ) { Com_Printf("clientDownload: %d : \"%s\" download disabled", (int) (cl - svs.clients), cl->downloadName); if (sv_pure->integer) { Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n" "You will need to get this file elsewhere before you " "can connect to this pure server.\n", cl->downloadName); } else { Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n" "The server you are connecting to is not a pure server, " "set autodownload to No in your settings and you might be " "able to join the game anyway.\n", cl->downloadName); } } else { // NOTE TTimo this is NOT supposed to happen unless bug in our filesystem scheme? // if the pk3 is referenced, it must have been found somewhere in the filesystem Com_Printf("clientDownload: %d : \"%s\" file not found on server\n", (int) (cl - svs.clients), cl->downloadName); Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" not found on server for autodownloading.\n", cl->downloadName); } MSG_WriteByte( msg, svc_download ); MSG_WriteShort( msg, 0 ); // client is expecting block zero MSG_WriteLong( msg, -1 ); // illegal file size MSG_WriteString( msg, errorMessage ); *cl->downloadName = 0; if(cl->download) FS_FCloseFile(cl->download); return; } Com_Printf( "clientDownload: %d : beginning \"%s\"\n", (int) (cl - svs.clients), cl->downloadName ); // Init cl->downloadCurrentBlock = cl->downloadClientBlock = cl->downloadXmitBlock = 0; cl->downloadCount = 0; cl->downloadEOF = qfalse; } // Perform any reads that we need to while (cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW && cl->downloadSize != cl->downloadCount) { curindex = (cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW); if (!cl->downloadBlocks[curindex]) cl->downloadBlocks[curindex] = Z_Malloc( MAX_DOWNLOAD_BLKSIZE ); cl->downloadBlockSize[curindex] = FS_Read( cl->downloadBlocks[curindex], MAX_DOWNLOAD_BLKSIZE, cl->download ); if (cl->downloadBlockSize[curindex] < 0) { // EOF right now cl->downloadCount = cl->downloadSize; break; } cl->downloadCount += cl->downloadBlockSize[curindex]; // Load in next block cl->downloadCurrentBlock++; } // Check to see if we have eof condition and add the EOF block if (cl->downloadCount == cl->downloadSize && !cl->downloadEOF && cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW) { cl->downloadBlockSize[cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW] = 0; cl->downloadCurrentBlock++; cl->downloadEOF = qtrue; // We have added the EOF block } // Loop up to window size times based on how many blocks we can fit in the // client snapMsec and rate // based on the rate, how many bytes can we fit in the snapMsec time of the client // normal rate / snapshotMsec calculation rate = cl->rate; if ( sv_maxRate->integer ) { if ( sv_maxRate->integer < 1000 ) { Cvar_Set( "sv_MaxRate", "1000" ); } if ( sv_maxRate->integer < rate ) { rate = sv_maxRate->integer; } } if ( sv_minRate->integer ) { if ( sv_minRate->integer < 1000 ) Cvar_Set( "sv_minRate", "1000" ); if ( sv_minRate->integer > rate ) rate = sv_minRate->integer; } if (!rate) { blockspersnap = 1; } else { blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) / MAX_DOWNLOAD_BLKSIZE; } if (blockspersnap < 0) blockspersnap = 1; while (blockspersnap--) { // Write out the next section of the file, if we have already reached our window, // automatically start retransmitting if (cl->downloadClientBlock == cl->downloadCurrentBlock) return; // Nothing to transmit if (cl->downloadXmitBlock == cl->downloadCurrentBlock) { // We have transmitted the complete window, should we start resending? //FIXME: This uses a hardcoded one second timeout for lost blocks //the timeout should be based on client rate somehow if (svs.time - cl->downloadSendTime > 1000) cl->downloadXmitBlock = cl->downloadClientBlock; else return; } // Send current block curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW); MSG_WriteByte( msg, svc_download ); MSG_WriteShort( msg, cl->downloadXmitBlock ); // block zero is special, contains file size if ( cl->downloadXmitBlock == 0 ) MSG_WriteLong( msg, cl->downloadSize ); MSG_WriteShort( msg, cl->downloadBlockSize[curindex] ); // Write the block if ( cl->downloadBlockSize[curindex] ) { MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] ); } Com_DPrintf( "clientDownload: %d : writing block %d\n", (int) (cl - svs.clients), cl->downloadXmitBlock ); // Move on to the next block // It will get sent with next snap shot. The rate will keep us in line. cl->downloadXmitBlock++; cl->downloadSendTime = svs.time; } }
/* ================== SV_RehashBans_f Load saved bans from file. ================== */ static void SV_RehashBans_f( void ) { int index, filelen; fileHandle_t readfrom; char *textbuf, *curpos, *maskpos, *newlinepos, *endpos; char filepath[MAX_QPATH]; // make sure server is running if ( !com_sv_running->integer ) { return; } serverBansCount = 0; if ( !sv_banFile->string || !*sv_banFile->string ) return; Com_sprintf( filepath, sizeof( filepath ), "%s/%s", FS_GetCurrentGameDir(), sv_banFile->string ); if ( (filelen = FS_SV_FOpenFileRead( filepath, &readfrom )) >= 0 ) { if ( filelen < 2 ) { // Don't bother if file is too short. FS_FCloseFile( readfrom ); return; } curpos = textbuf = (char *)Z_Malloc( filelen, TAG_TEMP_WORKSPACE ); filelen = FS_Read( textbuf, filelen, readfrom ); FS_FCloseFile( readfrom ); endpos = textbuf + filelen; for ( index = 0; index < SERVER_MAXBANS && curpos + 2 < endpos; index++ ) { // find the end of the address string for ( maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++ ); if ( maskpos + 1 >= endpos ) break; *maskpos = '\0'; maskpos++; // find the end of the subnet specifier for ( newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++ ); if ( newlinepos >= endpos ) break; *newlinepos = '\0'; if ( NET_StringToAdr( curpos + 2, &serverBans[index].ip ) ) { serverBans[index].isexception = (qboolean)(curpos[0] != '0'); serverBans[index].subnet = atoi( maskpos ); if ( serverBans[index].ip.type == NA_IP && (serverBans[index].subnet < 1 || serverBans[index].subnet > 32) ) { serverBans[index].subnet = 32; } } curpos = newlinepos + 1; } serverBansCount = index; Z_Free( textbuf ); } }
/* ================== SV_RehashBans_f Load saved bans from file. ================== */ static void SV_RehashBans_f(void) { int index, filelen; fileHandle_t readfrom; char *textbuf, *curpos, *maskpos, *newlinepos, *endpos; char filepath[MAX_QPATH]; serverBansCount = 0; if(!sv_banFile->string || !*sv_banFile->string) return; if(!(curpos = Cvar_VariableString("fs_game")) || !*curpos) curpos = BASEGAME; Com_sprintf(filepath, sizeof(filepath), "%s/%s", curpos, sv_banFile->string); if((filelen = FS_SV_FOpenFileRead(filepath, &readfrom)) >= 0) { if(filelen < 2) { // Don't bother if file is too short. FS_FCloseFile(readfrom); return; } curpos = textbuf = Z_Malloc(filelen); filelen = FS_Read(textbuf, filelen, readfrom); FS_FCloseFile(readfrom); endpos = textbuf + filelen; for(index = 0; index < SERVER_MAXBANS && curpos + 2 < endpos; index++) { // find the end of the address string for(maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++); if(maskpos + 1 >= endpos) break; *maskpos = '\0'; maskpos++; // find the end of the subnet specifier for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++); if(newlinepos >= endpos) break; *newlinepos = '\0'; if(NET_StringToAdr(curpos + 2, &serverBans[index].ip, NA_UNSPEC)) { serverBans[index].isexception = (curpos[0] != '0'); serverBans[index].subnet = atoi(maskpos); if(serverBans[index].ip.type == NA_IP && (serverBans[index].subnet < 1 || serverBans[index].subnet > 32)) { serverBans[index].subnet = 32; } else if(serverBans[index].ip.type == NA_IP6 && (serverBans[index].subnet < 1 || serverBans[index].subnet > 128)) { serverBans[index].subnet = 128; } } curpos = newlinepos + 1; } serverBansCount = index; Z_Free(textbuf); } }
/* ================== SV_WriteDownloadToClient Check to see if the client wants a file, open it if needed and start pumping the client Fill up msg with data ================== */ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) { int curindex; int rate; int blockspersnap; int idPack, missionPack; char errorMessage[1024]; if (!*cl->downloadName) return; // Nothing being downloaded if (!cl->download) { // We open the file here Com_Printf( "clientDownload: %d : begining \"%s\"\n", cl - svs.clients, cl->downloadName ); missionPack = FS_idPak(cl->downloadName, "missionpack"); idPack = missionPack || FS_idPak(cl->downloadName, "baseq3"); if ( !sv_allowDownload->integer || idPack || ( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) <= 0 ) { // cannot auto-download file if (idPack) { Com_Printf("clientDownload: %d : \"%s\" cannot download id pk3 files\n", cl - svs.clients, cl->downloadName); if (missionPack) { Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload Team Arena file \"%s\"\n" "The Team Arena mission pack can be found in your local game store.", cl->downloadName); } else { Com_sprintf(errorMessage, sizeof(errorMessage), "Cannot autodownload id pk3 file \"%s\"", cl->downloadName); } } else if ( !sv_allowDownload->integer ) { Com_Printf("clientDownload: %d : \"%s\" download disabled", cl - svs.clients, cl->downloadName); if (sv_pure->integer) { Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n" "You will need to get this file elsewhere before you " "can connect to this pure server.\n", cl->downloadName); } else { Com_sprintf(errorMessage, sizeof(errorMessage), "Could not download \"%s\" because autodownloading is disabled on the server.\n\n" "The server you are connecting to is not a pure server, " "set autodownload to No in your settings and you might be " "able to join the game anyway.\n", cl->downloadName); } } else { // NOTE TTimo this is NOT supposed to happen unless bug in our filesystem scheme? // if the pk3 is referenced, it must have been found somewhere in the filesystem Com_Printf("clientDownload: %d : \"%s\" file not found on server\n", cl - svs.clients, cl->downloadName); Com_sprintf(errorMessage, sizeof(errorMessage), "File \"%s\" not found on server for autodownloading.\n", cl->downloadName); } MSG_WriteByte( msg, svc_download ); MSG_WriteShort( msg, 0 ); // client is expecting block zero MSG_WriteLong( msg, -1 ); // illegal file size MSG_WriteString( msg, errorMessage ); *cl->downloadName = 0; return; } // Init cl->downloadCurrentBlock = cl->downloadClientBlock = cl->downloadXmitBlock = 0; cl->downloadCount = 0; cl->downloadEOF = qfalse; } // Perform any reads that we need to while (cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW && cl->downloadSize != cl->downloadCount) { curindex = (cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW); if (!cl->downloadBlocks[curindex]) cl->downloadBlocks[curindex] = Z_Malloc( MAX_DOWNLOAD_BLKSIZE ); cl->downloadBlockSize[curindex] = FS_Read( cl->downloadBlocks[curindex], MAX_DOWNLOAD_BLKSIZE, cl->download ); if (cl->downloadBlockSize[curindex] < 0) { // EOF right now cl->downloadCount = cl->downloadSize; break; } cl->downloadCount += cl->downloadBlockSize[curindex]; // Load in next block cl->downloadCurrentBlock++; } // Check to see if we have eof condition and add the EOF block if (cl->downloadCount == cl->downloadSize && !cl->downloadEOF && cl->downloadCurrentBlock - cl->downloadClientBlock < MAX_DOWNLOAD_WINDOW) { cl->downloadBlockSize[cl->downloadCurrentBlock % MAX_DOWNLOAD_WINDOW] = 0; cl->downloadCurrentBlock++; cl->downloadEOF = qtrue; // We have added the EOF block } // Loop up to window size times based on how many blocks we can fit in the // client snapMsec and rate // based on the rate, how many bytes can we fit in the snapMsec time of the client // normal rate / snapshotMsec calculation rate = cl->rate; if ( sv_maxRate->integer ) { if ( sv_maxRate->integer < 1000 ) { Cvar_Set( "sv_MaxRate", "1000" ); } if ( sv_maxRate->integer < rate ) { rate = sv_maxRate->integer; } } if (!rate) { blockspersnap = 1; } else { blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) / MAX_DOWNLOAD_BLKSIZE; } if (blockspersnap < 0) blockspersnap = 1; while (blockspersnap--) { // Write out the next section of the file, if we have already reached our window, // automatically start retransmitting if (cl->downloadClientBlock == cl->downloadCurrentBlock) return; // Nothing to transmit if (cl->downloadXmitBlock == cl->downloadCurrentBlock) { // We have transmitted the complete window, should we start resending? //FIXME: This uses a hardcoded one second timeout for lost blocks //the timeout should be based on client rate somehow if (svs.time - cl->downloadSendTime > 1000) cl->downloadXmitBlock = cl->downloadClientBlock; else return; } // Send current block curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW); MSG_WriteByte( msg, svc_download ); MSG_WriteShort( msg, cl->downloadXmitBlock ); // block zero is special, contains file size if ( cl->downloadXmitBlock == 0 ) MSG_WriteLong( msg, cl->downloadSize ); MSG_WriteShort( msg, cl->downloadBlockSize[curindex] ); // Write the block if ( cl->downloadBlockSize[curindex] ) { MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] ); } Com_DPrintf( "clientDownload: %d : writing block %d\n", cl - svs.clients, cl->downloadXmitBlock ); // Move on to the next block // It will get sent with next snap shot. The rate will keep us in line. cl->downloadXmitBlock++; cl->downloadSendTime = svs.time; } }
unsigned int _GeoIP_seek_record ( unsigned long ipnum ) { fileHandle_t file; int depth; unsigned int x; unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; const unsigned char *buf = stack_buffer; unsigned int offset = 0; const unsigned char * p; int j; FS_SV_FOpenFileRead("GeoIP.dat", &file); if(!file){ Com_Printf("File Read error.\n"); return 0; } /* unsigned char *data; = malloc(1024*1024*2); if(!FS_Seek(file, 0, SEEK_SET)){ FS_Read(data , 1024*1024*2, file); } */ unsigned int foffset; for (depth = 31; depth >= 0; depth--) { /* read from disk */ foffset = (long)RECORD_LENGTH * 2 *offset; if(!FS_Seek(file, foffset, FS_SEEK_SET)){ FS_Read(stack_buffer , RECORD_LENGTH * 2, file); } /* simply point to record in memory */ // buf = data + (long)RECORD_LENGTH * 2 *offset; if (ipnum & (1 << depth)) { /* Take the right-hand branch */ if ( RECORD_LENGTH == 3 ) { /* Most common case is completely unrolled and uses constants. */ x = (buf[3*1 + 0] << (0*8)) + (buf[3*1 + 1] << (1*8)) + (buf[3*1 + 2] << (2*8)); } else { /* General case */ j = RECORD_LENGTH; p = &buf[2*j]; x = 0; do { x <<= 8; x += *(--p); } while ( --j ); } } else { /* Take the left-hand branch */ if ( RECORD_LENGTH == 3 ) { /* Most common case is completely unrolled and uses constants. */ x = (buf[3*0 + 0] << (0*8)) + (buf[3*0 + 1] << (1*8)) + (buf[3*0 + 2] << (2*8)); } else { /* General case */ j = RECORD_LENGTH; p = &buf[1*j]; x = 0; do { x <<= 8; x += *(--p); } while ( --j ); } } if (x >= BEGIN_OFFSET) { //gi->netmask = gl->netmask = 32 - depth; FS_FCloseFile(file); return x - BEGIN_OFFSET; } offset = x; } /* shouldn't reach here */ Com_PrintError("Traversing Database for ipnum = %lu - Perhaps database is corrupt?\n",ipnum); FS_FCloseFile(file); return 0; }
/* ================== SV_RehashServerRconFile Helper to reload a "serverRcon_t" type of file Returns number of entries loaded ================== */ static int SV_RehashServerRconFile(convar_t *fileName, int maxEntries, serverRcon_t buffer[]) { int index, filelen, numEntries = 0; fileHandle_t readfrom; char *textbuf, *curpos, *maskpos, *newlinepos, *endpos, filepath[MAX_QPATH]; if(!fileName->string || !*fileName->string) { goto exit; } if(!(curpos = Cvar_VariableString("fs_game")) || !*curpos) { curpos = BASEGAME; } Com_sprintf(filepath, sizeof(filepath), "%s/%s", curpos, fileName->string); if((filelen = FS_SV_FOpenFileRead(filepath, &readfrom)) < 0) { Com_Printf("SV_RehashServerRconFile: failed to open %s\n", filepath); goto exit; } if(filelen < 2) { // Don't bother if file is too short. FS_FCloseFile(readfrom); goto exit; } curpos = textbuf = (char*)Z_Malloc(filelen); filelen = FS_Read(textbuf, filelen, readfrom); FS_FCloseFile(readfrom); endpos = textbuf + filelen; for(index = 0; index < maxEntries && curpos + 2 < endpos; index++) { // find the end of the address string for(maskpos = curpos + 2; maskpos < endpos && *maskpos != ' '; maskpos++); if(maskpos + 1 >= endpos) { break; } *maskpos = '\0'; maskpos++; // find the end of the subnet specifier for(newlinepos = maskpos; newlinepos < endpos && *newlinepos != '\n'; newlinepos++); if(newlinepos >= endpos) { break; } *newlinepos = '\0'; if(NET_StringToAdr(curpos + 2, &buffer[index].ip, NA_UNSPEC)) { buffer[index].isexception = (qboolean)(curpos[0] != '0'); buffer[index].subnet = atoi(maskpos); if(buffer[index].ip.type == NA_IP && (buffer[index].subnet < 1 || buffer[index].subnet > 32)) { buffer[index].subnet = 32; } else if(buffer[index].ip.type == NA_IP6 && (buffer[index].subnet < 1 || buffer[index].subnet > 128)) { buffer[index].subnet = 128; } } curpos = newlinepos + 1; } Z_Free(textbuf); numEntries = index; exit: return numEntries; }
/* ==================== SV_ParseVersionMapping Reads versionmap.cfg which sets up a mapping of client version to installer to download ==================== */ void SV_ParseVersionMapping( void ) { int handle; char *filename = "versionmap.cfg"; char *buf; char *buftrav; char *token; int len; len = FS_SV_FOpenFileRead( filename, &handle ); if ( len >= 0 ) { // the file exists buf = (char *)Z_Malloc( len + 1 ); memset( buf, 0, len + 1 ); FS_Read( (void *)buf, len, handle ); FS_FCloseFile( handle ); // now parse the file, setting the version table info buftrav = buf; token = COM_Parse( &buftrav ); if ( strcmp( token, "RTCW-VersionMap" ) ) { Z_Free( buf ); Com_Error( ERR_FATAL, "invalid versionmap.cfg" ); return; } Com_Printf( "\n------------Update Server-------------\n\nParsing version map..." ); while ( ( token = COM_Parse( &buftrav ) ) && token[0] ) { // read the version number strcpy( versionMap[ numVersions ].version, token ); // read the platform token = COM_Parse( &buftrav ); if ( token && token[0] ) { strcpy( versionMap[ numVersions ].platform, token ); } else { Z_Free( buf ); Com_Error( ERR_FATAL, "error parsing versionmap.cfg, after %s", versionMap[ numVersions ].version ); return; } // read the installer name token = COM_Parse( &buftrav ); if ( token && token[0] ) { strcpy( versionMap[ numVersions ].installer, token ); } else { Z_Free( buf ); Com_Error( ERR_FATAL, "error parsing versionmap.cfg, after %s", versionMap[ numVersions ].platform ); return; } numVersions++; if ( numVersions >= MAX_UPDATE_VERSIONS ) { Z_Free( buf ); Com_Error( ERR_FATAL, "Exceeded maximum number of mappings(%d)", MAX_UPDATE_VERSIONS ); return; } } Com_Printf( " found %d mapping%c\n--------------------------------------\n\n", numVersions, numVersions > 1 ? 's' : ' ' ); Z_Free( buf ); } else { Com_Error( ERR_FATAL, "Couldn't open versionmap.cfg" ); } }
/* ==================== LAN_LoadCachedServers ==================== */ void LAN_LoadCachedServers() { #if defined RTCW_SP // TTimo: stub, this is only relevant to MP, SP kills the servercache.dat (and favorites) // show_bug.cgi?id=445 /* int size; fileHandle_t fileIn; cls.numglobalservers = cls.nummplayerservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; if (FS_SV_FOpenFileRead("servercache.dat", &fileIn)) { FS_Read(&cls.numglobalservers, sizeof(int), fileIn); FS_Read(&cls.nummplayerservers, sizeof(int), fileIn); FS_Read(&cls.numfavoriteservers, sizeof(int), fileIn); FS_Read(&size, sizeof(int), fileIn); if (size == sizeof(cls.globalServers) + sizeof(cls.favoriteServers) + sizeof(cls.mplayerServers)) { FS_Read(&cls.globalServers, sizeof(cls.globalServers), fileIn); FS_Read(&cls.mplayerServers, sizeof(cls.mplayerServers), fileIn); FS_Read(&cls.favoriteServers, sizeof(cls.favoriteServers), fileIn); } else { cls.numglobalservers = cls.nummplayerservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; } FS_FCloseFile(fileIn); } */ #elif defined RTCW_MP int size; fileHandle_t fileIn; cls.numglobalservers = cls.nummplayerservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; if ( FS_SV_FOpenFileRead( "servercache.dat", &fileIn ) ) { FS_Read( &cls.numglobalservers, sizeof( int ), fileIn ); FS_Read( &cls.nummplayerservers, sizeof( int ), fileIn ); FS_Read( &cls.numfavoriteservers, sizeof( int ), fileIn ); FS_Read( &size, sizeof( int ), fileIn ); if ( size == sizeof( cls.globalServers ) + sizeof( cls.favoriteServers ) + sizeof( cls.mplayerServers ) ) { FS_Read( &cls.globalServers, sizeof( cls.globalServers ), fileIn ); FS_Read( &cls.mplayerServers, sizeof( cls.mplayerServers ), fileIn ); FS_Read( &cls.favoriteServers, sizeof( cls.favoriteServers ), fileIn ); } else { cls.numglobalservers = cls.nummplayerservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; } FS_FCloseFile( fileIn ); } #else int size; fileHandle_t fileIn; char filename[MAX_QPATH]; cls.numglobalservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; if ( com_gameInfo.usesProfiles && cl_profile->string[0] ) { Com_sprintf( filename, sizeof( filename ), "profiles/%s/servercache.dat", cl_profile->string ); } else { Q_strncpyz( filename, "servercache.dat", sizeof( filename ) ); } // Arnout: moved to mod/profiles dir //if (FS_SV_FOpenFileRead(filename, &fileIn)) { if ( FS_FOpenFileRead( filename, &fileIn, qtrue ) ) { FS_Read( &cls.numglobalservers, sizeof( int ), fileIn ); FS_Read( &cls.numfavoriteservers, sizeof( int ), fileIn ); FS_Read( &size, sizeof( int ), fileIn ); if ( size == sizeof( cls.globalServers ) + sizeof( cls.favoriteServers ) ) { FS_Read( &cls.globalServers, sizeof( cls.globalServers ), fileIn ); FS_Read( &cls.favoriteServers, sizeof( cls.favoriteServers ), fileIn ); } else { cls.numglobalservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; } FS_FCloseFile( fileIn ); } #endif // RTCW_XX }