2005-09-27 04:05:32 +00:00
// log.c: handles console logging functions and cvars
# include "quakedef.h"
2006-04-12 00:17:02 +00:00
// cvar callbacks
void Log_Dir_Callback ( struct cvar_s * var , char * oldvalue ) ;
void Log_Name_Callback ( struct cvar_s * var , char * oldvalue ) ;
2005-09-27 04:05:32 +00:00
// cvars
# define CONLOGGROUP "Console logging"
2010-07-11 02:22:39 +00:00
cvar_t log_enable [ LOG_TYPES ] = { CVARF ( " log_enable " , " 0 " , CVAR_NOTFROMSERVER ) ,
2014-06-24 03:02:32 +00:00
CVARF ( " log_enable_players " , " 0 " , CVAR_NOTFROMSERVER ) ,
CVARF ( " log_enable_rcon " , " 1 " , CVAR_NOTFROMSERVER )
} ;
2010-07-11 02:22:39 +00:00
cvar_t log_name [ LOG_TYPES ] = { CVARFC ( " log_name " , " " , CVAR_NOTFROMSERVER , Log_Name_Callback ) ,
2014-09-02 02:44:43 +00:00
CVARFC ( " log_name_players " , " players " , CVAR_NOTFROMSERVER , Log_Name_Callback ) ,
CVARFC ( " log_name_rcon " , " rcon " , CVAR_NOTFROMSERVER , Log_Name_Callback ) } ;
2010-07-11 02:22:39 +00:00
cvar_t log_dir = CVARFC ( " log_dir " , " " , CVAR_NOTFROMSERVER , Log_Dir_Callback ) ;
2013-10-08 14:28:11 +00:00
cvar_t log_readable = CVARFD ( " log_readable " , " 7 " , CVAR_NOTFROMSERVER , " Bitfield describing what to convert/strip. If 0, exact byte representation will be used. \n &1: Dequakify text. \n &2: Strip special markup. \n &4: Strip ansi control codes. " ) ;
2010-07-11 02:22:39 +00:00
cvar_t log_developer = CVARF ( " log_developer " , " 0 " , CVAR_NOTFROMSERVER ) ;
cvar_t log_rotate_files = CVARF ( " log_rotate_files " , " 0 " , CVAR_NOTFROMSERVER ) ;
cvar_t log_rotate_size = CVARF ( " log_rotate_size " , " 131072 " , CVAR_NOTFROMSERVER ) ;
2013-10-08 14:28:11 +00:00
cvar_t log_timestamps = CVARF ( " log_timestamps " , " 1 " , CVAR_NOTFROMSERVER ) ;
# ifdef _WIN32
cvar_t log_dosformat = CVARF ( " log_dosformat " , " 1 " , CVAR_NOTFROMSERVER ) ;
# else
2010-07-11 02:22:39 +00:00
cvar_t log_dosformat = CVARF ( " log_dosformat " , " 0 " , CVAR_NOTFROMSERVER ) ;
2013-10-08 14:28:11 +00:00
# endif
qboolean log_newline [ LOG_TYPES ] ;
2005-09-27 04:05:32 +00:00
// externals
extern char gamedirfile [ ] ;
2006-04-12 00:17:02 +00:00
// Log_Dir_Callback: called when a log_dir is changed
void Log_Dir_Callback ( struct cvar_s * var , char * oldvalue )
{
char * t = var - > string ;
2014-01-17 08:31:16 +00:00
char * e = t + ( * t ? strlen ( t ) : 0 ) ;
2006-04-12 00:17:02 +00:00
2014-01-17 08:31:16 +00:00
// sanity check for directory. // is equivelent to /../ on some systems, so make sure that can't be used either. : is for drives on windows or amiga, or alternative thingies on windows, so block thoses completely.
if ( strstr ( t , " .. " ) | | strstr ( t , " : " ) | | * t = = ' / ' | | * t = = ' \\ ' | | * e = = ' / ' | | * e = = ' \\ ' | | strstr ( t , " // " ) | | strstr ( t , " \\ \\ " ) )
2006-04-12 00:17:02 +00:00
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_NOTICE " %s forced to default due to invalid characters. \n " , var - > name ) ;
2006-04-12 00:17:02 +00:00
// recursion is avoided by assuming the default value is sane
Cvar_ForceSet ( var , var - > defaultstr ) ;
}
}
2007-07-27 21:24:31 +00:00
// Log_Name_Callback: called when a log_name is changed
2006-04-12 00:17:02 +00:00
void Log_Name_Callback ( struct cvar_s * var , char * oldvalue )
{
char * t = var - > string ;
// sanity check for directory
if ( strstr ( t , " .. " ) | | strstr ( t , " : " ) | | strstr ( t , " / " ) | | strstr ( t , " \\ " ) )
{
2007-09-23 15:28:06 +00:00
Con_Printf ( CON_NOTICE " %s forced to default due to invalid characters. \n " , var - > name ) ;
2006-04-12 00:17:02 +00:00
// recursion is avoided by assuming the default value is sane
Cvar_ForceSet ( var , var - > defaultstr ) ;
}
}
2005-09-27 04:05:32 +00:00
// Con_Log: log string to console log
2007-07-27 21:24:31 +00:00
void Log_String ( logtype_t lognum , char * s )
2005-09-27 04:05:32 +00:00
{
2007-07-27 21:24:31 +00:00
vfsfile_t * fi ;
2005-09-27 04:05:32 +00:00
char * d ; // directory
char * f ; // filename
char * t ;
2013-10-08 14:28:11 +00:00
char utf8 [ 2048 ] ;
2005-09-27 04:05:32 +00:00
int i ;
2014-12-06 02:19:34 +00:00
char fbase [ MAX_QPATH ] ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
char fname [ MAX_QPATH ] ;
2013-10-08 14:28:11 +00:00
conchar_t cline [ 2048 ] , * c ;
unsigned int u ;
2005-09-27 04:05:32 +00:00
2007-07-27 21:24:31 +00:00
f = NULL ;
switch ( lognum )
{
case LOG_CONSOLE :
f = " qconsole " ;
break ;
case LOG_PLAYER :
f = " players " ;
break ;
2014-06-24 03:02:32 +00:00
case LOG_RCON :
f = " rcon " ;
break ;
2007-07-27 21:24:31 +00:00
default :
2014-08-25 07:35:41 +00:00
return ;
2007-07-27 21:24:31 +00:00
}
2014-08-25 07:35:41 +00:00
if ( ! log_enable [ lognum ] . value )
return ;
// get directory/filename
if ( log_dir . string [ 0 ] )
d = log_dir . string ;
else
d = " " ; //gamedirfile;
2007-07-27 21:24:31 +00:00
if ( log_name [ lognum ] . string [ 0 ] )
f = log_name [ lognum ] . string ;
if ( ! f )
return ;
2005-09-27 04:05:32 +00:00
2013-10-08 14:28:11 +00:00
COM_ParseFunString ( CON_WHITEMASK , s , cline , sizeof ( cline ) , ! ( log_readable . ival & 2 ) ) ;
t = utf8 ;
for ( c = cline ; * c ; c + + )
2005-09-27 04:05:32 +00:00
{
2013-10-08 14:28:11 +00:00
if ( ( * c & CON_HIDDEN ) & & ( log_readable . ival & 2 ) )
continue ;
if ( log_readable . ival & 1 )
u = COM_DeQuake ( * c ) ;
else
u = * c & CON_CHARMASK ;
2005-09-27 04:05:32 +00:00
2013-10-08 14:28:11 +00:00
//at the start of a new line, we might want a timestamp (so timestamps are correct for the first char of the line, instead of the preceeding \n)
if ( log_newline [ lognum ] )
2005-09-27 04:05:32 +00:00
{
2013-10-08 14:28:11 +00:00
if ( log_timestamps . ival )
2005-09-27 04:05:32 +00:00
{
2013-10-08 14:28:11 +00:00
time_t unixtime = time ( NULL ) ;
2014-05-30 03:57:30 +00:00
int bufferspace = utf8 + sizeof ( utf8 ) - 1 - t ;
if ( bufferspace > 0 )
{
strftime ( t , bufferspace , " %Y-%m-%d %H:%M:%S " , localtime ( & unixtime ) ) ;
t + = strlen ( t ) ;
}
2005-09-27 04:05:32 +00:00
}
2013-10-08 14:28:11 +00:00
log_newline [ lognum ] = false ;
2005-09-27 04:05:32 +00:00
}
2013-10-08 14:28:11 +00:00
//make sure control codes are stripped. no exploiting xterm bugs please.
if ( ( log_readable . ival & 4 ) & & ( ( u < 32 & & u ! = ' \t ' & & u ! = ' \n ' ) | | u = = 127 | | ( u > = 128 & & u < 128 + 32 ) ) ) //\r is stripped too
u = ' ? ' ;
//if dos format logs, we insert a \r before every \n (also flag next char as the start of a new line)
if ( u = = ' \n ' )
2005-09-27 04:05:32 +00:00
{
2013-10-08 14:28:11 +00:00
log_newline [ lognum ] = true ;
if ( log_dosformat . ival )
t + = utf8_encode ( t , ' \r ' , utf8 + sizeof ( utf8 ) - 1 - t ) ;
2005-09-27 04:05:32 +00:00
}
2013-10-08 14:28:11 +00:00
t + = utf8_encode ( t , u , utf8 + sizeof ( utf8 ) - 1 - t ) ;
2005-09-27 04:05:32 +00:00
}
* t = 0 ;
2014-01-17 08:31:16 +00:00
if ( * d )
2014-12-06 02:19:34 +00:00
Q_snprintfz ( fbase , sizeof ( fname ) - 4 , " %s/%s " , d , f ) ;
2014-01-17 08:31:16 +00:00
else
2014-12-06 02:19:34 +00:00
Q_snprintfz ( fbase , sizeof ( fname ) - 4 , " %s " , f ) ;
Q_snprintfz ( fname , sizeof ( fname ) , " %s.log " , fbase ) ;
2005-09-27 04:05:32 +00:00
// file rotation
2006-03-04 20:43:48 +00:00
if ( log_rotate_size . value > = 4096 & & log_rotate_files . value > = 1 )
2005-09-27 04:05:32 +00:00
{
int x ;
2005-12-21 03:07:33 +00:00
vfsfile_t * fi ;
2005-09-27 04:05:32 +00:00
// check file size, use x as temp
2013-10-08 14:28:11 +00:00
if ( ( fi = FS_OpenVFS ( fname , " rb " , FS_GAMEONLY ) ) )
2005-09-27 04:05:32 +00:00
{
2005-12-21 03:07:33 +00:00
x = VFS_GETLEN ( fi ) ;
VFS_CLOSE ( fi ) ;
2013-10-08 14:28:11 +00:00
x + = strlen ( utf8 ) ; // add string size to file size to never go over
2005-09-27 04:05:32 +00:00
}
else
x = 0 ;
if ( x > ( int ) log_rotate_size . value )
{
char newf [ MAX_OSPATH ] ;
char oldf [ MAX_OSPATH ] ;
i = log_rotate_files . value ;
2006-03-04 20:43:48 +00:00
2005-09-27 04:05:32 +00:00
// unlink file at the top of the chain
2014-12-06 02:19:34 +00:00
Q_snprintfz ( oldf , sizeof ( oldf ) , " %s.%i.log " , fbase , i ) ;
2013-10-08 14:28:11 +00:00
FS_Remove ( oldf , FS_GAMEONLY ) ;
2005-09-27 04:05:32 +00:00
// rename files through chain
for ( x = i - 1 ; x > 0 ; x - - )
{
strcpy ( newf , oldf ) ;
2014-12-06 02:19:34 +00:00
Q_snprintfz ( oldf , sizeof ( oldf ) , " %s.%i.log " , fbase , x ) ;
2005-09-27 04:05:32 +00:00
// check if file exists, otherwise skip
2013-10-08 14:28:11 +00:00
if ( ( fi = FS_OpenVFS ( oldf , " rb " , FS_GAMEONLY ) ) )
2005-12-21 03:07:33 +00:00
VFS_CLOSE ( fi ) ;
2005-09-27 04:05:32 +00:00
else
continue ; // skip nonexistant files
2013-10-08 14:28:11 +00:00
if ( ! FS_Rename ( oldf , newf , FS_GAMEONLY ) )
2005-09-27 04:05:32 +00:00
{
// rename failed, disable log and bug out
2007-07-27 21:24:31 +00:00
Cvar_ForceSet ( & log_enable [ lognum ] , " 0 " ) ;
2005-09-27 04:05:32 +00:00
Con_Printf ( " Unable to rotate log files. Logging disabled. \n " ) ;
return ;
}
}
// TODO: option to compress file somewhere in here?
2013-10-08 14:28:11 +00:00
// rename our base file, which had better exist...
if ( ! FS_Rename ( fname , oldf , FS_GAMEONLY ) )
2005-09-27 04:05:32 +00:00
{
// rename failed, disable log and bug out
2007-07-27 21:24:31 +00:00
Cvar_ForceSet ( & log_enable [ lognum ] , " 0 " ) ;
2005-09-27 04:05:32 +00:00
Con_Printf ( " Unable to rename base log file. Logging disabled. \n " ) ;
return ;
}
}
}
2013-10-08 14:28:11 +00:00
FS_CreatePath ( fname , FS_GAMEONLY ) ;
if ( ( fi = FS_OpenVFS ( fname , " ab " , FS_GAMEONLY ) ) )
2007-07-27 21:24:31 +00:00
{
2013-10-08 14:28:11 +00:00
VFS_WRITE ( fi , utf8 , strlen ( utf8 ) ) ;
2007-07-27 21:24:31 +00:00
VFS_CLOSE ( fi ) ;
}
else
2005-12-05 16:47:29 +00:00
{
// write failed, bug out
2007-07-27 21:24:31 +00:00
Cvar_ForceSet ( & log_enable [ lognum ] , " 0 " ) ;
2005-12-05 16:47:29 +00:00
Con_Printf ( " Unable to write to log file. Logging disabled. \n " ) ;
return ;
}
2005-09-27 04:05:32 +00:00
}
2007-07-27 21:24:31 +00:00
void Con_Log ( char * s )
{
Log_String ( LOG_CONSOLE , s ) ;
}
2007-08-07 14:41:23 +00:00
# ifndef CLIENTONLY
2007-07-27 21:24:31 +00:00
//still to add stuff at:
//connects
//disconnects
//kicked
void SV_LogPlayer ( client_t * cl , char * msg )
{
char line [ 2048 ] ;
2008-06-08 14:37:57 +00:00
char remote_adr [ MAX_ADR_SIZE ] ;
char realip_adr [ MAX_ADR_SIZE ] ;
2008-12-06 02:08:57 +00:00
if ( cl - > protocol = = SCP_BAD )
return ; //don't log botclients
2007-07-27 21:24:31 +00:00
snprintf ( line , sizeof ( line ) ,
2013-10-08 14:28:11 +00:00
" %s \\ %s \\ %i \\ %s \\ %s \\ %i \\ guid \\ %s%s \n " ,
2011-05-15 13:23:13 +00:00
msg , cl - > name , cl - > userid ,
2013-05-03 04:28:08 +00:00
NET_BaseAdrToString ( remote_adr , sizeof ( remote_adr ) , & cl - > netchan . remote_address ) , ( cl - > realip_status > 0 ? NET_BaseAdrToString ( realip_adr , sizeof ( realip_adr ) , & cl - > realip ) : " ?? " ) ,
2013-10-08 14:28:11 +00:00
cl - > netchan . remote_address . port , cl - > guid , cl - > userinfo ) ;
2007-07-27 21:24:31 +00:00
Log_String ( LOG_PLAYER , line ) ;
}
2007-08-07 14:41:23 +00:00
# endif
2007-07-27 21:24:31 +00:00
void Log_Logfile_f ( void )
{
extern char gamedirfile [ ] ;
if ( log_enable [ LOG_CONSOLE ] . value )
{
Cvar_SetValue ( & log_enable [ LOG_CONSOLE ] , 0 ) ;
Con_Printf ( " Logging disabled. \n " ) ;
}
else
{
char * d , * f ;
d = gamedirfile ;
if ( log_dir . string [ 0 ] )
d = log_dir . string ;
f = " qconsole " ;
if ( log_name [ LOG_CONSOLE ] . string [ 0 ] )
f = log_name [ LOG_CONSOLE ] . string ;
2011-05-15 13:23:13 +00:00
Con_Printf ( " %s " , va ( " Logging to %s/%s.log. \n " , d , f ) ) ;
2007-07-27 21:24:31 +00:00
Cvar_SetValue ( & log_enable [ LOG_CONSOLE ] , 1 ) ;
}
}
/*
void SV_Fraglogfile_f ( void )
{
char name [ MAX_OSPATH ] ;
int i ;
if ( sv_fraglogfile )
{
2013-11-29 14:36:47 +00:00
Con_TPrintf ( " Frag file logging off. \n " ) ;
2007-07-27 21:24:31 +00:00
VFS_CLOSE ( sv_fraglogfile ) ;
sv_fraglogfile = NULL ;
return ;
}
// find an unused name
for ( i = 0 ; i < 1000 ; i + + )
{
sprintf ( name , " frag_%i.log " , i ) ;
sv_fraglogfile = FS_OpenVFS ( name , " rb " , FS_GAME ) ;
if ( ! sv_fraglogfile )
{ // can't read it, so create this one
sv_fraglogfile = FS_OpenVFS ( name , " wb " , FS_GAME ) ;
if ( ! sv_fraglogfile )
i = 1000 ; // give error
break ;
}
VFS_CLOSE ( sv_fraglogfile ) ;
}
if ( i = = 1000 )
{
2013-11-29 14:36:47 +00:00
Con_TPrintf ( " Can't open any logfiles. \n " ) ;
2007-07-27 21:24:31 +00:00
sv_fraglogfile = NULL ;
return ;
}
2013-11-29 14:36:47 +00:00
Con_TPrintf ( " Logging frags to %s. \n " , name ) ;
2007-07-27 21:24:31 +00:00
}
*/
2005-09-27 04:05:32 +00:00
void Log_Init ( void )
{
2007-07-27 21:24:31 +00:00
int i ;
2005-09-27 04:05:32 +00:00
// register cvars
2007-07-27 21:24:31 +00:00
for ( i = 0 ; i < LOG_TYPES ; i + + )
{
Cvar_Register ( & log_enable [ i ] , CONLOGGROUP ) ;
Cvar_Register ( & log_name [ i ] , CONLOGGROUP ) ;
2013-10-08 14:28:11 +00:00
log_newline [ i ] = true ;
2007-07-27 21:24:31 +00:00
}
2005-09-27 04:05:32 +00:00
Cvar_Register ( & log_dir , CONLOGGROUP ) ;
Cvar_Register ( & log_readable , CONLOGGROUP ) ;
Cvar_Register ( & log_developer , CONLOGGROUP ) ;
Cvar_Register ( & log_rotate_size , CONLOGGROUP ) ;
Cvar_Register ( & log_rotate_files , CONLOGGROUP ) ;
Cvar_Register ( & log_dosformat , CONLOGGROUP ) ;
2013-10-08 14:28:11 +00:00
Cvar_Register ( & log_timestamps , CONLOGGROUP ) ;
2005-09-27 04:05:32 +00:00
2007-07-27 21:24:31 +00:00
Cmd_AddCommand ( " logfile " , Log_Logfile_f ) ;
2005-09-27 04:05:32 +00:00
// cmd line options, debug options
# ifdef CRAZYDEBUGGING
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
Cvar_ForceSet ( & log_enable [ LOG_CONSOLE ] , " 1 " ) ;
2005-09-27 04:05:32 +00:00
TRACE ( ( " dbg: Con_Init: log_enable forced \n " ) ) ;
# endif
if ( COM_CheckParm ( " -condebug " ) )
2007-07-27 21:24:31 +00:00
Cvar_ForceSet ( & log_enable [ LOG_CONSOLE ] , " 1 " ) ;
2006-03-04 20:43:48 +00:00
}