/* * Cvar_Find */ cvar_t *Cvar_Find ( const char *var_name ) { cvar_t *cvar; assert( cvar_trie ); Trie_Find( cvar_trie, var_name, TRIE_EXACT_MATCH, (void **)&cvar ); return cvar; }
/* * 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_GetFilename * Returns the filename for the map with the corresponding fullname */ const char *ML_GetFilenameExt( const char *fullname, bool recursive ) { mapinfo_t *map; trie_error_t err; char *fullname2; if( !ml_initialized ) return MLIST_NULL; if( !ML_ValidateFullname( fullname ) ) return MLIST_NULL; fullname2 = ( char* )Mem_TempMalloc( strlen( fullname ) + 1 ); strcpy( fullname2, fullname ); Q_strlwr( fullname2 ); err = Trie_Find( mlist_fullnames_trie, fullname2, TRIE_EXACT_MATCH, (void **)&map ); Mem_Free( fullname2 ); if( err == TRIE_OK ) return map->filename; // we should technically never get here, but // maybe the mapper has changed the fullname of the map // or the user has tampered with the mapcache // we need to reload the whole cache from file if we get here /* if( !recursive ) { ML_Restart( true ); return ML_GetFilenameExt( fullname, true ); } */ return MLIST_NULL; }
/* * CL_ResolveMasterAddress */ static void CL_ResolveMasterAddress( const char *master, netadr_t *adr ) { trie_error_t err; masteradrcache_t *cache; // check memory cache err = Trie_Find( serverlist_masters_trie, master, TRIE_EXACT_MATCH, (void **)&cache ); if( err == TRIE_OK ) { if( adr ) *adr = cache->adr; return; } // send a unicast packet cache = Mem_ZoneMalloc( sizeof( *cache ) ); NET_StringToAddress( master, &cache->adr ); if( adr ) *adr = cache->adr; cache->next = serverlist_masters_head; serverlist_masters_head = cache; Trie_Insert( serverlist_masters_trie, master, (void *)cache ); }
dynvar_t *Dynvar_Lookup( const char *name ) { dynvar_t *dynvar; assert( dynvar_trie ); Trie_Find( dynvar_trie, name, TRIE_EXACT_MATCH, (void **)&dynvar ); return dynvar; }
/* * L10n_LookupString */ const char *L10n_LookupString( const podomain_t *podomain, const char *string ) { const pofile_t *pofile; const podict_t *dict; char *result = NULL; for( pofile = podomain->pofiles_head; pofile; pofile = pofile->next ) { dict = pofile->dict; if( Trie_Find( dict->trie, string, TRIE_EXACT_MATCH, (void **)&result ) == TRIE_OK ) { return result; } } return result; }
/* * 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; }
/* * CL_GetServers_f */ void CL_GetServers_f( void ) { netadr_t adr, *padr; char *requeststring; int i; char *modname, *master; trie_error_t err; filter_allow_full = qfalse; filter_allow_empty = qfalse; for( i = 2; i < Cmd_Argc(); i++ ) { if( !Q_stricmp( "full", Cmd_Argv( i ) ) ) filter_allow_full = qtrue; if( !Q_stricmp( "empty", Cmd_Argv( i ) ) ) filter_allow_empty = qtrue; } if( !Q_stricmp( Cmd_Argv( 1 ), "local" ) ) { if( localQueryTimeStamp + LAN_SERVER_PINGING_TIMEOUT > Sys_Milliseconds() ) { return; } padr = &adr; localQueryTimeStamp = Sys_Milliseconds(); // send a broadcast packet Com_DPrintf( "pinging broadcast...\n" ); // erm... modname isn't sent in local queries? requeststring = va( "info %i %s %s", SERVERBROWSER_PROTOCOL_VERSION, filter_allow_full ? "full" : "", filter_allow_empty ? "empty" : "" ); for( i = 0; i < NUM_BROADCAST_PORTS; i++ ) { NET_BroadcastAddress( padr, PORT_SERVER + i ); Netchan_OutOfBandPrint( &cls.socket_udp, padr, requeststring ); } return; } //get what master master = Cmd_Argv( 2 ); if( !master || !( *master ) ) return; modname = Cmd_Argv( 3 ); // never allow anyone to use DEFAULT_BASEGAME as mod name if( !modname || !modname[0] || !Q_stricmp( modname, DEFAULT_BASEGAME ) ) modname = APPLICATION; assert( modname[0] ); // check memory cache QMutex_Lock( resolveLock ); err = Trie_Find( serverlist_masters_trie, master, TRIE_EXACT_MATCH, (void **)&padr ); QMutex_Unlock( resolveLock ); if( err == TRIE_OK && ( padr->type == NA_IP || padr->type == NA_IP6 ) ) { const char *cmdname; socket_t *socket; if ( padr->type == NA_IP ) { cmdname = "getservers"; socket = &cls.socket_udp; } else { cmdname = "getserversExt"; socket = &cls.socket_udp6; } // create the message requeststring = va( "%s %c%s %i %s %s", cmdname, toupper( modname[0] ), modname+1, SERVERBROWSER_PROTOCOL_VERSION, filter_allow_full ? "full" : "", filter_allow_empty ? "empty" : "" ); if( NET_GetAddressPort( padr ) == 0 ) NET_SetAddressPort( padr, PORT_MASTER ); Netchan_OutOfBandPrint( socket, padr, requeststring ); Com_DPrintf( "quering %s...%s: %s\n", master, NET_AddressToString(padr), requeststring ); } else { Com_Printf( "Bad address: %s\n", master ); } }
/* * Cvar_Get * Creates the variable if it doesn't exist. * If the variable already exists, the value will not be set * The flags will be or'ed and default value overwritten in if the variable exists. */ cvar_t *Cvar_Get( const char *var_name, const char *var_value, cvar_flag_t flags ) { cvar_t *var; if( !var_name || !var_name[0] ) return NULL; if( Cvar_FlagIsSet( flags, CVAR_USERINFO ) || Cvar_FlagIsSet( flags, CVAR_SERVERINFO ) ) { if( !Cvar_InfoValidate( var_name, qtrue ) ) { Com_Printf( "invalid info cvar name\n" ); return NULL; } } assert( cvar_trie ); Trie_Find( cvar_trie, var_name, TRIE_EXACT_MATCH, (void **)&var ); if( var ) { assert( var_value ); if( !var->dvalue || strcmp( var->dvalue, var_value ) ) { if( var->dvalue ) Mem_ZoneFree( var->dvalue ); // free the old default value string var->dvalue = ZoneCopyString( (char *) var_value ); } #ifdef PUBLIC_BUILD if( Cvar_FlagIsSet( flags, CVAR_READONLY ) || Cvar_FlagIsSet( flags, CVAR_DEVELOPER ) ) { #else if( Cvar_FlagIsSet( flags, CVAR_READONLY ) ) { #endif if( !var->string || strcmp( var->string, var_value ) ) { if( var->string ) Mem_ZoneFree( var->string ); var->string = ZoneCopyString( (char *) var_value ); var->value = atof( var->string ); var->integer = Q_rint( var->value ); } var->flags = flags; } if( Cvar_FlagIsSet( flags, CVAR_USERINFO ) && !Cvar_FlagIsSet( var->flags, CVAR_USERINFO ) ) userinfo_modified = qtrue; // transmit at next oportunity Cvar_FlagSet( &var->flags, flags ); return var; } if( !var_value ) return NULL; if( Cvar_FlagIsSet( flags, CVAR_USERINFO ) || Cvar_FlagIsSet( flags, CVAR_SERVERINFO ) ) { if( !Cvar_InfoValidate( var_value, qfalse ) ) { Com_Printf( "invalid info cvar value\n" ); return NULL; } } var = Mem_ZoneMalloc( (int)( sizeof( *var ) + strlen( var_name ) + 1 ) ); var->name = (char *)( (qbyte *)var + sizeof( *var ) ); strcpy( var->name, var_name ); var->dvalue = ZoneCopyString( (char *) var_value ); var->string = ZoneCopyString( (char *) var_value ); Cvar_SetModified( var ); var->value = atof( var->string ); var->integer = Q_rint( var->value ); var->flags = flags; Trie_Insert( cvar_trie, var_name, var ); return var; } /* * Cvar_Set2 */ static cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) { cvar_t *var = Cvar_Find( var_name ); if( !var ) { // create it return Cvar_Get( var_name, value, 0 ); } if( Cvar_FlagIsSet( var->flags, CVAR_USERINFO ) || Cvar_FlagIsSet( var->flags, CVAR_SERVERINFO ) ) { if( !Cvar_InfoValidate( value, qfalse ) ) { Com_Printf( "invalid info cvar value\n" ); return var; } } if( !force ) { #ifdef PUBLIC_BUILD if( Cvar_FlagIsSet( var->flags, CVAR_NOSET ) || Cvar_FlagIsSet( var->flags, CVAR_READONLY ) || Cvar_FlagIsSet( var->flags, CVAR_DEVELOPER ) ) { #else if( Cvar_FlagIsSet( var->flags, CVAR_NOSET ) || Cvar_FlagIsSet( var->flags, CVAR_READONLY ) ) { #endif Com_Printf( "%s is write protected.\n", var_name ); return var; } if( Cvar_FlagIsSet( var->flags, CVAR_CHEAT ) && strcmp( value, var->dvalue ) ) { if( !Cvar_CheatsAllowed() ) { Com_Printf( "%s is cheat protected.\n", var_name ); return var; } } if( Cvar_FlagIsSet( var->flags, CVAR_LATCH ) || Cvar_FlagIsSet( var->flags, CVAR_LATCH_VIDEO ) || Cvar_FlagIsSet( var->flags, CVAR_LATCH_SOUND ) ) { if( var->latched_string ) { if( !strcmp( value, var->latched_string ) ) return var; Mem_ZoneFree( var->latched_string ); } else { if( !strcmp( value, var->string ) ) return var; } if( Com_ServerState() ) { Com_Printf( "%s will be changed upon restarting.\n", var->name ); var->latched_string = ZoneCopyString( (char *) value ); } else { if( Cvar_FlagIsSet( var->flags, CVAR_LATCH_VIDEO ) ) { Com_Printf( "%s will be changed upon restarting video.\n", var->name ); var->latched_string = ZoneCopyString( (char *) value ); } else if( Cvar_FlagIsSet( var->flags, CVAR_LATCH_SOUND ) ) { Com_Printf( "%s will be changed upon restarting sound.\n", var->name ); var->latched_string = ZoneCopyString( (char *) value ); } else { if( !strcmp( var->name, "fs_game" ) ) { FS_SetGameDirectory( value, qfalse ); return var; } Mem_ZoneFree( var->string ); // free the old value string var->string = ZoneCopyString( value ); var->value = atof( var->string ); var->integer = Q_rint( var->value ); Cvar_SetModified( var ); } } return var; } } else { if( var->latched_string ) { Mem_ZoneFree( var->latched_string ); var->latched_string = NULL; } } if( !strcmp( value, var->string ) ) return var; // not changed Cvar_SetModified( var ); if( Cvar_FlagIsSet( var->flags, CVAR_USERINFO ) ) userinfo_modified = qtrue; // transmit at next oportunity Mem_ZoneFree( var->string ); // free the old value string var->string = ZoneCopyString( (char *) value ); var->value = atof( var->string ); var->integer = Q_rint( var->value ); return var; } /* * Cvar_ForceSet * Set the variable even if NOSET or LATCH */ cvar_t *Cvar_ForceSet( const char *var_name, const char *value ) { return Cvar_Set2( var_name, value, qtrue ); } /* * Cvar_Set * Create the variable if it doesn't exist */ cvar_t *Cvar_Set( const char *var_name, const char *value ) { return Cvar_Set2( var_name, value, qfalse ); } /* * Cvar_FullSet */ cvar_t *Cvar_FullSet( const char *var_name, const char *value, cvar_flag_t flags, qboolean overwrite_flags ) { cvar_t *var; var = Cvar_Find( var_name ); if( !var ) return Cvar_Get( var_name, value, flags ); if( overwrite_flags ) { var->flags = flags; } else { Cvar_FlagSet( &var->flags, flags ); } // if we overwrite the flags, we will also force the value return Cvar_Set2( var_name, value, overwrite_flags ); }