Index: src/game/g_admin.c =================================================================== RCS file: /devel/cvs/tremulous/src/game/g_admin.c,v retrieving revision 1.4 retrieving revision 1.7 diff -u -r1.4 -r1.7 --- src/game/g_admin.c 30 Nov 2007 16:54:00 -0000 1.4 +++ src/game/g_admin.c 2 Dec 2007 02:29:52 -0000 1.7 @@ -133,6 +133,11 @@ "" }, + {"listmaps", G_admin_listmaps, "j", + "display a list of available maps on the server", + "" + }, + {"lock", G_admin_lock, "K", "lock a team to prevent anyone from joining it", "[^3a|h^7]" @@ -143,6 +148,11 @@ "[^3mapname^7] (^5layout^7)" }, + {"maplog", G_admin_maplog, "U", + "show recently played maps", + "" + }, + {"mute", G_admin_mute, "m", "mute a player", "[^3name|slot#^7]" @@ -667,23 +677,23 @@ } Q_strncpyz( g_admin_levels[ 0 ]->name, "^4Unknown Player", sizeof( l->name ) ); - Q_strncpyz( g_admin_levels[ 0 ]->flags, "iahC", sizeof( l->flags ) ); + Q_strncpyz( g_admin_levels[ 0 ]->flags, "iahCj", sizeof( l->flags ) ); Q_strncpyz( g_admin_levels[ 1 ]->name, "^5Server Regular", sizeof( l->name ) ); - Q_strncpyz( g_admin_levels[ 1 ]->flags, "iahC", sizeof( l->flags ) ); + Q_strncpyz( g_admin_levels[ 1 ]->flags, "iahCj", sizeof( l->flags ) ); Q_strncpyz( g_admin_levels[ 2 ]->name, "^6Team Manager", sizeof( l->name ) ); - Q_strncpyz( g_admin_levels[ 2 ]->flags, "iahCpPwd", sizeof( l->flags ) ); + Q_strncpyz( g_admin_levels[ 2 ]->flags, "iahCjpPwd", sizeof( l->flags ) ); Q_strncpyz( g_admin_levels[ 3 ]->name, "^2Junior Admin", sizeof( l->name ) ); - Q_strncpyz( g_admin_levels[ 3 ]->flags, "iahCpPkmwd?$", sizeof( l->flags ) ); + Q_strncpyz( g_admin_levels[ 3 ]->flags, "iahCjpPkmwd?$uU", sizeof( l->flags ) ); Q_strncpyz( g_admin_levels[ 4 ]->name, "^3Senior Admin", sizeof( l->name ) ); - Q_strncpyz( g_admin_levels[ 4 ]->flags, "iahCpPkmBbewd?$", sizeof( l->flags ) ); + Q_strncpyz( g_admin_levels[ 4 ]->flags, "iahCjpPkmBbewd?$uU", sizeof( l->flags ) ); Q_strncpyz( g_admin_levels[ 5 ]->name, "^1Server Operator", sizeof( l->name ) ); @@ -2258,6 +2268,71 @@ return qtrue; } +void G_admin_maplog_update( void ) +{ + char map[ 64 ]; + char maplog[ MAX_CVAR_VALUE_STRING ]; + char *ptr; + int count = 0; + + trap_Cvar_VariableStringBuffer( "mapname", map, sizeof( map ) ); + + Q_strncpyz( maplog, g_adminMapLog.string, sizeof( maplog ) ); + ptr = maplog; + while( *ptr && count < MAX_ADMIN_MAPLOG_LENGTH ) + { + while( *ptr != ' ' && *ptr != '\0' ) ptr++; + + count++; + if( count >= MAX_ADMIN_MAPLOG_LENGTH ) + { + *ptr = '\0'; + } + + if( *ptr == ' ' ) ptr++; + } + + trap_Cvar_Set( "g_adminMapLog", va( "%s%s%s", + map, + ( maplog[0] != '\0' ) ? " " : "", + maplog ) ); +} + +qboolean G_admin_maplog( gentity_t *ent, int skiparg ) +{ + char maplog[ MAX_CVAR_VALUE_STRING ]; + char *ptr; + int count = 0; + + Q_strncpyz( maplog, g_adminMapLog.string, sizeof( maplog ) ); + + ADMBP_begin( ); + ptr = maplog; + while( *ptr != '\0' && count < MAX_ADMIN_MAPLOG_LENGTH + 1 ) + { + char *end; + + end = ptr; + while( *end != ' ' && *end != '\0' ) end++; + if( *end == ' ' ) + { + *end = '\0'; + end++; + } + + ADMBP( va( "%s%s%s\n", + ( count == 0 ) ? "^3" : "^7", + ptr, + ( count == 0 ) ? " (current map)" : "" ) ); + + ptr = end; + count++; + } + ADMBP_end( ); + + return qtrue; +} + qboolean G_admin_mute( gentity_t *ent, int skiparg ) { int pids[ MAX_CLIENTS ]; @@ -2686,6 +2761,57 @@ return qtrue; } +#define MAX_LISTMAPS_MAPS 128 + +static int SortMaps(const void *a, const void *b) +{ + return strcmp(*(char **)a, *(char **)b); +} + +qboolean G_admin_listmaps( gentity_t *ent, int skiparg ) +{ + char fileList[ 4096 ] = {""}; + char *fileSort[ MAX_LISTMAPS_MAPS ]; + int numFiles; + int i; + int fileLen = 0; + int count = 0; + char *filePtr; + int rows; + + numFiles = trap_FS_GetFileList( "maps/", ".bsp", + fileList, sizeof( fileList ) ); + filePtr = fileList; + for( i = 0; i < numFiles && count < MAX_LISTMAPS_MAPS; i++, filePtr += fileLen + 1 ) + { + fileLen = strlen( filePtr ); + if (fileLen < 5) + continue; + + filePtr[ fileLen - 4 ] = '\0'; + fileSort[ count ] = filePtr; + count++; + } + + qsort(fileSort, count, sizeof(fileSort[ 0 ]), SortMaps); + + rows = count / 3; + if ( rows * 3 < count ) rows++; + + ADMBP_begin(); + for( i = 0; i < rows; i++ ) + { + ADMBP( va( "^7%20s %20s %20s\n", + fileSort[ i ], + ( rows + i < count ) ? fileSort[ rows + i ] : "", + ( rows * 2 + i < count ) ? fileSort[ rows * 2 + i ] : "" ) ); + } + ADMBP( va( "^3!listmaps: ^7listing %d maps.\n", count ) ); + ADMBP_end(); + + return qtrue; +} + qboolean G_admin_showbans( gentity_t *ent, int skiparg ) { int i, found = 0; Index: src/game/g_admin.h =================================================================== RCS file: /devel/cvs/tremulous/src/game/g_admin.h,v retrieving revision 1.3 retrieving revision 1.5 diff -u -r1.3 -r1.5 --- src/game/g_admin.h 30 Nov 2007 16:54:00 -0000 1.3 +++ src/game/g_admin.h 30 Nov 2007 23:54:41 -0000 1.5 @@ -79,6 +79,8 @@ #define MAX_ADMIN_LISTITEMS 20 #define MAX_ADMIN_SHOWBANS 10 +#define MAX_ADMIN_MAPLOG_LENGTH 5 + // important note: QVM does not seem to allow a single char to be a // member of a struct at init time. flag has been converted to char* typedef struct @@ -159,9 +161,12 @@ qboolean G_admin_listadmins( gentity_t *ent, int skiparg ); qboolean G_admin_listlayouts( gentity_t *ent, int skiparg ); qboolean G_admin_listplayers( gentity_t *ent, int skiparg ); +qboolean G_admin_listmaps( gentity_t *ent, int skiparg ); qboolean G_admin_map( gentity_t *ent, int skiparg ); qboolean G_admin_devmap( gentity_t *ent, int skiparg ); qboolean G_admin_layoutsave( gentity_t *ent, int skiparg ); +void G_admin_maplog_update( void ); +qboolean G_admin_maplog( gentity_t *ent, int skiparg ); qboolean G_admin_mute( gentity_t *ent, int skiparg ); qboolean G_admin_denybuild( gentity_t *ent, int skiparg ); qboolean G_admin_showbans( gentity_t *ent, int skiparg ); Index: src/game/g_local.h =================================================================== RCS file: /devel/cvs/tremulous/src/game/g_local.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/game/g_local.h 28 Nov 2007 20:47:21 -0000 1.1.1.1 +++ src/game/g_local.h 30 Nov 2007 23:54:41 -0000 1.2 @@ -1245,6 +1245,7 @@ extern vmCvar_t g_adminSayFilter; extern vmCvar_t g_adminNameProtect; extern vmCvar_t g_adminTempBan; +extern vmCvar_t g_adminMapLog; extern vmCvar_t g_minLevelToJoinTeam; extern vmCvar_t g_minLevelToSpecMM1; Index: src/game/g_main.c =================================================================== RCS file: /devel/cvs/tremulous/src/game/g_main.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- src/game/g_main.c 28 Nov 2007 20:47:21 -0000 1.1.1.1 +++ src/game/g_main.c 30 Nov 2007 23:54:41 -0000 1.2 @@ -144,6 +144,7 @@ vmCvar_t g_adminSayFilter; vmCvar_t g_adminNameProtect; vmCvar_t g_adminTempBan; +vmCvar_t g_adminMapLog; vmCvar_t g_minLevelToJoinTeam; vmCvar_t g_privateMessages; @@ -299,6 +300,7 @@ { &g_adminSayFilter, "g_adminSayFilter", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_adminNameProtect, "g_adminNameProtect", "1", CVAR_ARCHIVE, 0, qfalse }, { &g_adminTempBan, "g_adminTempBan", "120", CVAR_ARCHIVE, 0, qfalse }, + { &g_adminMapLog, "g_adminMapLog", "", CVAR_ROM, 0, qfalse }, { &g_minLevelToJoinTeam, "g_minLevelToJoinTeam", "0", CVAR_ARCHIVE, 0, qfalse }, { &g_privateMessages, "g_privateMessages", "1", CVAR_ARCHIVE, 0, qfalse }, @@ -672,6 +674,9 @@ trap_SetConfigstring( CS_INTERMISSION, "0" ); + // update maplog + G_admin_maplog_update( ); + // test to see if a custom buildable layout will be loaded G_LayoutSelect( );