/* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. A raw string should NEVER be passed as fmt, because of "%f" type crashers. ============= */ void QDECL Com_Printf( const char *fmt, ... ) { va_list argptr; char msg[MAXPRINTMSG]; va_start (argptr,fmt); vsprintf (msg,fmt,argptr); va_end (argptr); if ( rd_buffer ) { if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_buffer); *rd_buffer = 0; } Q_strcat(rd_buffer, rd_buffersize, msg); rd_flush(rd_buffer); *rd_buffer = 0; return; } // echo to console if we're not a dedicated server if ( com_dedicated && !com_dedicated->integer ) { CL_ConsolePrint( msg ); } // echo to dedicated console and early console Sys_Print( msg ); // logfile #ifndef _XBOX if ( com_logfile && com_logfile->integer ) { if ( !logfile && FS_Initialized() ) { struct tm *newtime; time_t aclock; time( &aclock ); newtime = localtime( &aclock ); logfile = FS_FOpenFileWrite( "qconsole.log" ); Com_Printf( "logfile opened on %s\n", asctime( newtime ) ); if ( com_logfile->integer > 1 ) { // force it to not buffer so we get valid // data even if we are crashing FS_ForceFlush(logfile); } } if ( logfile && FS_Initialized()) { FS_Write(msg, strlen(msg), logfile); } } #endif #if defined(_WIN32) && defined(_DEBUG) && !defined(_XBOX) if ( *msg ) { OutputDebugString ( Q_CleanStr(msg) ); OutputDebugString ("\n"); } #endif }
/* * Both client and server can use this, and it will output * to the apropriate place. */ void Com_Printf(char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; va_start(argptr, fmt); vsnprintf(msg, MAXPRINTMSG, fmt, argptr); va_end(argptr); if (rd_target) { if ((strlen(msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_target, rd_buffer); *rd_buffer = 0; } strcat(rd_buffer, msg); return; } #ifndef DEDICATED_ONLY Con_Print(msg); #endif /* also echo to debugging console */ Sys_ConsoleOutput(msg); /* logfile */ if (logfile_active && logfile_active->value) { char name[MAX_QPATH]; if (!logfile) { Com_sprintf(name, sizeof(name), "%s/qconsole.log", FS_Gamedir()); if (logfile_active->value > 2) { logfile = fopen(name, "a"); } else { logfile = fopen(name, "w"); } } if (logfile) { fprintf(logfile, "%s", msg); } if (logfile_active->value > 1) { fflush(logfile); /* force it to save every time */ } } }
void Com_EndRedirect (void) { rd_flush(rd_target, rd_buffer); rd_target = 0; rd_buffer = NULL; rd_buffersize = 0; rd_flush = NULL; }
void Com_EndRedirect( void ) { if ( rd_flush ) { rd_flush( rd_buffer ); } rd_buffer = NULL; rd_buffersize = 0; rd_flush = NULL; }
/* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. ============= */ void Com_Printf (char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; static qboolean printstamp = true; // jittimestamp va_start(argptr, fmt); _vsnprintf(msg, sizeof(msg), fmt, argptr); // jitsecurity -- prevent buffer overruns va_end(argptr); NULLTERMINATE(msg); // jitsecurity -- make sure string is null terminated. if (rd_target) { if ((strlen(msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_target, rd_buffer); *rd_buffer = 0; } strcat(rd_buffer, msg); return; } Con_Print(msg); // === // jittimestamp if (printstamp && timestamp_console && timestamp_console->value) { // don't tag timestamps on if it's not a new line time_t now; char timestamp[256]; struct tm *nowtime; static int lastday = -1; time(&now); nowtime = localtime(&now); if (nowtime->tm_mday != lastday) { Com_sprintf(timestamp, sizeof(timestamp), "[********] Date: %04d-%02d-%02d\n", nowtime->tm_year + 1900, nowtime->tm_mon + 1, nowtime->tm_mday); Sys_ConsoleOutput(timestamp); ConsoleLogfile(timestamp); lastday = nowtime->tm_mday; } strftime(timestamp, sizeof(timestamp), "[%H:%M:%S] ", nowtime); Sys_ConsoleOutput(timestamp); ConsoleLogfile(timestamp); } Sys_ConsoleOutput(msg); printstamp = (strchr(msg, '\n') != NULL); // so we only print timestamps after a newline. ConsoleLogfile(msg); // jittimestamp // === }
/* ================== idCommonLocal::EndRedirect ================== */ void idCommonLocal::EndRedirect() { if ( rd_flush && rd_buffer[ 0 ] ) { rd_flush( rd_buffer ); } rd_buffer = NULL; rd_buffersize = 0; rd_flush = NULL; }
__cdecl void Com_PrintMessage( int dumbIWvar, char *msg, msgtype_t type) { //secures calls to Com_PrintMessage from recursion while redirect printing static qboolean lock = qfalse; if(dumbIWvar == 6) return; int msglen = strlen(msg); if(type != MSG_NORDPRINT && !lock) { Sys_EnterCriticalSection(CRIT_REDIRECTPRINT); if ( !lock) { lock = qtrue; Com_PrintRedirect(msg, msglen); lock = qfalse; if ( rd_buffer ) { if(!rd_flush){ Sys_LeaveCriticalSection(CRIT_REDIRECTPRINT); return; } if ((msglen + strlen(rd_buffer)) > (rd_buffersize - 1)) { lock = qtrue; rd_flush(rd_buffer, qfalse); lock = qfalse; *rd_buffer = 0; } Q_strcat(rd_buffer, rd_buffersize, msg); // TTimo nooo .. that would defeat the purpose //rd_flush(rd_buffer); //*rd_buffer = 0; Sys_LeaveCriticalSection(CRIT_REDIRECTPRINT); return; } } Sys_LeaveCriticalSection(CRIT_REDIRECTPRINT); } // echo to dedicated console and early console Sys_Print( msg ); // logfile Com_PrintLogfile( msg ); }
void Com_EndRedirect( void ) { rd_flush( rd_target, rd_buffer, rd_extra ); rd_target = 0; rd_buffer = NULL; rd_buffersize = 0; rd_flush = NULL; rd_extra = NULL; QMutex_Unlock( com_print_mutex ); }
void QDECL Com_PrintfAlways( const char *fmt, ... ) { va_list argptr; char msg[MAXPRINTMSG]; va_start (argptr,fmt); vsprintf (msg,fmt,argptr); va_end (argptr); #ifndef _XBOX if ( rd_buffer ) { if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_buffer); *rd_buffer = 0; } strcat (rd_buffer, msg); return; } #endif CL_ConsolePrint( msg ); // echo to dedicated console and early console #ifndef FINAL_BUILD Sys_Print( msg ); #ifdef OUTPUT_TO_BUILD_WINDOW OutputDebugString(msg); #endif #endif #ifndef _XBOX // logfile if ( com_logfile && com_logfile->integer ) { if ( !logfile ) { logfile = FS_FOpenFileWrite( "qconsole.log" ); if ( com_logfile->integer > 1 ) { // force it to not buffer so we get valid // data even if we are crashing FS_ForceFlush(logfile); } } if ( logfile ) { FS_Write(msg, strlen(msg), logfile); } } #endif }
void Capture() { //TODO: follow console filtering rules if(addresses.size()){ for(i = 0; i < addresses.size(); i++){ const char* toSend = va("%i %s", channel, msg); Sys_SendPacket(strlen(toSend), toSend, addresses[i]); } } if (rd_buffer) { if ( ( strlen( msg ) + strlen( rd_buffer ) ) > ( rd_buffersize - 1 ) ) { rd_flush( rd_buffer ); *rd_buffer = 0; } strncat( rd_buffer, msg, rd_buffersize ); } }
/* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. A raw string should NEVER be passed as fmt, because of "%f" type crashers. ============= */ void QDECL Com_Printf( const char *fmt, ... ) { va_list argptr; char msg[MAXPRINTMSG]; va_start (argptr,fmt); Q_vsnprintf (msg, sizeof(msg), fmt, argptr); va_end (argptr); if ( rd_buffer ) { if ((strlen (msg) + strlen(rd_buffer)) > (unsigned)(rd_buffersize - 1)) { rd_flush(rd_buffer); *rd_buffer = 0; } Q_strcat (rd_buffer, strlen(rd_buffer), msg); return; } CL_ConsolePrint( msg ); // Strip out color codes because these aren't needed in the log/viewlog or in the output window --eez Q_StripColor( msg ); // echo to dedicated console and early console Sys_Print( msg ); #ifdef OUTPUT_TO_BUILD_WINDOW OutputDebugString(msg); #endif // logfile if ( com_logfile && com_logfile->integer ) { if ( !logfile ) { logfile = FS_FOpenFileWrite( "qconsole.log" ); if ( com_logfile->integer > 1 ) { // force it to not buffer so we get valid // data even if we are crashing FS_ForceFlush(logfile); } } if ( logfile ) { FS_Write(msg, strlen(msg), logfile); } } }
/* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. A raw string should NEVER be passed as fmt, because of "%f" type crashers. ============= */ void QDECL Com_Printf( const char *fmt, ... ) { va_list argptr; char msg[MAXPRINTMSG]; va_start (argptr,fmt); vsprintf (msg,fmt,argptr); va_end (argptr); if ( rd_buffer ) { if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_buffer); *rd_buffer = 0; } strcat (rd_buffer, msg); return; } CL_ConsolePrint( msg ); // echo to dedicated console and early console Sys_Print( msg ); // logfile if ( com_logfile && com_logfile->integer ) { if ( !logfile ) { logfile = FS_FOpenFileWrite( "qconsole.log" ); if ( com_logfile->integer > 1 ) { // force it to not buffer so we get valid // data even if we are crashing FS_ForceFlush(logfile); } } if ( logfile ) { FS_Write(msg, strlen(msg), logfile); } } }
/* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. A raw string should NEVER be passed as fmt, because of "%f" type crashers. ============= */ void QDECL Com_Printf( const char *fmt, ... ) { va_list argptr; char msg[MAXPRINTMSG]; static qboolean opening_qconsole = qfalse; va_start (argptr,fmt); Q_vsnprintf (msg, sizeof(msg), fmt, argptr); va_end (argptr); if ( rd_buffer ) { if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_buffer); *rd_buffer = 0; } Q_strcat(rd_buffer, rd_buffersize, msg); // TTimo nooo .. that would defeat the purpose //rd_flush(rd_buffer); //*rd_buffer = 0; return; } // echo to console if we're not a dedicated server if ( com_dedicated && !com_dedicated->integer ) { CL_ConsolePrint( msg ); } // echo to dedicated console and early console Sys_Print( msg ); // logfile if ( com_logfile && com_logfile->integer ) { // TTimo: only open the qconsole.log if the filesystem is in an initialized state // also, avoid recursing in the qconsole.log opening (i.e. if fs_debug is on) if ( !logfile && FS_Initialized() && !opening_qconsole ) { struct tm *newtime; time_t aclock; opening_qconsole = qtrue; time( &aclock ); newtime = localtime( &aclock ); logfile = FS_FOpenFileWrite( "qconsole.log" ); if ( logfile ) { Com_Printf( "logfile opened on %s\n", asctime( newtime ) ); if ( com_logfile->integer > 1 ) { // force it to not buffer so we get valid // data even if we are crashing FS_ForceFlush(logfile); } } else { Com_Printf( "Opening qconsole.log failed!\n" ); Cvar_SetValue( "logfile", 0 ); } } opening_qconsole = qfalse; if ( logfile && FS_Initialized()) { FS_Write(msg, strlen(msg), logfile); } } #if defined(_WIN32) && defined(_DEBUG) if ( *msg ) { OutputDebugString ( Q_CleanStr(msg) ); OutputDebugString ("\n"); } #endif }
/* * Com_Printf * * Both client and server can use this, and it will output * to the apropriate place. */ void Com_Printf( const char *format, ... ) { va_list argptr; char msg[MAX_PRINTMSG]; time_t timestamp; char timestamp_str[MAX_PRINTMSG]; struct tm *timestampptr; timestamp = time( NULL ); timestampptr = gmtime( ×tamp ); strftime( timestamp_str, MAX_PRINTMSG, "%Y-%m-%dT%H:%M:%SZ ", timestampptr ); va_start( argptr, format ); Q_vsnprintfz( msg, sizeof( msg ), format, argptr ); va_end( argptr ); if( rd_target ) { if( (int)( strlen( msg ) + strlen( rd_buffer ) ) > ( rd_buffersize - 1 ) ) { rd_flush( rd_target, rd_buffer, rd_extra ); *rd_buffer = 0; } strcat( rd_buffer, msg ); return; } QMutex_Lock( com_print_mutex ); Con_Print( msg ); // also echo to debugging console Sys_ConsoleOutput( msg ); // logconsole if( logconsole && logconsole->modified ) { logconsole->modified = qfalse; if( log_file ) { FS_FCloseFile( log_file ); log_file = 0; } if( logconsole->string && logconsole->string[0] ) { size_t name_size; char *name; name_size = strlen( logconsole->string ) + strlen( ".log" ) + 1; name = ( char* )Mem_TempMalloc( name_size ); Q_strncpyz( name, logconsole->string, name_size ); COM_DefaultExtension( name, ".log", name_size ); if( FS_FOpenFile( name, &log_file, ( logconsole_append && logconsole_append->integer ? FS_APPEND : FS_WRITE ) ) == -1 ) { log_file = 0; Com_Printf( "Couldn't open: %s\n", name ); } Mem_TempFree( name ); } } if( log_file ) { if( logconsole_timestamp && logconsole_timestamp->integer ) FS_Printf( log_file, "%s", timestamp_str ); FS_Printf( log_file, "%s", msg ); if( logconsole_flush && logconsole_flush->integer ) FS_Flush( log_file ); // force it to save every time } QMutex_Unlock( com_print_mutex ); }
/* ================== idCommonLocal::VPrintf A raw string should NEVER be passed as fmt, because of "%f" type crashes. ================== */ void idCommonLocal::VPrintf( const char *fmt, va_list args ) { static bool logFileFailed = false; // if the cvar system is not initialized if ( !cvarSystem->IsInitialized() ) { return; } // optionally put a timestamp at the beginning of each print, // so we can see how long different init sections are taking int timeLength = 0; char msg[MAX_PRINT_MSG_SIZE]; msg[ 0 ] = '\0'; if ( com_timestampPrints.GetInteger() ) { int t = Sys_Milliseconds(); if ( com_timestampPrints.GetInteger() == 1 ) { sprintf( msg, "[%5.2f]", t * 0.001f ); } else { sprintf( msg, "[%i]", t ); } } timeLength = strlen( msg ); // don't overflow if ( idStr::vsnPrintf( msg+timeLength, MAX_PRINT_MSG_SIZE-timeLength-1, fmt, args ) < 0 ) { msg[sizeof(msg)-2] = '\n'; msg[sizeof(msg)-1] = '\0'; // avoid output garbling Sys_Printf( "idCommon::VPrintf: truncated to %d characters\n", strlen(msg)-1 ); } if ( rd_buffer ) { if ( (int)( strlen( msg ) + strlen( rd_buffer ) ) > ( rd_buffersize - 1 ) ) { rd_flush( rd_buffer ); *rd_buffer = 0; } strcat( rd_buffer, msg ); return; } #ifndef ID_RETAIL if ( com_printFilter.GetString() != NULL && com_printFilter.GetString()[ 0 ] != '\0' ) { idStrStatic< 4096 > filterBuf = com_printFilter.GetString(); idStrStatic< 4096 > msgBuf = msg; filterBuf.ToLower(); msgBuf.ToLower(); char *sp = strtok( &filterBuf[ 0 ], ";" ); bool p = false; for( ; sp != NULL ; ) { if ( strstr( msgBuf, sp ) != NULL ) { p = true; break; } sp = strtok( NULL, ";" ); } if ( !p ) { return; } } #endif if ( !idLib::IsMainThread() ) { #if defined( ID_PC_WIN ) OutputDebugString( msg ); #else printf( "%s", msg ); #endif // ID_PC_WIN return; } // echo to console buffer console->Print( msg ); // remove any color codes idStr::RemoveColors( msg ); // echo to dedicated console and early console Sys_Printf( "%s", msg ); // print to script debugger server // DebuggerServerPrint( msg ); #if 0 // !@# #if defined(_DEBUG) && defined(WIN32) if ( strlen( msg ) < 512 ) { TRACE( msg ); } #endif #endif // logFile if ( com_logFile.GetInteger() && !logFileFailed && fileSystem->IsInitialized() ) { static bool recursing; if ( !logFile && !recursing ) { const char *fileName = com_logFileName.GetString()[0] ? com_logFileName.GetString() : "qconsole.log"; // fileSystem->OpenFileWrite can cause recursive prints into here recursing = true; logFile = fileSystem->OpenFileWrite( fileName ); if ( !logFile ) { logFileFailed = true; FatalError( "failed to open log file '%s'\n", fileName ); } recursing = false; if ( com_logFile.GetInteger() > 1 ) { // force it to not buffer so we get valid // data even if we are crashing logFile->ForceFlush(); } time_t aclock; time( &aclock ); struct tm * newtime = localtime( &aclock ); Printf( "log file '%s' opened on %s\n", fileName, asctime( newtime ) ); } if ( logFile ) { logFile->Write( msg, strlen( msg ) ); logFile->Flush(); // ForceFlush doesn't help a whole lot } } // don't trigger any updates if we are in the process of doing a fatal error if ( com_errorEntered != ERP_FATAL ) { // update the console if we are in a long-running command, like dmap if ( com_refreshOnPrint ) { const bool captureToImage = false; UpdateScreen( captureToImage ); } } }
/* * Both client and server can use this, and it will output * to the apropriate place. */ void Com_VPrintf(int print_level, const char *fmt, va_list argptr) { if((print_level == PRINT_DEVELOPER) && (!developer || !developer->value)) { return; /* don't confuse non-developers with techie stuff... */ } else { int i; char msg[MAXPRINTMSG]; int msgLen = vsnprintf(msg, MAXPRINTMSG, fmt, argptr); if(msgLen >= MAXPRINTMSG) msgLen = MAXPRINTMSG-1; if (rd_target) { if ((msgLen + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_target, rd_buffer); *rd_buffer = 0; } strcat(rd_buffer, msg); return; } #ifndef DEDICATED_ONLY Con_Print(msg); #endif // remove unprintable characters for(i=0; i<msgLen; ++i) { char c = msg[i]; if(c < ' ' && (c < '\t' || c > '\r')) { switch(c) { // no idea if the following two are ever sent here, but in conchars.pcx they look like this // so do the replacements.. won't hurt I guess.. case 0x10: msg[i] = '['; break; case 0x11: msg[i] = ']'; break; // horizontal line chars case 0x1D: case 0x1F: msg[i] = '-'; break; case 0x1E: msg[i] = '='; break; default: // just replace all other unprintable chars with space, should be good enough msg[i] = ' '; } } } /* also echo to debugging console */ Sys_ConsoleOutput(msg); /* logfile */ if (logfile_active && logfile_active->value) { char name[MAX_OSPATH]; if (!logfile) { Com_sprintf(name, sizeof(name), "%s/qconsole.log", FS_Gamedir()); if (logfile_active->value > 2) { logfile = fopen(name, "a"); } else { logfile = fopen(name, "w"); } } if (logfile) { fprintf(logfile, "%s", msg); } if (logfile_active->value > 1) { fflush(logfile); /* force it to save every time */ } } } }
/* ============= Com_Printf Both client and server can use this, and it will output to the apropriate place. ============= */ void Com_Printf (const char *fmt, ...) { va_list argptr; char msg[MAXPRINTMSG], *s, *text; va_start (argptr,fmt); vsnprintf(msg, MAXPRINTMSG, fmt, argptr); va_end (argptr); if (rd_target) { if ((strlen (msg) + strlen(rd_buffer)) > (rd_buffersize - 1)) { rd_flush(rd_target, rd_buffer); *rd_buffer = 0; } strcat (rd_buffer, msg); return; } Con_Print (msg); text = msg; //Remove color triggers switch (msg[0]) { case 1: case 2: text++; default: for (s = text; *s; s++) *s &= 127; break; case COLOR_ONE: text++; if (Q_IsColorString(text)) text += 2; for (s = text; *s; s++) *s &= 127; break; case COLOR_ENABLE: text++; for (s = text; *s;) { if(Q_IsColorString(s)) { memmove( s, s + 2, MAXPRINTMSG - 2 - (s - msg)); continue; } *s++ &= 127; } break; } // also echo to debugging console Sys_ConsoleOutput (text); // logfile if (logfile_active->integer) { if (!logfile) { logfile = fopen(va("%s/qconsole.log", FS_Gamedir()), (logfile_active->integer > 2) ? "a" : "w"); } if (logfile) { fprintf(logfile, "%s", text); if (logfile_active->integer > 1) fflush(logfile); // force it to save every time } } }