/* * ML_GetFullname * Returns the fullname for the map with the corresponding filename */ const char *ML_GetFullname( const char *filename ) { mapinfo_t *map; //char *filepath; if( !ml_initialized ) return MLIST_NULL; if( !ML_ValidateFilename( filename ) ) return MLIST_NULL; /* filepath = va( "maps/%s.bsp", filename ); COM_SanitizeFilePath( filepath ); if( FS_FOpenFile( filepath, NULL, FS_READ ) == -1 ) return MLIST_NULL; */ if( Trie_Find( mlist_filenames_trie, filename, TRIE_EXACT_MATCH, (void **)&map ) == TRIE_OK ) return map->fullname; // we should never get down here! assert( false ); return MLIST_NULL; }
/* * ML_AddMap * Handles assigning memory for map and adding it to the list * in alphabetical order */ static void ML_AddMap( const char *filename, const char *fullname ) { mapinfo_t *map; char *buffer; char fullname_[MAX_CONFIGSTRING_CHARS]; if( !ML_ValidateFilename( filename ) ) return; if( !strcmp(filename, "ui") ) return; if( !fullname ) { ML_GetFullnameFromMap( filename, fullname_, sizeof( fullname_ ) ); fullname = fullname_; } if( !ML_ValidateFullname( fullname ) && *fullname ) // allow empty fullnames return; if( !strcmp(fullname, "ui") ) return; ml_flush = true; // tell everyone that maplist has changed buffer = ( char* )Mem_ZoneMalloc( sizeof( mapinfo_t ) + strlen( filename ) + 1 + strlen( fullname ) + 1 ); map = ( mapinfo_t * )buffer; buffer += sizeof( mapinfo_t ); map->filename = buffer; strcpy( map->filename, filename ); COM_StripExtension( map->filename ); buffer += strlen( filename ) + 1; map->fullname = buffer; strcpy( map->fullname, fullname ); COM_RemoveColorTokens( map->fullname ); Q_strlwr( map->fullname ); Trie_Insert( mlist_filenames_trie, map->filename, map ); Trie_Insert( mlist_fullnames_trie, map->fullname, map ); map->next = maplist; maplist = map; }
/* * ML_FilenameExists * Checks to see if a filename is present in the map list */ static bool ML_FilenameExistsExt( const char *filename, bool quick ) { mapinfo_t *map; char *filepath; if( !ml_initialized ) return false; filepath = va( "maps/%s.bsp", filename ); COM_SanitizeFilePath( filepath ); if( !ML_ValidateFilename( filename ) ) return false; if( Trie_Find( mlist_filenames_trie, filename, TRIE_EXACT_MATCH, (void **)&map ) == TRIE_OK ) { if( quick || FS_FOpenFile( filepath, NULL, FS_READ ) != -1 ) return true; } return false; }
/* * SV_Map_f * * User command to change the map * map: restart game, and start map * devmap: restart game, enable cheats, and start map * gamemap: just start the map */ static void SV_Map_f( void ) { char *map; char mapname[MAX_CONFIGSTRING_CHARS]; qboolean found = qfalse; if( Cmd_Argc() < 2 ) { Com_Printf( "Usage: %s <map>\n", Cmd_Argv( 0 ) ); return; } // if map "<map>" is used Cmd_Args() will return the "" as well. if( Cmd_Argc() == 2 ) map = Cmd_Argv( 1 ); else map = Cmd_Args(); Com_DPrintf( "SV_GameMap(%s)\n", map ); // applies to fullnames and filenames (whereas + strlen( "maps/" ) wouldnt) if( strlen( map ) >= MAX_CONFIGSTRING_CHARS ) { Com_Printf( "Map name too long.\n" ); return; } Q_strncpyz( mapname, map, sizeof( mapname ) ); if( ML_ValidateFilename( mapname ) ) { COM_StripExtension( mapname ); if( ML_FilenameExists( mapname ) ) { found = qtrue; } else { ML_Update(); if( ML_FilenameExists( mapname ) ) found = qtrue; } } if( !found ) { if( ML_ValidateFullname( map ) ) { Q_strncpyz( mapname, ML_GetFilename( map ), sizeof( mapname ) ); if( *mapname ) found = qtrue; } if( !found ) { Com_Printf( "Couldn't find map: %s\n", map ); return; } } if( FS_GetNotifications() & FS_NOTIFT_NEWPAKS ) { FS_RemoveNotifications( FS_NOTIFT_NEWPAKS ); sv.state = ss_dead; // don't save current level when changing } else if( !Q_stricmp( Cmd_Argv( 0 ), "map" ) || !Q_stricmp( Cmd_Argv( 0 ), "devmap" ) ) { sv.state = ss_dead; // don't save current level when changing } // start up the next map SV_Map( mapname, !Q_stricmp( Cmd_Argv( 0 ), "devmap" ) ); // archive server state Q_strncpyz( svs.mapcmd, mapname, sizeof( svs.mapcmd ) ); }