diff options
author | Andrey Nazarov <skuller@skuller.net> | 2010-09-07 16:46:20 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2010-09-07 16:46:20 +0000 |
commit | 8f76ac32949a283e000b27f6acd4359aa5de1806 (patch) | |
tree | 39c2088e732aed475e54680eec3ad13733994c26 /source/sv_ccmds.c | |
parent | 9622b711c2b8e4641a778e144cf20ebfc87b12de (diff) |
Re-resolve master servers after one day.
Don't spam server console with ping acks from masters.
Added ‘listmasters’ command for checking IPs and ack times.
Send the first heartbeat soon after server initialization.
Diffstat (limited to 'source/sv_ccmds.c')
-rw-r--r-- | source/sv_ccmds.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/source/sv_ccmds.c b/source/sv_ccmds.c index 329b460..bd20571 100644 --- a/source/sv_ccmds.c +++ b/source/sv_ccmds.c @@ -38,8 +38,10 @@ Specify a list of master servers */ static void SV_SetMaster_f( void ) { netadr_t adr; - int i, j, slot; + int i, total; char *s; + master_t *m, *n; + size_t len; #if USE_CLIENT // only dedicated servers send heartbeats @@ -49,11 +51,16 @@ static void SV_SetMaster_f( void ) { } #endif - memset( &master_adr, 0, sizeof( master_adr ) ); + // free old masters + FOR_EACH_MASTER_SAFE( m, n ) { + Z_Free( m ); + } + + List_Init( &sv_masterlist ); - slot = 0; + total = 0; for( i = 1; i < Cmd_Argc(); i++ ) { - if( slot == MAX_MASTERS ) { + if( total == MAX_MASTERS ) { Com_Printf( "Too many masters.\n" ); break; } @@ -64,21 +71,26 @@ static void SV_SetMaster_f( void ) { continue; } - s = NET_AdrToString( &adr ); - for( j = 0; j < slot; j++ ) { - if( NET_IsEqualBaseAdr( &master_adr[j], &adr ) ) { - Com_Printf( "Ignoring duplicate master at %s.\n", s ); - break; + FOR_EACH_MASTER( m ) { + if( NET_IsEqualBaseAdr( &m->adr, &adr ) ) { + Com_Printf( "Ignoring duplicate master at %s.\n", NET_AdrToString( &adr ) ); + goto out; } } - if( j == slot ) { - Com_Printf( "Master server at %s.\n", s ); - master_adr[slot++] = adr; - } + Com_Printf( "Master server at %s.\n", NET_AdrToString( &adr ) ); + len = strlen( s ); + m = Z_Malloc( sizeof( *m ) + len ); + memcpy( m->name, s, len + 1 ); + m->adr = adr; + m->last_ack = 0; + m->last_resolved = time( NULL ); + List_Append( &sv_masterlist, &m->entry ); + total++; +out:; } - if( slot ) { + if( total ) { // make sure the server is listed public Cvar_Set( "public", "1" ); @@ -86,6 +98,32 @@ static void SV_SetMaster_f( void ) { } } +static void SV_ListMasters_f( void ) { + master_t *m; + char buf[16], *adr; + unsigned acked; + + if( LIST_EMPTY( &sv_masterlist ) ) { + Com_Printf( "There are no masters.\n" ); + return; + } + + Com_Printf( "hostname last ack address\n" + "--------------------- -------- ---------------------\n" ); + FOR_EACH_MASTER( m ) { + if( !svs.initialized ) { + strcpy( buf, "down" ); + } else if( !m->last_ack ) { + strcpy( buf, "never" ); + } else { + acked = ( svs.realtime - m->last_ack ) / 1000; + Com_FormatTime( buf, sizeof( buf ), acked ); + } + adr = m->adr.port ? NET_AdrToString( &m->adr ) : "<unknown>"; + Com_Printf( "%-21.21s %-8s %-21s\n", m->name, buf, adr ); + } +} + client_t *SV_GetPlayer( const char *s, qboolean partial ) { client_t *other, *match; int i, count; @@ -1257,6 +1295,7 @@ static const cmdreg_t c_server[] = { { "gamemap", SV_GameMap_f, SV_Map_c }, { "dumpents", SV_DumpEnts_f }, { "setmaster", SV_SetMaster_f }, + { "listmasters", SV_ListMasters_f }, { "killserver", SV_KillServer_f }, { "sv", SV_ServerCommand_f }, { "pickclient", SV_PickClient_f }, |