/* * ML_Update */ bool ML_Update( void ) { int i, len, total, newpaks; size_t size; char *map, *maps, *filename; newpaks = FS_Rescan(); if( !newpaks ) return false; total = FS_GetFileListExt( "maps", ".bsp", NULL, &size, 0, 0 ); if( size ) { maps = ( char* )Mem_TempMalloc( size ); FS_GetFileList( "maps", ".bsp", maps, size, 0, 0 ); for( i = 0, len = 0; i < total; i++ ) { map = maps + len; len += strlen( map ) + 1; filename = ( char * )COM_FileBase( map ); COM_StripExtension( filename ); // don't check for existance of each file itself, as we've just got the fresh list if( !ML_FilenameExistsExt( filename, true ) ) ML_AddMap( filename, MLIST_UNKNOWN_MAPNAME ); } Mem_TempFree( maps ); } return true; }
/* * TV_Upstream_NextDemo */ void TV_Upstream_NextDemo( const char *demoname, const char *curdemo, qboolean randomize, char **name, char **filepath ) { int i, j, total; size_t bufsize, len, dir_size; char *file, *buf, **match, *dir; const char *extension, *pattern, *p; *name = *filepath = NULL; assert( demoname ); assert( *demoname ); buf = NULL; bufsize = 0; total = 0; // check if user specified a demo pattern (e.g. "tutorials/*.wd10") or a demolist filename extension = COM_FileExtension( demoname ); if( extension && !Q_stricmp( extension, APP_DEMO_EXTENSION_STR ) ) pattern = demoname; else pattern = ""; dir_size = strlen( "demos" ) + strlen( pattern ) + 1; dir = Mem_TempMalloc( dir_size ); strcpy( dir, "demos" ); if( *pattern ) { // find first character that looks like a wildcard const char *last_slash = NULL; p = pattern; do { if( *p == '/' ) last_slash = p; else if( *p == '?' || *p == '*' || *p == '[' ) break; } while( *++p ); // append the path part of wildcard to dir and shift the pattern if( last_slash ) { Q_strncatz( dir, "/", dir_size ); Q_strncatz( dir, pattern, strlen( dir ) + (last_slash - pattern) + 1 ); pattern = last_slash + 1; } bufsize = 0; total = FS_GetFileListExt( dir, APP_DEMO_EXTENSION_STR, NULL, &bufsize, 0, 0 ); if( !total ) bufsize = 0; if( bufsize ) { buf = Mem_TempMalloc( bufsize ); FS_GetFileList( dir, APP_DEMO_EXTENSION_STR, buf, bufsize, 0, 0 ); } } else { // load demolist file and pick next available demo int filehandle = 0, filelen = -1; // load list from file filelen = FS_FOpenFile( demoname, &filehandle, FS_READ ); if( filehandle && filelen > 0 ) { bufsize = (size_t)(filelen + 1); buf = Mem_TempMalloc( bufsize ); FS_Read( buf, filelen, filehandle ); FS_FCloseFile( filehandle ); } // parse the list stripping CRLF characters if( buf ) { p = strtok( buf, "\r\n" ); if( p ) { char *newbuf; size_t newbufsize; newbufsize = 0; newbuf = Mem_TempMalloc( bufsize ); while( p != NULL ) { total++; Q_strncpyz( newbuf + newbufsize, p, bufsize - newbufsize ); newbufsize += strlen( p ) + 1; p = strtok( NULL, "\r\n" ); } Mem_TempFree( buf ); buf = newbuf; } } } if( buf ) { int next; // get the list of demo files match = Mem_TempMalloc( total * sizeof( char * ) ); total = 0; next = (randomize ? -1 : 0); for( len = 0; buf[len]; ) { file = buf + len; len += strlen( file ) + 1; if( *pattern ) { if( !Com_GlobMatch( pattern, file, qfalse ) ) continue; } // avoid replays if( curdemo && !Q_stricmp( file, curdemo ) ) { // if ordered, schedule the next map if( !randomize ) next = total; continue; } match[total++] = file; } // pick a new random demo if possible or otherwise try the old one if( total ) { if( next < 0 ) next = rand() % total; // walk the list until we find an existing file // in case of pattern match, the check is not necessary though for( i = 0; i < total; i++ ) { j = (i + next) % total; if( !*pattern ) { extension = COM_FileExtension( match[j] ); if( FS_FOpenFile( va( "demos/%s%s", match[j], (extension ? "" : APP_DEMO_EXTENSION_STR) ), NULL, FS_READ ) == -1 ) continue; } *name = TempCopyString( match[j] ); break; } } // fallback to current demo if( !*name && curdemo ) *name = TempCopyString( curdemo ); Mem_TempFree( match ); // append the dir to filename, sigh.. if( *name ) { size_t filepath_size; filepath_size = strlen( dir ) + strlen( "/" ) + strlen( *name ) + strlen( APP_DEMO_EXTENSION_STR ) + 1; *filepath = Mem_TempMalloc( filepath_size ); strcpy( *filepath, dir ); strcat( *filepath, "/" ); strcat( *filepath, *name ); COM_DefaultExtension( *filepath, APP_DEMO_EXTENSION_STR, filepath_size ); } Mem_TempFree( buf ); } Mem_TempFree( dir ); }
/* * ML_InitFromCache * Fills map list array from cache, much faster */ static void ML_InitFromCache( void ) { int count, i, total, len; size_t size = 0; char *buffer, *chr, *current, *curend; char *temp, *maps, *map; mapdir_t *dir, *curmap, *prev; if( ml_initialized ) return; total = FS_GetFileListExt( "maps", ".bsp", NULL, &size, 0, 0 ); if( !total ) return; // load maps from directory reading into a list maps = temp = ( char* )Mem_TempMalloc( size + sizeof( mapdir_t ) * total ); temp += size; FS_GetFileList( "maps", ".bsp", maps, size, 0, 0 ); len = 0; prev = NULL; dir = NULL; for( i = 0; i < total; i++ ) { map = maps + len; len += strlen( map ) + 1; curmap = ( mapdir_t * )temp; temp += sizeof( mapdir_t ); COM_StripExtension( map ); if( !i ) dir = curmap; else { prev->next = curmap; curmap->prev = prev; } curmap->filename = map; prev = curmap; } FS_LoadCacheFile( MLIST_CACHE, (void **)&buffer, NULL, 0 ); if( !buffer ) { Mem_TempFree( maps ); return; } current = curend = buffer; count = 0; for( chr = buffer; *chr; chr++ ) { // current character is a delimiter if( *chr == '\n' ) { if( *(chr-1) == '\r' ) *(chr-1) = '\0'; // clear the CR too *chr = '\0'; // clear the LF // if we have got both params if( !( ++count & 1 ) ) { // check if its in the maps directory for( curmap = dir; curmap; curmap = curmap->next ) { if( !Q_stricmp( curmap->filename, current ) ) { if( curmap->prev ) curmap->prev->next = curmap->next; else dir = curmap->next; if( curmap->next ) curmap->next->prev = curmap->prev; break; } } // if we found it in the maps directory if( curmap ) { COM_SanitizeFilePath( current ); // well, if we've got a map with an unknown fullname, load it from map if( !strcmp( curend + 1, MLIST_UNKNOWN_MAPNAME ) ) ML_AddMap( current, NULL ); else ML_AddMap( current, curend + 1 ); } current = chr + 1; } else curend = chr; } } // we've now loaded the mapcache, but there may be files which // have been added to maps directory, and the mapcache isnt aware // these will be left over in our directory list for( curmap = dir; curmap; curmap = curmap->next ) ML_AddMap( curmap->filename, NULL ); Mem_TempFree( maps ); FS_FreeFile( buffer ); }
/* * SV_Demo_Purge_f * * Removes the server demo files */ void SV_Demo_Purge_f( void ) { char *buffer; char *p, *s, num[8]; char path[256]; size_t extlen, length, bufSize; unsigned int i, numdemos, numautodemos, maxautodemos; if( Cmd_Argc() > 2 ) { Com_Printf( "Usage: serverrecordpurge [maxautodemos]\n" ); return; } maxautodemos = 0; if( Cmd_Argc() == 2 ) maxautodemos = atoi( Cmd_Argv( 1 ) ); numdemos = FS_GetFileListExt( SV_DEMO_DIR, APP_DEMO_EXTENSION_STR, NULL, &bufSize, 0, 0 ); if( !numdemos ) return; extlen = strlen( APP_DEMO_EXTENSION_STR ); buffer = Mem_TempMalloc( bufSize ); FS_GetFileList( SV_DEMO_DIR, APP_DEMO_EXTENSION_STR, buffer, bufSize, 0, 0 ); numautodemos = 0; s = buffer; for( i = 0; i < numdemos; i++, s += length + 1 ) { length = strlen( s ); if( length < strlen( "_auto9999" ) + extlen ) continue; p = s + length - strlen( "_auto9999" ) - extlen; if( strncmp( p, "_auto", strlen( "_auto" ) ) ) continue; p += strlen( "_auto" ); Q_snprintfz( num, sizeof( num ), "%04i", atoi( p ) ); if( strncmp( p, num, 4 ) ) continue; numautodemos++; } if( numautodemos <= maxautodemos ) { Mem_TempFree( buffer ); return; } s = buffer; for( i = 0; i < numdemos; i++, s += length + 1 ) { length = strlen( s ); if( length < strlen( "_auto9999" ) + extlen ) continue; p = s + length - strlen( "_auto9999" ) - extlen; if( strncmp( p, "_auto", strlen( "_auto" ) ) ) continue; p += strlen( "_auto" ); Q_snprintfz( num, sizeof( num ), "%04i", atoi( p ) ); if( strncmp( p, num, 4 ) ) continue; Q_snprintfz( path, sizeof( path ), "%s/%s", SV_DEMO_DIR, s ); Com_Printf( "Removing old autorecord demo: %s\n", path ); if( !FS_RemoveFile( path ) ) { Com_Printf( "Error, couldn't remove file: %s\n", path ); continue; } if( --numautodemos == maxautodemos ) break; } Mem_TempFree( buffer ); }