diff options
author | M. Kristall <mkpdev@gmail.com> | 2009-10-03 12:41:40 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:16:09 +0000 |
commit | 19433e1c2790ebab99bdff1f18f16e8ab86d249f (patch) | |
tree | 804fbd10d47ce2622119ed5089463a4ca0b01a52 /src | |
parent | 47fd44d7bb4acd32854e4f6fdbdef04692ff728f (diff) |
* (bug 4037) cgame forgets to close buildstat.cfg
* Admin searches now list all matches
* !listadmins now properly handles negative numbers
* "!ban: too many bans" errors were sometimes wrong
* A bit of refactoring
* Add %s support to sscanf
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_buildable.c | 2 | ||||
-rw-r--r-- | src/game/bg_lib.c | 39 | ||||
-rw-r--r-- | src/game/g_admin.c | 571 | ||||
-rw-r--r-- | src/game/g_cmds.c | 19 |
4 files changed, 232 insertions, 399 deletions
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c index 03e43e17..1f882a3a 100644 --- a/src/cgame/cg_buildable.c +++ b/src/cgame/cg_buildable.c @@ -806,10 +806,12 @@ void CG_BuildableStatusParse( const char *filename, buildStat_t *bs ) Com_Printf("CG_BuildableStatusParse: unknown token %s in %s\n", token.string, filename ); bs->loaded = qfalse; + trap_Parse_FreeSource( handle ); return; } } bs->loaded = qtrue; + trap_Parse_FreeSource( handle ); } #define STATUS_FADE_TIME 200 diff --git a/src/game/bg_lib.c b/src/game/bg_lib.c index fa184228..1ed9c6b3 100644 --- a/src/game/bg_lib.c +++ b/src/game/bg_lib.c @@ -2391,10 +2391,11 @@ int Q_snprintf(char *str, size_t length, const char *fmt, ...) int sscanf( const char *buffer, const char *fmt, ... ) { int cmd; - int **arg; + va_list ap; int count; + size_t len; - arg = (int **)&fmt + 1; + va_start( ap, fmt ); count = 0; while( *fmt ) @@ -2405,27 +2406,47 @@ int sscanf( const char *buffer, const char *fmt, ... ) continue; } - cmd = fmt[ 1 ]; - fmt += 2; + fmt++; + cmd = *fmt; + + if( isdigit( cmd ) ) + { + len = (size_t)_atoi( &fmt ); + cmd = *( fmt - 1 ); + } + else + { + len = MAX_STRING_CHARS - 1; + fmt++; + } switch( cmd ) { case 'i': case 'd': case 'u': - **arg = _atoi( &buffer ); + *( va_arg( ap, int * ) ) = _atoi( &buffer ); break; case 'f': - *(float *)*arg = _atof( &buffer ); + *( va_arg( ap, float * ) ) = _atof( &buffer ); break; case 'x': - **arg = _hextoi( &buffer ); + *( va_arg( ap, unsigned int * ) ) = _hextoi( &buffer ); + break; + case 's': + { + char *s = va_arg( ap, char * ); + while( isspace( *buffer ) ) + buffer++; + while( *buffer && !isspace( *buffer) && len-- > 0 ) + *s++ = *buffer++; + *s++ = '\0'; break; + } } - - arg++; } + va_end( ap ); return count; } diff --git a/src/game/g_admin.c b/src/game/g_admin.c index 7ad67357..8c1749f4 100644 --- a/src/game/g_admin.c +++ b/src/game/g_admin.c @@ -281,7 +281,7 @@ qboolean G_admin_name_check( gentity_t *ent, char *name, char *err, int len ) G_SanitiseString( name, name2, sizeof( name2 ) ); - if( !Q_stricmp( name2, "UnnamedPlayer" ) ) + if( !strcmp( name2, "unnamedplayer" ) ) return qtrue; for( i = 0; i < level.maxclients; i++ ) @@ -295,7 +295,7 @@ qboolean G_admin_name_check( gentity_t *ent, char *name, char *err, int len ) continue; G_SanitiseString( client->pers.netname, testName, sizeof( testName ) ); - if( !Q_stricmp( name2, testName ) ) + if( !strcmp( name2, testName ) ) { Com_sprintf( err, len, "The name '%s^7' is already in use", name ); return qfalse; @@ -310,7 +310,7 @@ qboolean G_admin_name_check( gentity_t *ent, char *name, char *err, int len ) if( g_admin_admins[ i ]->level < 1 ) continue; G_SanitiseString( g_admin_admins[ i ]->name, testName, sizeof( testName ) ); - if( !Q_stricmp( name2, testName ) && + if( !strcmp( name2, testName ) && Q_stricmp( ent->client->pers.guid, g_admin_admins[ i ]->guid ) ) { Com_sprintf( err, len, "The name '%s^7' belongs to an admin, " @@ -362,15 +362,8 @@ static qboolean admin_higher( gentity_t *admin, gentity_t *victim ) static void admin_writeconfig_string( char *s, fileHandle_t f ) { - char buf[ MAX_STRING_CHARS ]; - - buf[ 0 ] = '\0'; if( s[ 0 ] ) - { - //Q_strcat(buf, sizeof(buf), s); - Q_strncpyz( buf, s, sizeof( buf ) ); - trap_FS_Write( buf, strlen( buf ), f ); - } + trap_FS_Write( s, strlen( s ), f ); trap_FS_Write( "\n", 1, f ); } @@ -378,15 +371,14 @@ static void admin_writeconfig_int( int v, fileHandle_t f ) { char buf[ 32 ]; - Com_sprintf( buf, sizeof(buf), "%d", v ); + Com_sprintf( buf, sizeof( buf ), "%d\n", v ); trap_FS_Write( buf, strlen( buf ), f ); - trap_FS_Write( "\n", 1, f ); } static void admin_writeconfig( void ) { fileHandle_t f; - int len, i, j; + int i, j; int t; char levels[ MAX_STRING_CHARS ] = {""}; @@ -397,8 +389,7 @@ static void admin_writeconfig( void ) return; } t = trap_RealTime( NULL ); - len = trap_FS_FOpenFile( g_admin.string, &f, FS_WRITE ); - if( len < 0 ) + if( trap_FS_FOpenFile( g_admin.string, &f, FS_WRITE ) < 0 ) { G_Printf( "admin_writeconfig: could not open g_admin file \"%s\"\n", g_admin.string ); @@ -436,8 +427,7 @@ static void admin_writeconfig( void ) { // don't write expired bans // if expires is 0, then it's a perm ban - if( g_admin_bans[ i ]->expires != 0 && - ( g_admin_bans[ i ]->expires - t ) < 1 ) + if( g_admin_bans[ i ]->expires != 0 && g_admin_bans[ i ]->expires <= t ) continue; trap_FS_Write( "[ban]\n", 6, f ); @@ -537,8 +527,6 @@ static void admin_default_levels( void ) { l = BG_Alloc( sizeof( g_admin_level_t ) ); l->level = i; - *l->name = '\0'; - *l->flags = '\0'; g_admin_levels[ i ] = l; } Q_strncpyz( g_admin_levels[ 0 ]->name, "^4Unknown Player", @@ -712,14 +700,15 @@ static void admin_log( gentity_t *admin, char *cmd, int skiparg ) static int admin_listadmins( gentity_t *ent, int start, char *search ) { int drawn = 0; - char guid_stub[9]; char name[ MAX_NAME_LENGTH ] = {""}; char name2[ MAX_NAME_LENGTH ] = {""}; char lname[ MAX_NAME_LENGTH ] = {""}; int i, j; gentity_t *vic; - int l = 0; - qboolean dup = qfalse; + int colorlen; + + if( search[ 0 ] ) + start = 0; ADMBP_begin(); @@ -728,49 +717,41 @@ static int admin_listadmins( gentity_t *ent, int start, char *search ) { vic = &g_entities[ i ]; - if( vic->client && vic->client->pers.connected != CON_CONNECTED ) + if( vic->client->pers.connected == CON_DISCONNECTED ) continue; - l = vic->client->pers.adminLevel; - G_SanitiseString( vic->client->pers.netname, name, sizeof( name ) ); if( !strstr( name, search ) ) continue; - for( j = 0; j < 8; j++ ) - guid_stub[ j ] = vic->client->pers.guid[ j + 24 ]; - guid_stub[ j ] = '\0'; - lname[ 0 ] = '\0'; for( j = 0; j < MAX_ADMIN_LEVELS && g_admin_levels[ j ]; j++ ) { - if( g_admin_levels[ j ]->level == l ) + if( g_admin_levels[ j ]->level == vic->client->pers.adminLevel ) { - int k, colorlen; - - for( colorlen = k = 0; g_admin_levels[ j ]->name[ k ]; k++ ) - { - if( Q_IsColorString( &g_admin_levels[ j ]->name[ k ] ) ) - colorlen += 2; - } - - Com_sprintf( lname, sizeof( lname ), "%*s", - admin_level_maxname + colorlen, - g_admin_levels[ j ]->name ); + Q_strncpyz( lname, g_admin_levels[ j ]->name, sizeof( lname ) ); break; } } - ADMBP( va( "%4i %4i %s^7 (*%s) %s^7\n", + + for( colorlen = j = 0; lname[ j ]; j++ ) + { + if( Q_IsColorString( &lname[ j ] ) ) + colorlen += 2; + } + + ADMBP( va( "%4i %4i %*s^7 (*%s) %s\n", i, - l, + vic->client->pers.adminLevel, + admin_level_maxname + colorlen, lname, - guid_stub, + vic->client->pers.guid + 24, vic->client->pers.netname ) ); drawn++; } for( i = start; i < MAX_ADMIN_ADMINS && g_admin_admins[ i ] && - drawn < MAX_ADMIN_LISTITEMS; i++ ) + ( search[ 0 ] || i - start < MAX_ADMIN_LISTITEMS ); i++ ) { if( search[ 0 ] ) { @@ -780,51 +761,44 @@ static int admin_listadmins( gentity_t *ent, int start, char *search ) // verify we don't have the same guid/name pair in connected players // since we don't want to draw the same player twice - dup = qfalse; for( j = 0; j < level.maxclients; j++ ) { vic = &g_entities[ j ]; - if( !vic->client || vic->client->pers.connected != CON_CONNECTED ) + if( vic->client->pers.connected == CON_DISCONNECTED ) continue; G_SanitiseString( vic->client->pers.netname, name2, sizeof( name2 ) ); if( !Q_stricmp( vic->client->pers.guid, g_admin_admins[ i ]->guid ) && strstr( name2, search ) ) { - dup = qtrue; break; } } - if( dup ) + if( j < level.maxclients ) continue; } - for( j = 0; j < 8; j++ ) - guid_stub[ j ] = g_admin_admins[ i ]->guid[ j + 24 ]; - guid_stub[ j ] = '\0'; lname[ 0 ] = '\0'; for( j = 0; j < MAX_ADMIN_LEVELS && g_admin_levels[ j ]; j++ ) { if( g_admin_levels[ j ]->level == g_admin_admins[ i ]->level ) { - int k, colorlen; - - for( colorlen = k = 0; g_admin_levels[ j ]->name[ k ]; k++ ) - { - if( Q_IsColorString( &g_admin_levels[ j ]->name[ k ] ) ) - colorlen += 2; - } - - Com_sprintf( lname, sizeof( lname ), "%*s", - admin_level_maxname + colorlen, - g_admin_levels[ j ]->name ); + Q_strncpyz( lname, g_admin_levels[ j ]->name, sizeof( lname ) ); break; } } - ADMBP( va( "%4i %4i %s^7 (*%s) %s^7\n", + + for( colorlen = j = 0; lname[ j ]; j++ ) + { + if( Q_IsColorString( &lname[ j ] ) ) + colorlen += 2; + } + + ADMBP( va( "%4i %4i %*s^7 (*%s) %s\n", ( i + MAX_CLIENTS ), g_admin_admins[ i ]->level, + admin_level_maxname + colorlen, lname, - guid_stub, + g_admin_admins[ i ]->guid + 24, g_admin_admins[ i ]->name ) ); drawn++; } @@ -834,7 +808,7 @@ static int admin_listadmins( gentity_t *ent, int start, char *search ) void G_admin_duration( int secs, char *duration, int dursize ) { - + // sizeof("12.5 minutes") == 13 if( secs > ( 60 * 60 * 24 * 365 * 50 ) || secs < 0 ) Q_strncpyz( duration, "PERMANENT", dursize ); else if( secs >= ( 60 * 60 * 24 * 365 ) ) @@ -873,13 +847,13 @@ qboolean G_admin_ban_check( char *userinfo, char *reason, int rlen ) for( i = 0; i < MAX_ADMIN_BANS && g_admin_bans[ i ]; i++ ) { // 0 is for perm ban - if( g_admin_bans[ i ]->expires != 0 && - ( g_admin_bans[ i ]->expires - t ) < 1 ) + if( g_admin_bans[ i ]->expires != 0 && g_admin_bans[ i ]->expires <= t ) continue; - if( strstr( ip, g_admin_bans[ i ]->ip ) ) + if( strstr( ip, g_admin_bans[ i ]->ip ) || + ( *guid && !Q_stricmp( g_admin_bans[ i ]->guid, guid ) ) ) { - char duration[ 32 ]; - G_admin_duration( ( g_admin_bans[ i ]->expires - t ), + char duration[ 13 ]; + G_admin_duration( g_admin_bans[ i ]->expires - t, duration, sizeof( duration ) ); Com_sprintf( reason, @@ -889,23 +863,7 @@ qboolean G_admin_ban_check( char *userinfo, char *reason, int rlen ) g_admin_bans[ i ]->reason, duration ); - G_Printf( "Banned player tried to connect from IP %s\n", ip ); - return qtrue; - } - if( *guid && !Q_stricmp( g_admin_bans[ i ]->guid, guid ) ) - { - char duration[ 32 ]; - G_admin_duration( ( g_admin_bans[ i ]->expires - t ), - duration, sizeof( duration ) ); - Com_sprintf( - reason, - rlen, - "You have been banned by %s^7 reason: %s^7 expires: %s", - g_admin_bans[ i ]->banner, - g_admin_bans[ i ]->reason, - duration - ); - G_Printf( "Banned player tried to connect with GUID %s\n", guid ); + G_Printf( "Banned player (#%d) tried to connect from %s\n", i + 1, ip ); return qtrue; } } @@ -931,14 +889,11 @@ qboolean G_admin_cmd_check( gentity_t *ent, qboolean say ) G_SayArgv( 1, command, sizeof( command ) ); } - if( command[ 0 ] == '!' ) - { - cmd = &command[ 1 ]; - } + cmd = command; + if( *cmd == '!' ) + cmd++; else - { return qfalse; - } for( i = 0; i < MAX_ADMIN_COMMANDS && g_admin_commands[ i ]; i++ ) { @@ -1009,8 +964,8 @@ void G_admin_namelog_update( gclient_t *client, qboolean disconnect ) if( disconnect && g_admin_namelog[ i ]->slot != clientNum ) continue; - if( !disconnect && !( g_admin_namelog[ i ]->slot == clientNum || - g_admin_namelog[ i ]->slot == -1 ) ) + if( !disconnect && g_admin_namelog[ i ]->slot != clientNum && + g_admin_namelog[ i ]->slot != -1 ) { continue; } @@ -1022,11 +977,11 @@ void G_admin_namelog_update( gclient_t *client, qboolean disconnect ) g_admin_namelog[ i ]->name[ j ][ 0 ]; j++ ) { G_SanitiseString( g_admin_namelog[ i ]->name[ j ], n2, sizeof( n2 ) ); - if( !Q_stricmp( n1, n2 ) ) + if( !strcmp( n1, n2 ) ) break; } if( j == MAX_ADMIN_NAMELOG_NAMES ) - j = MAX_ADMIN_NAMELOG_NAMES - 1; + j = client->pers.nameChanges % MAX_ADMIN_NAMELOG_NAMES; Q_strncpyz( g_admin_namelog[ i ]->name[ j ], client->pers.netname, sizeof( g_admin_namelog[ i ]->name[ j ] ) ); g_admin_namelog[ i ]->slot = ( disconnect ) ? -1 : clientNum; @@ -1038,7 +993,7 @@ void G_admin_namelog_update( gclient_t *client, qboolean disconnect ) return; } } - if( i >= MAX_ADMIN_NAMELOGS ) + if( i == MAX_ADMIN_NAMELOGS ) { G_Printf( "G_admin_namelog_update: warning, g_admin_namelogs overflow\n" ); return; @@ -1149,6 +1104,10 @@ qboolean G_admin_readconfig( gentity_t *ent, int skiparg ) else if( !Q_stricmp( t, "name" ) ) { admin_readconfig_string( &cnf, l->name, sizeof( l->name ) ); + // max printable name length for formatting + len = Q_PrintStrlen( l->name ); + if( len > admin_level_maxname ) + admin_level_maxname = len; } else if( !Q_stricmp( t, "flags" ) ) { @@ -1265,17 +1224,6 @@ qboolean G_admin_readconfig( gentity_t *ent, int skiparg ) lc, ac, bc, cc ) ); if( lc == 0 ) admin_default_levels(); - else - { - // max printable name length for formatting - for( i = 0; i < MAX_ADMIN_LEVELS && g_admin_levels[ i ]; i++ ) - { - len = Q_PrintStrlen( g_admin_levels[ i ]->name ); - if( len > admin_level_maxname ) - admin_level_maxname = len; - } - } - // reset adminLevel for( i = 0; i < level.maxclients; i++ ) { @@ -1299,7 +1247,7 @@ qboolean G_admin_time( gentity_t *ent, int skiparg ) qboolean G_admin_setlevel( gentity_t *ent, int skiparg ) { char name[ MAX_NAME_LENGTH ] = {""}; - char lstr[ 11 ]; // 10 is max strlen() for 32-bit int + char lstr[ 12 ]; // 11 is max strlen() for 32-bit (signed) int char adminname[ MAX_NAME_LENGTH ] = {""}; char testname[ MAX_NAME_LENGTH ] = {""}; char guid[ 33 ]; @@ -1312,7 +1260,6 @@ qboolean G_admin_setlevel( gentity_t *ent, int skiparg ) int matches = 0; int id = -1; - if( G_SayArgc() < 3 + skiparg ) { ADMP( "^3!setlevel: ^7usage: !setlevel [name|slot#] [level]\n" ); @@ -1486,10 +1433,26 @@ static qboolean admin_create_ban( gentity_t *ent, int i; t = trap_RealTime( &qt ); - b = BG_Alloc( sizeof( g_admin_ban_t ) ); + + for( i = 0; i < MAX_ADMIN_BANS && g_admin_bans[ i ]; i++ ) + { + if( g_admin_bans[ i ]->expires != 0 && g_admin_bans[ i ]->expires <= t ) + { + b = g_admin_bans[ i ]; + break; + } + } if( !b ) - return qfalse; + { + if( i == MAX_ADMIN_BANS || g_admin_bans[ i ] ) + { + ADMP( "^3!ban: ^7too many bans\n" ); + return qfalse; + } + b = BG_Alloc( sizeof( g_admin_ban_t ) ); + g_admin_bans[ i ] = b; + } Q_strncpyz( b->name, netname, sizeof( b->name ) ); Q_strncpyz( b->guid, guid, sizeof( b->guid ) ); @@ -1512,15 +1475,6 @@ static qboolean admin_create_ban( gentity_t *ent, Q_strncpyz( b->reason, "banned by admin", sizeof( b->reason ) ); else Q_strncpyz( b->reason, reason, sizeof( b->reason ) ); - for( i = 0; i < MAX_ADMIN_BANS && g_admin_bans[ i ]; i++ ) - ; - if( i == MAX_ADMIN_BANS ) - { - ADMP( "^3!ban: ^7too many bans\n" ); - BG_Free( b ); - return qfalse; - } - g_admin_bans[ i ] = b; return qtrue; } @@ -1593,10 +1547,9 @@ qboolean G_admin_kick( gentity_t *ent, int skiparg ) vic->client->pers.netname, vic->client->pers.guid, vic->client->pers.ip, - G_admin_parse_time( va( "1s%s", g_adminTempBan.string ) ), + MAX( 1, G_admin_parse_time( g_adminTempBan.string ) ), ( *reason ) ? reason : "kicked by admin" ); - if( g_admin.string[ 0 ] ) - admin_writeconfig(); + admin_writeconfig(); trap_SendServerCommand( pids[ 0 ], va( "disconnect \"You have been kicked.\n%s^7\nreason:\n%s\"", @@ -1616,31 +1569,14 @@ qboolean G_admin_ban( gentity_t *ent, int skiparg ) char search[ MAX_NAME_LENGTH ]; char secs[ MAX_TOKEN_CHARS ]; char *reason; - int minargc; - char duration[ 32 ]; + char duration[ 13 ]; int logmatch = -1, logmatches = 0; int i, j; qboolean exactmatch = qfalse; char n2[ MAX_NAME_LENGTH ]; char s2[ MAX_NAME_LENGTH ]; - char guid_stub[ 9 ]; - if( G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && - G_admin_permission( ent, ADMF_UNACCOUNTABLE ) ) - { - minargc = 2 + skiparg; - } - else if( G_admin_permission( ent, ADMF_CAN_PERM_BAN ) || - G_admin_permission( ent, ADMF_UNACCOUNTABLE ) || - g_adminMaxBan.integer ) - { - minargc = 3 + skiparg; - } - else - { - minargc = 4 + skiparg; - } - if( G_SayArgc() < minargc ) + if( G_SayArgc() < 2 + skiparg ) { ADMP( "^3!ban: ^7usage: !ban [name|slot|ip] [duration] [reason]\n" ); return qfalse; @@ -1652,52 +1588,38 @@ qboolean G_admin_ban( gentity_t *ent, int skiparg ) seconds = G_admin_parse_time( secs ); if( seconds <= 0 ) { - if( g_adminMaxBan.integer && !G_admin_permission( ent, ADMF_CAN_PERM_BAN) ) - { - ADMP( va( "^3!ban: ^7using your admin level's maximum ban length of %s\n", - g_adminMaxBan.string ) ); - seconds = G_admin_parse_time( g_adminMaxBan.string ); - } - else if( G_admin_permission( ent, ADMF_CAN_PERM_BAN ) ) - { - seconds = 0; - } - else - { - ADMP( "^3!ban: ^7you may not issue permanent bans\n" ); - return qfalse; - } + seconds = 0; reason = G_SayConcatArgs( 2 + skiparg ); } else { - if( g_adminMaxBan.integer && - !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && - seconds > G_admin_parse_time( g_adminMaxBan.string ) ) + reason = G_SayConcatArgs( 3 + skiparg ); + } + if( !*reason && !G_admin_permission( ent, ADMF_UNACCOUNTABLE ) ) + { + ADMP( "^3!ban: ^7you must specify a reason\n" ); + return qfalse; + } + if( !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) ) + { + int maximum = MAX( 1, G_admin_parse_time( g_adminMaxBan.string ) ); + if( seconds == 0 || seconds > maximum ) { - ADMP( va( "^3!ban: ^7ban length limited to %s for your admin level\n", - g_adminMaxBan.string ) ); - seconds = G_admin_parse_time( g_adminMaxBan.string ); + ADMP( "^3!ban: ^7you may not issue permanent bans\n" ); + seconds = maximum; } - reason = G_SayConcatArgs( 3 + skiparg ); } - for( i = 0; i < MAX_ADMIN_NAMELOGS && g_admin_namelog[ i ]; i++ ) + // ban by clientnum + for( i = 0; search[ i ] && isdigit( search[ i ] ); i++ ); + if( !search[ i ] ) { - // skip players in the namelog who have already been banned - if( g_admin_namelog[ i ]->banned ) - continue; - - // skip disconnected players when banning on slot number - if( g_admin_namelog[ i ]->slot == -1 ) - continue; - - if( !Q_stricmp( va( "%d", g_admin_namelog[ i ]->slot ), search ) ) + i = atoi( search ); + if( level.clients[ i ].pers.connected != CON_DISCONNECTED ) { logmatches = 1; - logmatch = i; exactmatch = qtrue; - break; + for( logmatch = 0; g_admin_namelog[ i ]->slot != i; logmatch++ ); } } @@ -1740,9 +1662,6 @@ qboolean G_admin_ban( gentity_t *ent, int skiparg ) ADMBP( "^3!ban: ^7multiple recent clients match name, use IP or slot#:\n" ); for( i = 0; i < MAX_ADMIN_NAMELOGS && g_admin_namelog[ i ]; i++ ) { - for( j = 0; j < 8; j++ ) - guid_stub[ j ] = g_admin_namelog[ i ]->guid[ j + 24 ]; - guid_stub[ j ] = '\0'; for( j = 0; j < MAX_ADMIN_NAMELOG_NAMES && g_admin_namelog[ i ]->name[ j ][ 0 ]; j++ ) { @@ -1754,7 +1673,7 @@ qboolean G_admin_ban( gentity_t *ent, int skiparg ) ADMBP( va( "%-2s (*%s) %15s ^7'%s^7'\n", ( g_admin_namelog[ i ]->slot > -1 ) ? va( "%d", g_admin_namelog[ i ]->slot ) : "-", - guid_stub, + g_admin_namelog[ i ]->guid + 24, g_admin_namelog[ i ]->ip, g_admin_namelog[ i ]->name[ j ] ) ); } @@ -1839,37 +1758,30 @@ qboolean G_admin_unban( gentity_t *ent, int skiparg ) ADMP( "^3!unban: ^7invalid ban#\n" ); return qfalse; } - if( g_admin_bans[ bnum - 1 ]->expires == 0 && - !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) ) + if( !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && + ( g_admin_bans[ bnum - 1 ]->expires == 0 || + ( g_admin_bans[ bnum - 1 ]->expires - time > MAX( 1, + G_admin_parse_time( g_adminMaxBan.string ) ) ) ) ) { ADMP( "^3!unban: ^7you cannot remove permanent bans\n" ); return qfalse; } - if( g_adminMaxBan.integer && - !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && - g_admin_bans[ bnum - 1 ]->expires - time > G_admin_parse_time( g_adminMaxBan.string ) ) - { - ADMP( va( "^3!unban: ^7your admin level cannot remove bans longer than %s\n", - g_adminMaxBan.string ) ); - return qfalse; - } g_admin_bans[ bnum - 1 ]->expires = time; AP( va( "print \"^3!unban: ^7ban #%d for %s^7 has been removed by %s\n\"", bnum, g_admin_bans[ bnum - 1 ]->name, ( ent ) ? ent->client->pers.netname : "console" ) ); - if( g_admin.string[ 0 ] ) - admin_writeconfig(); + admin_writeconfig(); return qtrue; } qboolean G_admin_adjustban( gentity_t *ent, int skiparg ) { int bnum; - int length; + int length, maximum; int expires; int time = trap_RealTime( NULL ); - char duration[ 32 ] = {""}; + char duration[ 13 ] = {""}; char *reason; char bs[ 5 ]; char secs[ MAX_TOKEN_CHARS ]; @@ -1889,19 +1801,13 @@ qboolean G_admin_adjustban( gentity_t *ent, int skiparg ) return qfalse; } ban = g_admin_bans[ bnum - 1 ]; - if( ban->expires == 0 && !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) ) + maximum = MAX( 1, G_admin_parse_time( g_adminMaxBan.string ) ); + if( !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && + ( ban->expires == 0 || ban->expires - time > maximum ) ) { ADMP( "^3!adjustban: ^7you cannot modify permanent bans\n" ); return qfalse; } - if( g_adminMaxBan.integer && - !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && - ban->expires - time > G_admin_parse_time( g_adminMaxBan.string ) ) - { - ADMP( va( "^3!adjustban: ^7your admin level cannot modify bans longer than %s\n", - g_adminMaxBan.string ) ); - return qfalse; - } G_SayArgv( 2 + skiparg, secs, sizeof( secs ) ); if( secs[ 0 ] == '+' || secs[ 0 ] == '-' ) mode = secs[ 0 ]; @@ -1928,22 +1834,14 @@ qboolean G_admin_adjustban( gentity_t *ent, int skiparg ) ADMP( "^3!adjustban: ^7ban duration must be positive\n" ); return qfalse; } - if( g_adminMaxBan.integer && - !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && - expires - time > G_admin_parse_time( g_adminMaxBan.string ) ) - { - ADMP( va( "^3!adjustban: ^7ban length is limited to %s for your admin level\n", - g_adminMaxBan.string ) ); - length = G_admin_parse_time( g_adminMaxBan.string ); - expires = time + length; - } } - else if( G_admin_permission( ent, ADMF_CAN_PERM_BAN ) ) - expires = 0; else + length = expires = 0; + if( !G_admin_permission( ent, ADMF_CAN_PERM_BAN ) && + ( length == 0 || length > maximum ) ) { - ADMP( "^3!adjustban: ^7ban duration must be positive\n" ); - return qfalse; + ADMP( "^3!adjustban: ^7you may not issue permanent bans\n" ); + expires = time + maximum; } ban->expires = expires; @@ -1965,8 +1863,7 @@ qboolean G_admin_adjustban( gentity_t *ent, int skiparg ) reason ) ); if( ent ) Q_strncpyz( ban->banner, ent->client->pers.netname, sizeof( ban->banner ) ); - if( g_admin.string[ 0 ] ) - admin_writeconfig(); + admin_writeconfig(); return qtrue; } @@ -2184,7 +2081,6 @@ qboolean G_admin_listadmins( gentity_t *ent, int skiparg ) char search[ MAX_NAME_LENGTH ] = {""}; char s[ MAX_NAME_LENGTH ] = {""}; int start = 0; - qboolean numeric = qtrue; int drawn = 0; for( i = 0; i < MAX_ADMIN_ADMINS && g_admin_admins[ i ]; i++ ) @@ -2202,17 +2098,13 @@ qboolean G_admin_listadmins( gentity_t *ent, int skiparg ) if( G_SayArgc() == 2 + skiparg ) { G_SayArgv( 1 + skiparg, s, sizeof( s ) ); - for( i = 0; i < sizeof( s ) && s[ i ]; i++ ) - { - if( isdigit( s[ i ] ) ) - continue; - numeric = qfalse; - } - if( numeric ) + i = s[ 0 ] == '-' && s[ 1 ] ? 1 : 0; + for( ; s[ i ] && isdigit( s[ i ] ); i++ ); + if( !s[ i ] ) { start = atoi( s ); if( start > 0 ) - start -= 1; + start--; else if( start < 0 ) start = found + start; } @@ -2223,12 +2115,6 @@ qboolean G_admin_listadmins( gentity_t *ent, int skiparg ) if( start >= found || start < 0 ) start = 0; - if( start >= found ) - { - ADMP( va( "^3!listadmins: ^7listing %d admins\n", found ) ); - return qfalse; - } - drawn = admin_listadmins( ent, start, search ); if( search[ 0 ] ) @@ -2240,11 +2126,10 @@ qboolean G_admin_listadmins( gentity_t *ent, int skiparg ) { ADMBP_begin(); ADMBP( va( "^3!listadmins:^7 showing admin %d - %d of %d. ", - ( found ) ? ( start + 1 ) : 0, - ( ( start + MAX_ADMIN_LISTITEMS ) > found ) ? - found : ( start + MAX_ADMIN_LISTITEMS ), + found ? start + 1 : 0, + start + MAX_ADMIN_LISTITEMS > found ? found : start + MAX_ADMIN_LISTITEMS, found ) ); - if( ( start + MAX_ADMIN_LISTITEMS ) < found ) + if( start + MAX_ADMIN_LISTITEMS < found ) { ADMBP( va( "run '!listadmins %d' to see more", ( start + MAX_ADMIN_LISTITEMS + 1 ) ) ); @@ -2298,14 +2183,14 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) { int i, j; gclient_t *p; - char c[ 3 ], t[ 2 ]; // color and team letter + char c, t; // color and team letter char n[ MAX_NAME_LENGTH ] = {""}; char n2[ MAX_NAME_LENGTH ] = {""}; char n3[ MAX_NAME_LENGTH ] = {""}; char lname[ MAX_NAME_LENGTH ]; - char guid_stub[ 9 ]; - char muted[ 2 ], denied[ 2 ]; + char muted, denied; int l; + int colorlen; ADMBP_begin(); ADMBP( va( "^3!listplayers: ^7%d players connected:\n", @@ -2313,43 +2198,26 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) for( i = 0; i < level.maxclients; i++ ) { p = &level.clients[ i ]; - Q_strncpyz( t, "S", sizeof( t ) ); - Q_strncpyz( c, S_COLOR_YELLOW, sizeof( c ) ); - if( p->pers.teamSelection == TEAM_HUMANS ) - { - Q_strncpyz( t, "H", sizeof( t ) ); - Q_strncpyz( c, S_COLOR_BLUE, sizeof( c ) ); - } - else if( p->pers.teamSelection == TEAM_ALIENS ) - { - Q_strncpyz( t, "A", sizeof( t ) ); - Q_strncpyz( c, S_COLOR_RED, sizeof( c ) ); - } - + if( p->pers.connected == CON_DISCONNECTED ) + continue; if( p->pers.connected == CON_CONNECTING ) { - Q_strncpyz( t, "C", sizeof( t ) ); - Q_strncpyz( c, S_COLOR_CYAN, sizeof( c ) ); + t = 'C'; + c = COLOR_CYAN; } - else if( p->pers.connected != CON_CONNECTED ) + else { - continue; + t = toupper( *( BG_TeamName( p->pers.teamSelection ) ) ); + if( p->pers.teamSelection == TEAM_HUMANS ) + c = COLOR_BLUE; + else if( p->pers.teamSelection == TEAM_ALIENS ) + c = COLOR_RED; + else + c = COLOR_YELLOW; } - for( j = 0; j < 8; j++ ) - guid_stub[ j ] = p->pers.guid[ j + 24 ]; - guid_stub[ j ] = '\0'; - - muted[ 0 ] = '\0'; - if( p->pers.muted ) - { - Q_strncpyz( muted, "M", sizeof( muted ) ); - } - denied[ 0 ] = '\0'; - if( p->pers.denyBuild ) - { - Q_strncpyz( denied, "B", sizeof( denied ) ); - } + muted = p->pers.muted ? 'M' : ' '; + denied = p->pers.denyBuild ? 'B' : ' '; l = 0; G_SanitiseString( p->pers.netname, n2, sizeof( n2 ) ); @@ -2377,28 +2245,25 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) { if( g_admin_levels[ j ]->level == l ) { - int k, colorlen; - - for( colorlen = k = 0; g_admin_levels[ j ]->name[ k ]; k++ ) - { - if( Q_IsColorString( &g_admin_levels[ j ]->name[ k ] ) ) - colorlen += 2; - } - - Com_sprintf( lname, sizeof( lname ), "%*s", - admin_level_maxname + colorlen, - g_admin_levels[ j ]->name ); + Q_strncpyz( lname, g_admin_levels[ j ]->name, sizeof( lname ) ); break; } } - ADMBP( va( "%2i %s%s^7 %-2i %s^7 (*%s) ^1%1s%1s^7 %s^7 %s%s^7%s\n", + for( colorlen = j = 0; lname[ j ]; j++ ) + { + if( Q_IsColorString( &lname[ j ] ) ) + colorlen += 2; + } + + ADMBP( va( "%2i ^%c%c^7 %-2i %*s^7 (*%s) ^1%c%c^7 %s^7 %s%s^7%s\n", i, c, t, l, + admin_level_maxname + colorlen, lname, - guid_stub, + p->pers.guid + 24, muted, denied, p->pers.netname, @@ -2412,20 +2277,20 @@ qboolean G_admin_listplayers( gentity_t *ent, int skiparg ) qboolean G_admin_showbans( gentity_t *ent, int skiparg ) { - int i, found = 0; + int i, j; + int found = 0; int max = -1, count; int t; - char duration[ 32 ]; - int max_name = 1, max_banner = 1, colorlen; + char duration[ 13 ]; + int max_name = 1, max_banner = 1; + int colorlen1, colorlen2; int len; int secs; int start = 0; char filter[ MAX_NAME_LENGTH ] = {""}; char date[ 11 ]; char *made; - int j, k; char n1[ MAX_NAME_LENGTH * 2 ] = {""}; - char n2[ MAX_NAME_LENGTH * 2 ] = {""}; qboolean numeric = qtrue; char *ip_match = NULL; int ip_match_len = 0; @@ -2435,11 +2300,8 @@ qboolean G_admin_showbans( gentity_t *ent, int skiparg ) for( i = 0; i < MAX_ADMIN_BANS && g_admin_bans[ i ]; i++ ) { - if( g_admin_bans[ i ]->expires != 0 && - ( g_admin_bans[ i ]->expires - t ) < 1 ) - { + if( g_admin_bans[ i ]->expires != 0 && g_admin_bans[ i ]->expires <= t ) continue; - } found++; max = i; } @@ -2488,8 +2350,7 @@ qboolean G_admin_showbans( gentity_t *ent, int skiparg ) { for( i = max, count = 0; i >= 0 && count < -start; i-- ) { - if( g_admin_bans[ i ]->expires == 0 || - ( g_admin_bans[ i ]->expires - t ) > 0 ) + if( g_admin_bans[ i ]->expires == 0 || g_admin_bans[ i ]->expires > t ) count++; } @@ -2497,9 +2358,6 @@ qboolean G_admin_showbans( gentity_t *ent, int skiparg ) } } - if( start < 0 ) - start = 0; - if( start > max ) { ADMP( va( "^3!showbans: ^7%d is the last valid ban\n", max + 1 ) ); @@ -2508,8 +2366,7 @@ qboolean G_admin_showbans( gentity_t *ent, int skiparg ) for( i = start, count = 0; i <= max && count < MAX_ADMIN_SHOWBANS; i++ ) { - if( g_admin_bans[ i ]->expires != 0 && - ( g_admin_bans[ i ]->expires - t ) < 1 ) + if( g_admin_bans[ i ]->expires != 0 && g_admin_bans[ i ]->expires <= t ) continue; if( name_match[ 0 ] ) @@ -2536,8 +2393,7 @@ qboolean G_admin_showbans( gentity_t *ent, int skiparg ) ADMBP_begin(); for( i = start, count = 0; i <= max && count < MAX_ADMIN_SHOWBANS; i++ ) { - if( g_admin_bans[ i ]->expires != 0 && - ( g_admin_bans[ i ]->expires - t ) < 1 ) + if( g_admin_bans[ i ]->expires != 0 && g_admin_bans[ i ]->expires <= t ) continue; if( name_match[ 0 ] ) @@ -2555,44 +2411,34 @@ qboolean G_admin_showbans( gentity_t *ent, int skiparg ) // only print out the the date part of made date[ 0 ] = '\0'; made = g_admin_bans[ i ]->made; - for( j = 0; made && *made; j++ ) - { - if( ( j + 1 ) >= sizeof( date ) ) - break; - if( *made == ' ' ) - break; - date[ j ] = *made; - date[ j + 1 ] = '\0'; - made++; - } + for( j = 0; *made && *made != ' ' && j < sizeof( date ) - 1; j++ ) + date[ j ] = *made++; + date[ j ] = 0; - secs = ( g_admin_bans[ i ]->expires - t ); + secs = g_admin_bans[ i ]->expires - t; G_admin_duration( secs, duration, sizeof( duration ) ); - for( colorlen = k = 0; g_admin_bans[ i ]->name[ k ]; k++ ) + for( colorlen1 = j = 0; g_admin_bans[ i ]->name[ j ]; j++ ) { - if( Q_IsColorString( &g_admin_bans[ i ]->name[ k ] ) ) - colorlen += 2; + if( Q_IsColorString( &g_admin_bans[ i ]->name[ j ] ) ) + colorlen1 += 2; } - Com_sprintf( n1, sizeof( n1 ), "%*s", max_name + colorlen, - g_admin_bans[ i ]->name ); - - for( colorlen = k = 0; g_admin_bans[ i ]->banner[ k ]; k++ ) + for( colorlen2 = j = 0; g_admin_bans[ i ]->banner[ j ]; j++ ) { - if( Q_IsColorString( &g_admin_bans[ i ]->banner[ k ] ) ) - colorlen += 2; + if( Q_IsColorString( &g_admin_bans[ i ]->banner[ j ] ) ) + colorlen2 += 2; } - Com_sprintf( n2, sizeof( n2 ), "%*s", max_banner + colorlen, - g_admin_bans[ i ]->banner ); - ADMBP( va( "%4i %s^7 %-15s %-8s %s^7 %-10s\n \\__ %s\n", + ADMBP( va( "%4i %*s^7 %-15s %-8s %*s^7 %-10s\n \\__ %s\n", ( i + 1 ), - n1, + max_name + colorlen1, + g_admin_bans[ i ]->name, g_admin_bans[ i ]->ip, date, - n2, + max_banner + colorlen2, + g_admin_bans[ i ]->banner, duration, g_admin_bans[ i ]->reason ) ); } @@ -2628,7 +2474,6 @@ qboolean G_admin_help( gentity_t *ent, int skiparg ) if( G_SayArgc() < 2 + skiparg ) { - int j = 0; int count = 0; ADMBP_begin(); @@ -2637,14 +2482,10 @@ qboolean G_admin_help( gentity_t *ent, int skiparg ) if( G_admin_permission( ent, g_admin_cmds[ i ].flag[ 0 ] ) ) { ADMBP( va( "^3!%-12s", g_admin_cmds[ i ].keyword ) ); - j++; count++; - } - // show 6 commands per line - if( j == 6 ) - { - ADMBP( "\n" ); - j = 0; + // show 6 commands per line + if( count % 6 == 0 ) + ADMBP( "\n" ); } } for( i = 0; i < MAX_ADMIN_COMMANDS && g_admin_commands[ i ]; i++ ) @@ -2652,17 +2493,13 @@ qboolean G_admin_help( gentity_t *ent, int skiparg ) if( ! admin_command_permission( ent, g_admin_commands[ i ]->command ) ) continue; ADMBP( va( "^3!%-12s", g_admin_commands[ i ]->command ) ); - j++; count++; // show 6 commands per line - if( j == 6 ) - { - ADMBP( "\n" ); - j = 0; - } + if( count % 6 == 0 ) + ADMBP( "\n" ); } - if( count ) - ADMBP( "\n" ); + if( count % 6 ) + ADMBP( "\n" ); ADMBP( va( "^3!help: ^7%i available commands\n", count ) ); ADMBP( "run !help [^3command^7] for help with a specific command.\n" ); ADMBP_end(); @@ -2787,7 +2624,7 @@ qboolean G_admin_allready( gentity_t *ent, int skiparg ) if( cl->pers.teamSelection == TEAM_NONE ) continue; - cl->readyToExit = 1; + cl->readyToExit = qtrue; } AP( va( "print \"^3!allready:^7 %s^7 says everyone is READY now\n\"", ( ent ) ? ent->client->pers.netname : "console" ) ); @@ -2854,7 +2691,7 @@ qboolean G_admin_spec999( gentity_t *ent, int skiparg ) if( vic->client->ps.ping == 999 ) { G_ChangeTeam( vic, TEAM_NONE ); - AP( va( "print \"^3!spec999: ^7%s^7 moved ^7%s^7 to spectators\n\"", + AP( va( "print \"^3!spec999: ^7%s^7 moved %s^7 to spectators\n\"", ( ent ) ? ent->client->pers.netname : "console", vic->client->pers.netname ) ); } @@ -2867,10 +2704,8 @@ qboolean G_admin_rename( gentity_t *ent, int skiparg ) int pids[ MAX_CLIENTS ], found; char name[ MAX_NAME_LENGTH ]; char newname[ MAX_NAME_LENGTH ]; - char oldname[ MAX_NAME_LENGTH ]; char err[ MAX_STRING_CHARS ]; char userinfo[ MAX_INFO_STRING ]; - char *s; gentity_t *victim = NULL; if( G_SayArgc() < 3 + skiparg ) @@ -2879,8 +2714,7 @@ qboolean G_admin_rename( gentity_t *ent, int skiparg ) return qfalse; } G_SayArgv( 1 + skiparg, name, sizeof( name ) ); - s = G_SayConcatArgs( 2 + skiparg ); - Q_strncpyz( newname, s, sizeof( newname ) ); + Q_strncpyz( newname, G_SayConcatArgs( 2 + skiparg ), sizeof( newname ) ); if( ( found = G_ClientNumbersFromString( name, pids, MAX_CLIENTS ) ) != 1 ) { G_MatchOnePlayer( pids, found, err, sizeof( err ) ); @@ -2899,18 +2733,16 @@ qboolean G_admin_rename( gentity_t *ent, int skiparg ) ADMP( va( "^3!rename: ^7%s\n", err ) ); return qfalse; } - level.clients[ pids[ 0 ] ].pers.nameChanges--; - level.clients[ pids[ 0 ] ].pers.nameChangeTime = 0; + victim->client->pers.nameChanges--; + victim->client->pers.nameChangeTime = 0; trap_GetUserinfo( pids[ 0 ], userinfo, sizeof( userinfo ) ); - s = Info_ValueForKey( userinfo, "name" ); - Q_strncpyz( oldname, s, sizeof( oldname ) ); - Info_SetValueForKey( userinfo, "name", newname ); - trap_SetUserinfo( pids[ 0 ], userinfo ); - ClientUserinfoChanged( pids[ 0 ] ); AP( va( "print \"^3!rename: ^7%s^7 has been renamed to %s^7 by %s\n\"", - oldname, + victim->client->pers.netname, newname, ( ent ) ? ent->client->pers.netname : "console" ) ); + Info_SetValueForKey( userinfo, "name", newname ); + trap_SetUserinfo( pids[ 0 ], userinfo ); + ClientUserinfoChanged( pids[ 0 ] ); return qtrue; } @@ -2962,8 +2794,6 @@ qboolean G_admin_namelog( gentity_t *ent, int skiparg ) char search[ MAX_NAME_LENGTH ] = {""}; char s2[ MAX_NAME_LENGTH ] = {""}; char n2[ MAX_NAME_LENGTH ] = {""}; - char guid_stub[ 9 ]; - qboolean found = qfalse; int printed = 0; if( G_SayArgc() > 1 + skiparg ) @@ -2976,30 +2806,23 @@ qboolean G_admin_namelog( gentity_t *ent, int skiparg ) { if( search[ 0 ] ) { - found = qfalse; for( j = 0; j < MAX_ADMIN_NAMELOG_NAMES && g_admin_namelog[ i ]->name[ j ][ 0 ]; j++ ) { G_SanitiseString( g_admin_namelog[ i ]->name[ j ], n2, sizeof( n2 ) ); if( strstr( n2, s2 ) ) { - found = qtrue; break; } } - if( !found ) + if( j == MAX_ADMIN_NAMELOG_NAMES || !g_admin_namelog[ i ]->name[ j ][ 0 ] ) continue; } printed++; - for( j = 0; j < 8; j++ ) - guid_stub[ j ] = g_admin_namelog[ i ]->guid[ j + 24 ]; - guid_stub[ j ] = '\0'; - if( g_admin_namelog[ i ]->slot > -1 ) - ADMBP( "^3" ); - ADMBP( va( "%-2s (*%s) %15s^7", + ADMBP( va( "%s (*%s) %15s^7", ( g_admin_namelog[ i ]->slot > -1 ) ? - va( "%d", g_admin_namelog[ i ]->slot ) : "-", - guid_stub, g_admin_namelog[ i ]->ip ) ); + va( "^3%-2d", g_admin_namelog[ i ]->slot ) : "-", + g_admin_namelog[ i ]->guid + 24, g_admin_namelog[ i ]->ip ) ); for( j = 0; j < MAX_ADMIN_NAMELOG_NAMES && g_admin_namelog[ i ]->name[ j ][ 0 ]; j++ ) { diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index c077a3b6..4f5159dd 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -3314,20 +3314,9 @@ qboolean G_SayArgv( int n, char *buffer, int bufferLength ) return qfalse; if( n < 0 ) return qfalse; - s = ConcatArgs( 0 ); - while( 1 ) - { - while( *s == ' ' ) - s++; - if( !*s || n == 0 ) - break; - n--; - while( *s && *s != ' ' ) - s++; - } - if( n > 0 ) + s = G_SayConcatArgs( n ); + if( !*s ) return qfalse; - //memccpy( buffer, s, ' ', bufferLength ); while( *s && *s != ' ' && bufferLength > 1 ) { *buffer++ = *s++; @@ -3361,9 +3350,7 @@ void G_DecolorString( char *in, char *out, int len ) while( *in && len > 0 ) { if( Q_IsColorString( in ) ) { - in++; - if( *in ) - in++; + in += 2; continue; } *out++ = *in++; |