diff -r c7b4237fff50 -r 03a67e41afbc core/Logger.cpp --- a/core/Logger.cpp Fri Mar 28 06:21:34 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,507 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include "sourcemod.h" -#include "sourcemm_api.h" -#include "sm_stringutil.h" -#include "Logger.h" -#include "systems/LibrarySys.h" -#include "TimerSys.h" -#include "sm_version.h" - -Logger g_Logger; - -/** - * :TODO: This should be creating the log folder if it doesn't exist - */ - -ConfigResult Logger::OnSourceModConfigChanged(const char *key, - const char *value, - ConfigSource source, - char *error, - size_t maxlength) -{ - if (strcasecmp(key, "Logging") == 0) - { - bool state; - - if (strcasecmp(value, "on") == 0) - { - state = true; - } else if (strcasecmp(value, "off") == 0) { - state = false; - } else { - UTIL_Format(error, maxlength, "Invalid value: must be \"on\" or \"off\""); - return ConfigResult_Reject; - } - - if (source == ConfigSource_Console) - { - state ? EnableLogging() : DisableLogging(); - } else { - m_InitialState = state; - } - - return ConfigResult_Accept; - } else if (strcasecmp(key, "LogMode") == 0) { - if (strcasecmp(value, "daily") == 0) - { - m_Mode = LoggingMode_Daily; - } else if (strcasecmp(value, "map") == 0) { - m_Mode = LoggingMode_PerMap; - } else if (strcasecmp(value, "game") == 0) { - m_Mode = LoggingMode_Game; - } else { - UTIL_Format(error, maxlength, "Invalid value: must be [daily|map|game]"); - return ConfigResult_Reject; - } - - return ConfigResult_Accept; - } - - return ConfigResult_Ignore; -} - -void Logger::OnSourceModStartup(bool late) -{ - InitLogger(m_Mode); -} - -void Logger::OnSourceModAllShutdown() -{ - CloseLogger(); -} - -void Logger::OnSourceModLevelChange(const char *mapName) -{ - MapChange(mapName); -} - -void Logger::_NewMapFile() -{ - if (!m_Active) - { - return; - } - - /* Append "Log file closed" to previous log file */ - _CloseFile(); - - char _filename[256]; - int i = 0; - - time_t t; - GetAdjustedTime(&t); - tm *curtime = localtime(&t); - - while (true) - { - g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i); - FILE *fp = fopen(_filename, "r"); - if (!fp) - { - break; - } - fclose(fp); - i++; - } - m_NrmFileName.assign(_filename); - - FILE *fp = fopen(m_NrmFileName.c_str(), "w"); - if (!fp) - { - char error[255]; - g_LibSys.GetPlatformError(error, sizeof(error)); - LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str()); - LogFatal("[SM] Platform returned error: \"%s\"", error); - LogFatal("[SM] Logging has been disabled."); - m_Active = false; - return; - } else { - char date[32]; - strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime); - fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SVN_FULL_VERSION); - fclose(fp); - } -} - -void Logger::_CloseFile() -{ - if (!m_Active) - { - return; - } - - FILE *fp = NULL; - if (!m_NrmFileName.empty()) - { - fp = fopen(m_NrmFileName.c_str(), "r+"); - if (fp) - { - fseek(fp, 0, SEEK_END); - LogMessage("Log file closed."); - fclose(fp); - } - m_NrmFileName.clear(); - } - - if (!m_ErrMapStart) - { - return; - } - fp = fopen(m_ErrFileName.c_str(), "r+"); - if (fp) - { - fseek(fp, 0, SEEK_END); - LogError("Error log file session closed."); - fclose(fp); - } - m_ErrFileName.clear(); -} - -void Logger::InitLogger(LoggingMode mode) -{ - m_Mode = mode; - m_Active = m_InitialState; - - time_t t; - GetAdjustedTime(&t); - tm *curtime = localtime(&t); - m_CurDay = curtime->tm_mday; - - char _filename[256]; - g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday); - m_ErrFileName.assign(_filename); - - switch (m_Mode) - { - case LoggingMode_PerMap: - { - if (!m_Active) - { - m_DelayedStart = true; - } - break; - } - case LoggingMode_Daily: - { - g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday); - m_NrmFileName.assign(_filename); - m_DailyPrintHdr = true; - break; - } - default: - { - /* do nothing... */ - break; - } - } -} - -void Logger::CloseLogger() -{ - _CloseFile(); -} - -void Logger::LogToOpenFile(FILE *fp, const char *msg, ...) -{ - if (!m_Active) - { - return; - } - - va_list ap; - va_start(ap, msg); - LogToOpenFileEx(fp, msg, ap); - va_end(ap); -} - -void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap) -{ - if (!m_Active) - { - return; - } - - char buffer[3072]; - UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap); - - char date[32]; - time_t t; - GetAdjustedTime(&t); - tm *curtime = localtime(&t); - strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime); - - fprintf(fp, "L %s: %s\n", date, buffer); - g_SMAPI->ConPrintf("L %s: %s\n", date, buffer); -} - -void Logger::LogMessage(const char *vafmt, ...) -{ - if (!m_Active) - { - return; - } - - if (m_Mode == LoggingMode_Game) - { - va_list ap; - va_start(ap, vafmt); - _PrintToGameLog(vafmt, ap); - va_end(ap); - return; - } - - if (m_DelayedStart) - { - m_DelayedStart = false; - _NewMapFile(); - } - - time_t t; - GetAdjustedTime(&t); - tm *curtime = localtime(&t); - - FILE *fp = NULL; - if (m_Mode == LoggingMode_PerMap) - { - fp = fopen(m_NrmFileName.c_str(), "a+"); - if (!fp) - { - _NewMapFile(); - fp = fopen(m_NrmFileName.c_str(), "a+"); - if (!fp) - { - goto print_error; - } - } - } else { - if (m_CurDay != curtime->tm_mday) - { - char _filename[256]; - g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday); - m_NrmFileName.assign(_filename); - m_CurDay = curtime->tm_mday; - m_DailyPrintHdr = true; - } - fp = fopen(m_NrmFileName.c_str(), "a+"); - } - - if (fp) - { - if (m_DailyPrintHdr) - { - char date[32]; - m_DailyPrintHdr = false; - strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime); - fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SVN_FULL_VERSION); - } - va_list ap; - va_start(ap, vafmt); - LogToOpenFileEx(fp, vafmt, ap); - va_end(ap); - fclose(fp); - } else { - goto print_error; - } - - return; -print_error: - char error[255]; - g_LibSys.GetPlatformError(error, sizeof(error)); - LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str()); - LogFatal("[SM] Platform returned error: \"%s\"", error); - LogFatal("[SM] Logging has been disabled."); - m_Active = false; -} - -void Logger::LogError(const char *vafmt, ...) -{ - if (!m_Active) - { - return; - } - - time_t t; - GetAdjustedTime(&t); - tm *curtime = localtime(&t); - - if (curtime->tm_mday != m_CurDay) - { - char _filename[256]; - g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday); - m_ErrFileName.assign(_filename); - m_CurDay = curtime->tm_mday; - m_ErrMapStart = false; - } - - FILE *fp = fopen(m_ErrFileName.c_str(), "a+"); - if (fp) - { - if (!m_ErrMapStart) - { - char date[32]; - strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime); - fprintf(fp, "L %s: SourceMod error session started\n", date); - fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday); - m_ErrMapStart = true; - } - va_list ap; - va_start(ap, vafmt); - LogToOpenFileEx(fp, vafmt, ap); - va_end(ap); - fclose(fp); - } - else - { - char error[255]; - g_LibSys.GetPlatformError(error, sizeof(error)); - LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str()); - LogFatal("[SM] Platform returned error: \"%s\"", error); - LogFatal("[SM] Logging has been disabled."); - m_Active = false; - return; - } -} - -void Logger::MapChange(const char *mapname) -{ - m_CurMapName.assign(mapname); - - switch (m_Mode) - { - case LoggingMode_Daily: - { - LogMessage("-------- Mapchange to %s --------", mapname); - break; - } - case LoggingMode_PerMap: - { - _NewMapFile(); - break; - } - default: - { - /* Do nothing... */ - break; - } - } - - if (m_ErrMapStart) - { - LogError("Error log file session closed."); - } - m_ErrMapStart = false; -} - -void Logger::_PrintToGameLog(const char *fmt, va_list ap) -{ - char msg[3072]; - size_t len; - - len = vsnprintf(msg, sizeof(msg)-2, fmt, ap); - len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len; - - msg[len++] = '\n'; - msg[len] = '\0'; - - engine->LogPrint(msg); -} - -const char *Logger::GetLogFileName(LogType type) const -{ - switch (type) - { - case LogType_Normal: - { - return m_NrmFileName.c_str(); - } - case LogType_Error: - { - return m_ErrFileName.c_str(); - } - default: - { - return ""; - } - } -} - -LoggingMode Logger::GetLoggingMode() const -{ - return m_Mode; -} - -void Logger::EnableLogging() -{ - if (m_Active) - { - return; - } - m_Active = true; - LogMessage("[SM] Logging enabled manually by user."); -} - -void Logger::DisableLogging() -{ - if (!m_Active) - { - return; - } - LogMessage("[SM] Logging disabled manually by user."); - m_Active = false; -} - -void Logger::LogFatal(const char *msg, ...) -{ - /* :TODO: make this print all pretty-like - * In fact, the pretty log printing function should be abstracted. - * It's already implemented twice which is bad. - */ - - va_list ap; - char path[PLATFORM_MAX_PATH]; - - g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log"); - - FILE *fp = fopen(path, "at"); - if (fp) - { - m_Active = true; - va_start(ap, msg); - LogToOpenFileEx(fp, msg, ap); - va_end(ap); - m_Active = false; - fclose(fp); - } -} -