diff --git a/core/AMBuilder b/core/AMBuilder index 7eb37f84b..d9f62d83c 100644 --- a/core/AMBuilder +++ b/core/AMBuilder @@ -31,7 +31,6 @@ project.sources += [ 'smn_console.cpp', 'UserMessages.cpp', 'MenuManager.cpp', - 'smn_core.cpp', 'smn_hudtext.cpp', 'smn_usermsgs.cpp', 'MenuStyle_Base.cpp', diff --git a/core/ConsoleDetours.cpp b/core/ConsoleDetours.cpp index 6c406666a..fba527217 100644 --- a/core/ConsoleDetours.cpp +++ b/core/ConsoleDetours.cpp @@ -195,7 +195,7 @@ class GenericCommandHooker : public IConCommandLinkListener size_t index; if (!FindVtable(vtable, index)) { - g_Logger.LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName()); + logger->LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName()); return; } @@ -219,7 +219,7 @@ public: if (dispatch.thisptroffs < 0) { - g_Logger.LogError("Command filter could not determine ConCommand layout"); + logger->LogError("Command filter could not determine ConCommand layout"); return false; } @@ -228,7 +228,7 @@ public: if (!vtables.size()) { - g_Logger.LogError("Command filter could not find any cvars!"); + logger->LogError("Command filter could not find any cvars!"); return false; } diff --git a/core/CoreConfig.cpp b/core/CoreConfig.cpp index 42c30ab15..1cce9f4d1 100644 --- a/core/CoreConfig.cpp +++ b/core/CoreConfig.cpp @@ -262,7 +262,7 @@ void CoreConfig::Initialize() { /* :TODO: This won't actually log or print anything :( - So fix that somehow */ const char *error = textparsers->GetSMCErrorString(err); - g_Logger.LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : ""); + logger->LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : ""); } } @@ -274,7 +274,7 @@ SMCResult CoreConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key, if (err == ConfigResult_Reject) { /* This is a fatal error */ - g_Logger.LogFatal("Config error (key: %s) (value: %s) %s", key, value, error); + logger->LogFatal("Config error (key: %s) (value: %s) %s", key, value, error); } return SMCResult_Continue; @@ -469,7 +469,7 @@ bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create) } else { - g_Logger.LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pl->GetFilename()); + logger->LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pl->GetFilename()); return can_create; } } diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index da8935fe1..9cc3bc51f 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -168,7 +168,7 @@ void CHalfLife2::InitLogicalEntData() if (!addr) { // Key exists so notify if lookup fails, but try other method. - g_Logger.LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown"); + logger->LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown"); } else { @@ -186,7 +186,7 @@ void CHalfLife2::InitLogicalEntData() int offset; if (!g_pGameConf->GetOffset("gEntList", &offset)) { - g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only"); + logger->LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only"); return; } @@ -198,7 +198,7 @@ void CHalfLife2::InitLogicalEntData() // If we have g_EntList from either of the above methods, make sure we can get the offset from it to EntInfo as well if (g_EntList && !g_pGameConf->GetOffset("EntInfo", &entInfoOffset)) { - g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only"); + logger->LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only"); g_EntList = NULL; return; } @@ -211,7 +211,7 @@ void CHalfLife2::InitLogicalEntData() if (!g_EntList && !g_pEntInfoList) { - g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only"); + logger->LogError("Failed lookup of gEntList - Reverting to networkable entities only"); return; } } @@ -225,7 +225,7 @@ void CHalfLife2::InitCommandLine() ke::AutoPtr lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error))); if (lib == NULL) { - g_Logger.LogError("Could not load %s: %s", TIER0_NAME, error); + logger->LogError("Could not load %s: %s", TIER0_NAME, error); return; } @@ -242,7 +242,7 @@ void CHalfLife2::InitCommandLine() ke::AutoPtr lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error))); if (lib == NULL) { - g_Logger.LogError("Could not load %s: %s", VSTDLIB_NAME, error); + logger->LogError("Could not load %s: %s", VSTDLIB_NAME, error); return; } @@ -251,7 +251,7 @@ void CHalfLife2::InitCommandLine() if (m_pGetCommandLine == NULL) { - g_Logger.LogError("Could not locate any command line functionality"); + logger->LogError("Could not locate any command line functionality"); } } diff --git a/core/Logger.cpp b/core/Logger.cpp index 20668fc4d..9dd402d38 100644 --- a/core/Logger.cpp +++ b/core/Logger.cpp @@ -39,61 +39,12 @@ #include "logic_bridge.h" #include -Logger g_Logger; +bool g_in_game_log_hook = false; + +static LoggerCore g_LoggerCore; SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *); -/** - * :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; -} - static void HookLogPrint(const char *message) { g_in_game_log_hook = true; @@ -104,477 +55,16 @@ static void HookLogPrint(const char *message) RETURN_META(MRES_SUPERCEDE); } -void Logger::OnSourceModStartup(bool late) +void LoggerCore::OnSourceModStartup(bool late) { - InitLogger(m_Mode); - SH_ADD_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false); } -void Logger::OnSourceModAllShutdown() +void LoggerCore::OnSourceModAllShutdown() { - CloseLogger(); SH_REMOVE_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false); } -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, SOURCEMOD_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_NrmCurDay = curtime->tm_mday; - m_ErrCurDay = 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::LogToFileOnly(FILE *fp, const char *msg, ...) -{ - if (!m_Active) - { - return; - } - - va_list ap; - va_start(ap, msg); - LogToFileOnlyEx(fp, msg, ap); - va_end(ap); -} - -void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap) -{ - if (!m_Active) - { - return; - } - - static ConVar *sv_logecho = icvar->FindVar("sv_logecho"); - - 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); - - if (!sv_logecho || sv_logecho->GetBool()) - { - g_SMAPI->ConPrintf("L %s: %s\n", date, buffer); - } -} - -void Logger::LogToFileOnlyEx(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); - fflush(fp); -} - -void Logger::LogMessage(const char *vafmt, ...) -{ - va_list ap; - va_start(ap, vafmt); - LogMessageEx(vafmt, ap); - va_end(ap); -} - -void Logger::LogMessageEx(const char *vafmt, va_list ap) -{ - if (!m_Active) - { - return; - } - - if (m_Mode == LoggingMode_Game) - { - _PrintToGameLog(vafmt, 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_NrmCurDay != 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_NrmCurDay = 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, SOURCEMOD_VERSION); - } - LogToOpenFileEx(fp, vafmt, 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, ...) -{ - va_list ap; - va_start(ap, vafmt); - LogErrorEx(vafmt, ap); - va_end(ap); -} - -void Logger::LogErrorEx(const char *vafmt, va_list ap) -{ - if (!m_Active) - { - return; - } - - time_t t; - GetAdjustedTime(&t); - tm *curtime = localtime(&t); - - if (curtime->tm_mday != m_ErrCurDay) - { - 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_ErrCurDay = 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; - } - LogToOpenFileEx(fp, vafmt, 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_LogPrintWrapper(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, ...) -{ - va_list ap; - va_start(ap, msg); - LogFatalEx(msg, ap); - va_end(ap); -} - -void Logger::LogFatalEx(const char *msg, va_list ap) -{ - /* :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. - */ - - 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; - LogToOpenFileEx(fp, msg, ap); - m_Active = false; - fclose(fp); - } -} - -bool g_in_game_log_hook = false; - void Engine_LogPrintWrapper(const char *msg) { if (g_in_game_log_hook) diff --git a/core/Logger.h b/core/Logger.h index 834492e99..a12dc9ef6 100644 --- a/core/Logger.h +++ b/core/Logger.h @@ -38,76 +38,13 @@ using namespace SourceHook; -enum LogType +class LoggerCore : public SMGlobalClass { - LogType_Normal, - LogType_Error -}; - -enum LoggingMode -{ - LoggingMode_Daily, - LoggingMode_PerMap, - LoggingMode_Game -}; - -class Logger : public SMGlobalClass -{ -public: - Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false), - m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false), - m_InitialState(true) - { - } public: //SMGlobalClass - ConfigResult OnSourceModConfigChanged(const char *key, - const char *value, - ConfigSource source, - char *error, - size_t maxlength); void OnSourceModStartup(bool late); void OnSourceModAllShutdown(); - void OnSourceModLevelChange(const char *mapName); -public: - void InitLogger(LoggingMode mode); - void CloseLogger(); - void EnableLogging(); - void DisableLogging(); - void LogMessage(const char *msg, ...); - void LogMessageEx(const char *msg, va_list ap); - void LogError(const char *msg, ...); - void LogErrorEx(const char *msg, va_list ap); - void LogFatal(const char *msg, ...); - void LogFatalEx(const char *msg, va_list ap); - void LogToOpenFile(FILE *fp, const char *msg, ...); - void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap); - /* This version does not print to console, and is thus thread-safe */ - void LogToFileOnly(FILE *fp, const char *msg, ...); - void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap); - void MapChange(const char *mapname); - const char *GetLogFileName(LogType type) const; - LoggingMode GetLoggingMode() const; -private: - void _CloseFile(); - void _NewMapFile(); - void _PrintToGameLog(const char *fmt, va_list ap); -private: - String m_NrmFileName; - String m_ErrFileName; - String m_CurMapName; - LoggingMode m_Mode; - int m_NrmCurDay; - int m_ErrCurDay; - bool m_ErrMapStart; - bool m_Active; - bool m_DelayedStart; - bool m_DailyPrintHdr; - bool m_InitialState; }; void Engine_LogPrintWrapper(const char *msg); -extern bool g_in_game_log_hook; -extern Logger g_Logger; - #endif // _INCLUDE_SOURCEMOD_CLOGGER_H_ diff --git a/core/NextMap.cpp b/core/NextMap.cpp index 922430087..126f8f666 100644 --- a/core/NextMap.cpp +++ b/core/NextMap.cpp @@ -36,6 +36,7 @@ #include "sm_stringutil.h" #include "sourcehook.h" #include "sm_srvcmds.h" +#include "logic_bridge.h" NextMapManager g_NextMap; @@ -130,7 +131,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const { if (g_forcedChange) { - g_Logger.LogMessage("[SM] Changed map to \"%s\"", map); + logger->LogMessage("[SM] Changed map to \"%s\"", map); RETURN_META(MRES_IGNORED); } @@ -141,7 +142,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const RETURN_META(MRES_IGNORED); } - g_Logger.LogMessage("[SM] Changed map to \"%s\"", newmap); + logger->LogMessage("[SM] Changed map to \"%s\"", newmap); UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap); UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change"); diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index bc2c10381..587db7e53 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -1238,7 +1238,7 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity) if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0') { unsigned int accountId = pPlayer->GetSteamAccountID(); - g_Logger.LogMessage("\"%s<%d><>\" has bad networkid (id \"%s\") (ip \"%s\")", + logger->LogMessage("\"%s<%d><>\" has bad networkid (id \"%s\") (ip \"%s\")", new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress()); pPlayer->Kick("NetworkID spoofing detected."); diff --git a/core/logic/AMBuilder b/core/logic/AMBuilder index b38a09658..17a8eb3a1 100644 --- a/core/logic/AMBuilder +++ b/core/logic/AMBuilder @@ -66,6 +66,8 @@ binary.sources += [ 'sm_trie.cpp', 'smn_console.cpp', 'ProfileTools.cpp', + 'Logger.cpp', + 'smn_core.cpp', ] if builder.target_platform == 'windows': binary.sources += ['thread/WinThreads.cpp'] diff --git a/core/logic/AdminCache.cpp b/core/logic/AdminCache.cpp index dc1094a58..a10ae6d12 100644 --- a/core/logic/AdminCache.cpp +++ b/core/logic/AdminCache.cpp @@ -198,11 +198,11 @@ private: if (!m_bFileNameLogged) { - smcore.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File); + logger->LogError("[SM] Parse error(s) detected in file \"%s\":", m_File); m_bFileNameLogged = true; } - smcore.LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer); + logger->LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer); } private: bool m_bFileNameLogged; diff --git a/core/logic/Database.cpp b/core/logic/Database.cpp index e691bf288..99c13f108 100644 --- a/core/logic/Database.cpp +++ b/core/logic/Database.cpp @@ -89,11 +89,11 @@ void DBManager::OnSourceModLevelChange(const char *mapName) ke::AutoLock lock(&m_ConfigLock); if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay) { - smcore.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename); + logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename); if (err != SMCError_Custom) { const char *txt = textparsers->GetSMCErrorString(err); - smcore.LogError("[SM] Line %d: %s", states.line, txt); + logger->LogError("[SM] Line %d: %s", states.line, txt); } } } @@ -541,7 +541,7 @@ bool DBManager::AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio) { if (!s_OneTimeThreaderErrorMsg) { - smcore.LogError("[SM] Unable to create db threader (error unknown)"); + logger->LogError("[SM] Unable to create db threader (error unknown)"); s_OneTimeThreaderErrorMsg = true; } m_Worker = NULL; diff --git a/core/logic/ExtensionSys.cpp b/core/logic/ExtensionSys.cpp index 87f3c5e6c..f1400864f 100644 --- a/core/logic/ExtensionSys.cpp +++ b/core/logic/ExtensionSys.cpp @@ -606,7 +606,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn { if (bErrorOnMissing || libsys->IsPathFile(p->GetPath())) { - smcore.LogError("[SM] Unable to load extension \"%s\": %s", path, error); + logger->LogError("[SM] Unable to load extension \"%s\": %s", path, error); } p->SetError(error); diff --git a/core/logic/GameConfigs.cpp b/core/logic/GameConfigs.cpp index f13e9d30b..120678532 100644 --- a/core/logic/GameConfigs.cpp +++ b/core/logic/GameConfigs.cpp @@ -301,8 +301,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n if (error[0] != '\0') { m_IgnoreLevel = 1; - smcore.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile); - smcore.LogError("[SM] %s", error); + logger->LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile); + logger->LogError("[SM] %s", error); } else { m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY; } @@ -335,8 +335,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n { if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0) { - smcore.LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile); - smcore.LogError("[SM] Unrecognized platform \"%s\"", name); + logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile); + logger->LogError("[SM] Unrecognized platform \"%s\"", name); } m_IgnoreLevel = 1; } @@ -435,7 +435,7 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key } else { - smcore.LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile); + logger->LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile); } } else if (strcmp(key, "signature") == 0) { strncopy(m_AddressSignature, value, sizeof(m_AddressSignature)); @@ -503,7 +503,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0) && (!m_Offsets.retrieve(m_offset))) { - smcore.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")", + logger->LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")", m_Class, m_Prop, m_CurFile, @@ -556,7 +556,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) void *final_addr = NULL; if (addrInBase == NULL) { - smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")", + logger->LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")", s_TempSig.library, m_CurFile); } @@ -570,7 +570,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) if (VirtualQuery(addrInBase, &mem, sizeof(mem))) final_addr = g_MemUtils.ResolveSymbol(mem.AllocationBase, &s_TempSig.sig[1]); else - smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File); + logger->LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File); #elif defined PLATFORM_POSIX Dl_info info; /* GNU only: returns 0 on error, inconsistent! >:[ */ @@ -585,12 +585,12 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) final_addr = dlsym(handle, &s_TempSig.sig[1]); dlclose(handle); } else { - smcore.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")", + logger->LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")", s_TempSig.library, m_File); } } else { - smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", + logger->LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File); } @@ -827,8 +827,8 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) { const char *msg = textparsers->GetSMCErrorString(err); - smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path); - smcore.LogError("[SM] Error %d on line %d, col %d: %s", + logger->LogError("[SM] Error parsing master gameconf file \"%s\":", path); + logger->LogError("[SM] Error %d on line %d, col %d: %s", err, state.line, state.col, @@ -915,8 +915,8 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength) { const char *msg = textparsers->GetSMCErrorString(err); - smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile); - smcore.LogError("[SM] Error %d on line %d, col %d: %s", + logger->LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile); + logger->LogError("[SM] Error %d on line %d, col %d: %s", err, state.line, state.col, diff --git a/core/logic/HandleSys.cpp b/core/logic/HandleSys.cpp index 2c43b9ccb..4ec906270 100644 --- a/core/logic/HandleSys.cpp +++ b/core/logic/HandleSys.cpp @@ -957,8 +957,8 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa } #define HANDLE_LOG_VERY_BAD(message, ...) \ - smcore.LogFatal(message, ##__VA_ARGS__); \ - smcore.LogError(message, ##__VA_ARGS__); + logger->LogFatal(message, ##__VA_ARGS__); \ + logger->LogError(message, ##__VA_ARGS__); bool HandleSystem::TryAndFreeSomeHandles() { diff --git a/core/logic/Translator.cpp b/core/logic/Translator.cpp index c29109214..a1fdaf42d 100644 --- a/core/logic/Translator.cpp +++ b/core/logic/Translator.cpp @@ -96,11 +96,11 @@ void CPhraseFile::ParseWarning(const char *message, ...) if (!m_FileLogged) { - smcore.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str()); + logger->LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str()); m_FileLogged = true; } - smcore.LogError("[SM] %s", buffer); + logger->LogError("[SM] %s", buffer); } void CPhraseFile::ReparseFile() @@ -142,8 +142,8 @@ void CPhraseFile::ReparseFile() msg = m_ParseError.c_str(); } - smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str()); - smcore.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); + logger->LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str()); + logger->LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); } const char *code; @@ -175,10 +175,10 @@ void CPhraseFile::ReparseFile() msg = m_ParseError.c_str(); } - smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"", + logger->LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"", code, m_File.c_str()); - smcore.LogError("[SM] Error (line %d, column %d): %s", + logger->LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); @@ -831,13 +831,13 @@ void Translator::RebuildLanguageDatabase() str_err = m_CustomError.c_str(); } - smcore.LogError("[SM] Failed to parse language header file: \"%s\"", path); - smcore.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err); + logger->LogError("[SM] Failed to parse language header file: \"%s\"", path); + logger->LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err); } if (!m_LCodeLookup.retrieve(m_InitialLang, &m_ServerLang)) { - smcore.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang); + logger->LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang); smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang)); m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH; @@ -845,7 +845,7 @@ void Translator::RebuildLanguageDatabase() if (!m_Languages.size()) { - smcore.LogError("[SM] Fatal error, no languages found! Translation will not work."); + logger->LogError("[SM] Fatal error, no languages found! Translation will not work."); } for (size_t i=0; iLogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name); } return SMCResult_Continue; @@ -1025,11 +1025,11 @@ bool CoreTranslate(char *buffer, size_t maxlength, const char *format, unsigned { if (fail_phrase != NULL) { - smcore.LogError("[SM] Could not find core phrase: %s", fail_phrase); + logger->LogError("[SM] Could not find core phrase: %s", fail_phrase); } else { - smcore.LogError("[SM] Unknown fatal error while translating a core phrase."); + logger->LogError("[SM] Unknown fatal error while translating a core phrase."); } return false; diff --git a/core/logic/common_logic.cpp b/core/logic/common_logic.cpp index 7c988b5f6..74681a11d 100644 --- a/core/logic/common_logic.cpp +++ b/core/logic/common_logic.cpp @@ -50,6 +50,7 @@ #include "ForwardSys.h" #include "AdminCache.h" #include "ProfileTools.h" +#include "Logger.h" sm_core_t smcore; IHandleSys *handlesys = &g_HandleSys; @@ -72,6 +73,7 @@ ISourcePawnEngine *g_pSourcePawn; ISourcePawnEngine2 *g_pSourcePawn2; CNativeOwner g_CoreNatives; IScriptManager *scripts = &g_PluginSys; +ILogger *logger = &g_Logger; static void AddCorePhraseFile(const char *filename) { @@ -140,6 +142,7 @@ static sm_logic_t logic = &g_Forwards, &g_Admins, NULL, + &g_Logger, -1.0f }; diff --git a/core/logic/common_logic.h b/core/logic/common_logic.h index f008d4e38..45f9fc643 100644 --- a/core/logic/common_logic.h +++ b/core/logic/common_logic.h @@ -53,6 +53,8 @@ extern IPlayerManager *playerhelpers; extern IAdminSystem *adminsys; extern IGameHelpers *gamehelpers; extern IScriptManager *scripts; +extern IExtensionSys *extsys; +extern ILogger *logger; #endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */ diff --git a/core/logic/intercom.h b/core/logic/intercom.h index 5d86853d4..6837ba96a 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -52,7 +52,7 @@ using namespace SourceHook; * Add 1 to the RHS of this expression to bump the intercom file * This is to prevent mismatching core/logic binaries */ -#define SM_LOGIC_MAGIC (0x0F47C0DE - 28) +#define SM_LOGIC_MAGIC (0x0F47C0DE - 29) #if defined SM_LOGIC class IVEngineServer @@ -213,6 +213,14 @@ public: virtual void FreeExtensionList(const CVector *list) = 0; }; +class ILogger +{ +public: + virtual void LogMessage(const char *msg, ...) = 0; + virtual void LogError(const char *msg, ...) = 0; + virtual void LogFatal(const char *msg, ...) = 0; +}; + class AutoPluginList { public: @@ -273,13 +281,10 @@ struct sm_core_t ConVar * (*FindConVar)(const char*); unsigned int (*strncopy)(char*, const char*, size_t); char * (*TrimWhitespace)(char *, size_t &); - void (*LogError)(const char*, ...); - void (*LogFatal)(const char*, ...); - void (*Log)(const char*, ...); - void (*LogToFile)(FILE *fp, const char*, ...); void (*LogToGame)(const char *message); void (*ConPrint)(const char *message); const char * (*GetCvarString)(ConVar*); + bool (*GetCvarBool)(ConVar*); size_t (*Format)(char*, size_t, const char*, ...); size_t (*FormatArgs)(char*, size_t, const char*,va_list ap); bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **, @@ -325,7 +330,7 @@ struct sm_logic_t char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool); size_t (*DecodeHexString)(unsigned char *, size_t, const char *); IGameConfig * (*GetCoreGameConfig)(); - bool (*OnLogPrint)(const char *msg); // true to supercede + bool (*OnLogPrint)(const char *msg); // true to supersede IDebugListener *debugger; void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...); void (*AddNatives)(sp_nativeinfo_t *natives); @@ -339,6 +344,7 @@ struct sm_logic_t IForwardManager *forwardsys; IAdminSystem *adminsys; IdentityToken_t *core_ident; + ILogger *logger; float sentinel; }; diff --git a/core/logic/smn_filesystem.cpp b/core/logic/smn_filesystem.cpp index 26575acf9..ed83b1cb8 100644 --- a/core/logic/smn_filesystem.cpp +++ b/core/logic/smn_filesystem.cpp @@ -38,6 +38,7 @@ #include #include #include "common_logic.h" +#include "Logger.h" HandleType_t g_FileType; HandleType_t g_DirType; @@ -598,7 +599,7 @@ static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params) } IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext()); - smcore.Log("[%s] %s", pPlugin->GetFilename(), buffer); + g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer); return 1; } @@ -616,7 +617,7 @@ static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params) } IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext()); - smcore.LogError("[%s] %s", pPlugin->GetFilename(), buffer); + g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer); return 1; } @@ -669,7 +670,7 @@ static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params) } IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext()); - smcore.LogToFile(pFile, "[%s] %s", pPlugin->GetFilename(), buffer); + g_Logger.LogToOpenFile(pFile, "[%s] %s", pPlugin->GetFilename(), buffer); return 1; } @@ -699,7 +700,7 @@ static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params) return 0; } - smcore.LogToFile(pFile, "%s", buffer); + g_Logger.LogToOpenFile(pFile, "%s", buffer); return 1; } diff --git a/core/logic/smn_maplists.cpp b/core/logic/smn_maplists.cpp index 00a19a95a..9faba5d86 100644 --- a/core/logic/smn_maplists.cpp +++ b/core/logic/smn_maplists.cpp @@ -202,8 +202,8 @@ public: { errmsg = "Unknown error"; } - smcore.LogError("[SM] Could not parse file \"%s\"", m_ConfigFile); - smcore.LogError("[SM] Error on line %d (col %d): %s", states.line, states.col, errmsg); + logger->LogError("[SM] Could not parse file \"%s\"", m_ConfigFile); + logger->LogError("[SM] Error on line %d (col %d): %s", states.line, states.col, errmsg); } else { diff --git a/core/logic/smn_players.cpp b/core/logic/smn_players.cpp index 55d4fcbfd..47288f0a3 100644 --- a/core/logic/smn_players.cpp +++ b/core/logic/smn_players.cpp @@ -120,7 +120,7 @@ public: //ICommandTargetProcessor Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL); AutoHandleCloner ahc(hndl, sec); if (ahc.getClone() == BAD_HANDLE) { - smcore.LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__); + logger->LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__); delete array; return false; } diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index 057f660c4..13fba9fe1 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -86,6 +86,7 @@ IExtensionSys *extsys; IHandleSys *handlesys; IForwardManager *forwardsys; IAdminSystem *adminsys; +ILogger *logger; class VEngineServer_Logic : public IVEngineServer_Logic { @@ -251,46 +252,13 @@ static VPlayerInfo_Logic logic_playerinfo; static ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY, "Activity display setting (see sourcemod.cfg)"); static ConVar sm_immunity_mode("sm_immunity_mode", "1", FCVAR_SPONLY, "Mode for deciding immunity protection"); +static ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules"); static ConVar *find_convar(const char *name) { return icvar->FindVar(name); } -static void log_error(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - g_Logger.LogErrorEx(fmt, ap); - va_end(ap); -} - -static void log_fatal(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - g_Logger.LogFatalEx(fmt, ap); - va_end(ap); -} - -static void log_message(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - g_Logger.LogMessageEx(fmt, ap); - va_end(ap); -} - -static void log_to_file(FILE *fp, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - g_Logger.LogToOpenFileEx(fp, fmt, ap); - va_end(ap); -} - static void log_to_game(const char *message) { Engine_LogPrintWrapper(message); @@ -306,6 +274,11 @@ static const char *get_cvar_string(ConVar* cvar) return cvar->GetString(); } +static bool get_cvar_bool(ConVar* cvar) +{ + return cvar->GetBool(); +} + static bool get_game_name(char *buffer, size_t maxlength) { KeyValues *pGameInfo = new KeyValues("GameInfo"); @@ -561,13 +534,10 @@ static sm_core_t core_bridge = find_convar, strncopy, UTIL_TrimWhitespace, - log_error, - log_fatal, - log_message, - log_to_file, log_to_game, conprint, get_cvar_string, + get_cvar_bool, UTIL_Format, UTIL_FormatArgs, gnprintf, @@ -636,6 +606,7 @@ void InitLogicBridge() handlesys = logicore.handlesys; forwardsys = logicore.forwardsys; adminsys = logicore.adminsys; + logger = logicore.logger; } bool StartLogicBridge(char *error, size_t maxlength) diff --git a/core/logic_bridge.h b/core/logic_bridge.h index 76372a7c6..34f6de1a4 100644 --- a/core/logic_bridge.h +++ b/core/logic_bridge.h @@ -48,5 +48,6 @@ extern IExtensionSys *extsys; extern IHandleSys *handlesys; extern IForwardManager *forwardsys; extern IAdminSystem *adminsys; +extern ILogger *logger; #endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */ diff --git a/core/smn_console.cpp b/core/smn_console.cpp index d92fc4923..eda2529b1 100644 --- a/core/smn_console.cpp +++ b/core/smn_console.cpp @@ -1216,7 +1216,7 @@ static cell_t AddCommandListener(IPluginContext *pContext, const cell_t *params) if (strcasecmp(name, "sm") == 0) { - g_Logger.LogError("Request to register \"sm\" command denied."); + logger->LogError("Request to register \"sm\" command denied."); return 0; } diff --git a/core/smn_core.cpp b/core/smn_core.cpp deleted file mode 100644 index 4d301db42..000000000 --- a/core/smn_core.cpp +++ /dev/null @@ -1,774 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 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 -#include -#include "sm_stringutil.h" -#include "sm_globals.h" -#include "sourcemod.h" -#include "LibrarySys.h" -#include "TimerSys.h" -#include "Logger.h" -#include -#include "logic_bridge.h" - -#if defined PLATFORM_WINDOWS -#include -#elif defined PLATFORM_POSIX -#include -#include -#include -#endif - -HandleType_t g_PlIter; -ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules"); -IForward *g_OnLogAction = NULL; - -class CoreNativeHelpers : - public SMGlobalClass, - public IHandleTypeDispatch -{ -public: - void OnSourceModAllInitialized() - { - HandleAccess hacc; - handlesys->InitAccessDefaults(NULL, &hacc); - hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER; - - g_PlIter = handlesys->CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL); - - g_OnLogAction = forwardsys->CreateForward("OnLogAction", - ET_Hook, - 5, - NULL, - Param_Cell, - Param_Cell, - Param_Cell, - Param_Cell, - Param_String); - } - void OnHandleDestroy(HandleType_t type, void *object) - { - IPluginIterator *iter = (IPluginIterator *)object; - iter->Release(); - } - void OnSourceModShutdown() - { - forwardsys->ReleaseForward(g_OnLogAction); - handlesys->RemoveType(g_PlIter, g_pCoreIdent); - } -} g_CoreNativeHelpers; - -void LogAction(Handle_t hndl, int type, int client, int target, const char *message) -{ - if (g_OnLogAction->GetFunctionCount()) - { - cell_t result = 0; - g_OnLogAction->PushCell(hndl); - g_OnLogAction->PushCell(type); - g_OnLogAction->PushCell(client); - g_OnLogAction->PushCell(target); - g_OnLogAction->PushString(message); - g_OnLogAction->Execute(&result); - - if (result >= (ResultType)Pl_Handled) - { - return; - } - } - - const char *logtag = "SM"; - if (type == 2) - { - HandleError err; - IPlugin *pPlugin = scripts->FindPluginByHandle(hndl, &err); - if (pPlugin) - { - logtag = pPlugin->GetFilename(); - } - } - - g_Logger.LogMessage("[%s] %s", logtag, message); -} - -static cell_t ThrowError(IPluginContext *pContext, const cell_t *params) -{ - char buffer[512]; - - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - - if (pContext->GetLastNativeError() == SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer); - } - - return 0; -} - -static cell_t GetTime(IPluginContext *pContext, const cell_t *params) -{ - time_t t = GetAdjustedTime(); - cell_t *addr; - pContext->LocalToPhysAddr(params[1], &addr); - - *(time_t *)addr = t; - - return static_cast(t); -} - -#if defined SUBPLATFORM_SECURECRT -void _ignore_invalid_parameter( - const wchar_t * expression, - const wchar_t * function, - const wchar_t * file, - unsigned int line, - uintptr_t pReserved - ) -{ - /* Wow we don't care, thanks Microsoft. */ -} -#endif - -static cell_t FormatTime(IPluginContext *pContext, const cell_t *params) -{ - char *format, *buffer; - pContext->LocalToString(params[1], &buffer); - pContext->LocalToStringNULL(params[3], &format); - - if (format == NULL) - { - format = const_cast(sm_datetime_format.GetString()); - } - -#if defined SUBPLATFORM_SECURECRT - _invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter); -#endif - - time_t t = (params[4] == -1) ? GetAdjustedTime() : (time_t)params[4]; - size_t written = strftime(buffer, params[2], format, localtime(&t)); - -#if defined SUBPLATFORM_SECURECRT - _set_invalid_parameter_handler(handler); -#endif - - if (params[2] && format[0] != '\0' && !written) - { - pContext->ThrowNativeError("Invalid time format or buffer too small"); - return 0; - } - - return 1; -} - -static cell_t GetPluginIterator(IPluginContext *pContext, const cell_t *params) -{ - IPluginIterator *iter = scripts->GetPluginIterator(); - - Handle_t hndl = handlesys->CreateHandle(g_PlIter, iter, pContext->GetIdentity(), g_pCoreIdent, NULL); - - if (hndl == BAD_HANDLE) - { - iter->Release(); - } - - return hndl; -} - -static cell_t MorePlugins(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - IPluginIterator *pIter; - - HandleSecurity sec; - sec.pIdentity = g_pCoreIdent; - sec.pOwner = pContext->GetIdentity(); - - if ((err=handlesys->ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None) - { - return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err); - } - - return pIter->MorePlugins() ? 1 : 0; -} - -static cell_t ReadPlugin(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = (Handle_t)params[1]; - HandleError err; - IPluginIterator *pIter; - - HandleSecurity sec; - sec.pIdentity = g_pCoreIdent; - sec.pOwner = pContext->GetIdentity(); - - if ((err=handlesys->ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None) - { - return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err); - } - - IPlugin *pPlugin = pIter->GetPlugin(); - if (!pPlugin) - { - return BAD_HANDLE; - } - - pIter->NextPlugin(); - - return pPlugin->GetMyHandle(); -} - -IPlugin *GetPluginFromHandle(IPluginContext *pContext, Handle_t hndl) -{ - if (hndl == BAD_HANDLE) - { - return scripts->FindPluginByContext(pContext->GetContext()); - } else { - HandleError err; - IPlugin *pPlugin = scripts->FindPluginByHandle(hndl, &err); - if (!pPlugin) - { - pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err); - } - return pPlugin; - } -} - -static cell_t GetPluginStatus(IPluginContext *pContext, const cell_t *params) -{ - IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]); - if (!pPlugin) - { - return 0; - } - - return pPlugin->GetStatus(); -} - -static cell_t GetPluginFilename(IPluginContext *pContext, const cell_t *params) -{ - IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]); - if (!pPlugin) - { - return 0; - } - - pContext->StringToLocalUTF8(params[2], params[3], pPlugin->GetFilename(), NULL); - - return 1; -} - -static cell_t IsPluginDebugging(IPluginContext *pContext, const cell_t *params) -{ - IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]); - if (!pPlugin) - { - return 0; - } - - return pPlugin->IsDebugging() ? 1 : 0; -} - -/* Local to plugins only */ -enum PluginInfo -{ - PlInfo_Name, /**< Plugin name */ - PlInfo_Author, /**< Plugin author */ - PlInfo_Description, /**< Plugin description */ - PlInfo_Version, /**< Plugin verison */ - PlInfo_URL, /**< Plugin URL */ -}; - -static cell_t GetPluginInfo(IPluginContext *pContext, const cell_t *params) -{ - IPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]); - if (!pPlugin) - { - return 0; - } - - const sm_plugininfo_t *info = pPlugin->GetPublicInfo(); - - if (!info) - { - return 0; - } - - const char *str = NULL; - - switch ((PluginInfo)params[2]) - { - case PlInfo_Name: - { - str = info->name; - break; - } - case PlInfo_Author: - { - str = info->author; - break; - } - case PlInfo_Description: - { - str = info->description; - break; - } - case PlInfo_Version: - { - str = info->version; - break; - } - case PlInfo_URL: - { - str = info->url; - break; - } - } - - if (!str || str[0] == '\0') - { - return 0; - } - - pContext->StringToLocalUTF8(params[3], params[4], str, NULL); - - return 1; -} - -static cell_t SetFailState(IPluginContext *pContext, const cell_t *params) -{ - char *str; - SMPlugin *pPlugin; - - pContext->LocalToString(params[1], &str); - pPlugin = scripts->FindPluginByContext(pContext->GetContext()); - - if (params[0] == 1) - { - pPlugin->SetErrorState(Plugin_Error, "%s", str); - - return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", str); - } - else - { - char buffer[2048]; - - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - pPlugin->SetErrorState(Plugin_Error, "%s", str); - return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "Formatting error (%s)", str); - } - else - { - pPlugin->SetErrorState(Plugin_Error, "%s", buffer); - return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer); - } - } - - return 0; -} - -static cell_t GetSysTickCount(IPluginContext *pContext, const cell_t *params) -{ -#if defined PLATFORM_WINDOWS - return (cell_t)GetTickCount(); -#elif defined PLATFORM_POSIX - tms tm; - clock_t ticks = times(&tm); - long ticks_per_sec = sysconf(_SC_CLK_TCK); - double fticks = (double)ticks / (double)ticks_per_sec; - fticks *= 1000.0f; - if (fticks > INT_MAX) - { - double r = (int)(fticks / INT_MAX) * (double)INT_MAX; - fticks -= r; - } - return (cell_t)fticks; -#endif -} - -static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params) -{ - SMPlugin *plugin = scripts->FindPluginByContext(pContext->GetContext()); - - char *cfg, *folder; - pContext->LocalToString(params[2], &cfg); - pContext->LocalToString(params[3], &folder); - - if (cfg[0] == '\0') - { - static char temp_str[255]; - static char temp_file[PLATFORM_MAX_PATH]; - char *ptr; - - g_LibSys.GetFileFromPath(temp_str, sizeof(temp_str), plugin->GetFilename()); - if ((ptr = strstr(temp_str, ".smx")) != NULL) - { - *ptr = '\0'; - } - - /* We have the raw filename! */ - UTIL_Format(temp_file, sizeof(temp_file), "plugin.%s", temp_str); - cfg = temp_file; - } - - plugin->AddConfig(params[1] ? true : false, cfg, folder); - - return 1; -} - -static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *params) -{ - char *name; - uint32_t idx; - sp_native_t *native; - - pContext->LocalToString(params[1], &name); - if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE) - { - /* Oops! This HAS to silently fail! */ - return 0; - } - - pContext->GetNativeByIndex(idx, &native); - - native->flags |= SP_NTVFLAG_OPTIONAL; - - return 1; -} - -static cell_t RegPluginLibrary(IPluginContext *pContext, const cell_t *params) -{ - char *name; - SMPlugin *pl = scripts->FindPluginByContext(pContext->GetContext()); - - pContext->LocalToString(params[1], &name); - - pl->AddLibrary(name); - return 1; -} - -static cell_t LibraryExists(IPluginContext *pContext, const cell_t *params) -{ - char *str; - pContext->LocalToString(params[1], &str); - - if (strcmp(str, "__CanTestFeatures__") == 0) - { - return 1; - } - - if (scripts->LibraryExists(str)) - { - return 1; - } - - if (extsys->LibraryExists(str)) - { - return 1; - } - - return 0; -} - -static cell_t sm_LogAction(IPluginContext *pContext, const cell_t *params) -{ - char buffer[2048]; - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - return 0; - } - - IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext()); - - LogAction(pPlugin->GetMyHandle(), 2, params[1], params[2], buffer); - - return 1; -} - -static cell_t LogToFile(IPluginContext *pContext, const cell_t *params) -{ - char *file; - pContext->LocalToString(params[1], &file); - - char path[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file); - - FILE *fp = fopen(path, "at"); - if (!fp) - { - return pContext->ThrowNativeError("Could not open file \"%s\"", path); - } - - char buffer[2048]; - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - fclose(fp); - return 0; - } - - IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext()); - - g_Logger.LogToOpenFile(fp, "[%s] %s", pPlugin->GetFilename(), buffer); - - fclose(fp); - - return 1; -} - -static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params) -{ - char *file; - pContext->LocalToString(params[1], &file); - - char path[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file); - - FILE *fp = fopen(path, "at"); - if (!fp) - { - return pContext->ThrowNativeError("Could not open file \"%s\"", path); - } - - char buffer[2048]; - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - fclose(fp); - return 0; - } - - g_Logger.LogToOpenFile(fp, "%s", buffer); - - fclose(fp); - - return 1; -} - -static cell_t GetExtensionFileStatus(IPluginContext *pContext, const cell_t *params) -{ - char *str; - pContext->LocalToString(params[1], &str); - - IExtension *pExtension = extsys->FindExtensionByFile(str); - - if (!pExtension) - { - return -2; - } - - if (!pExtension->IsLoaded()) - { - return -1; - } - - char *error; - pContext->LocalToString(params[2], &error); - if (!pExtension->IsRunning(error, params[3])) - { - return 0; - } - - return 1; -} - -static cell_t FindPluginByNumber(IPluginContext *pContext, const cell_t *params) -{ - IPlugin *pPlugin = scripts->FindPluginByOrder(params[1]); - - if (pPlugin == NULL) - { - return BAD_HANDLE; - } - - return pPlugin->GetMyHandle(); -} - -static cell_t VerifyCoreVersion(IPluginContext *pContext, const cell_t *params) -{ - return 4; -} - -static cell_t GetFeatureStatus(IPluginContext *pContext, const cell_t *params) -{ - FeatureType type = (FeatureType)params[1]; - char *name; - - pContext->LocalToString(params[2], &name); - - return sharesys->TestFeature(pContext->GetRuntime(), type, name); -} - -static cell_t RequireFeature(IPluginContext *pContext, const cell_t *params) -{ - FeatureType type = (FeatureType)params[1]; - char *name; - - pContext->LocalToString(params[2], &name); - - if (sharesys->TestFeature(pContext->GetRuntime(), type, name) != FeatureStatus_Available) - { - char buffer[255]; - char *msg = buffer; - char default_message[255]; - SMPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext()); - - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3); - if (pContext->GetLastNativeError() != SP_ERROR_NONE || buffer[0] == '\0') - { - UTIL_Format(default_message, sizeof(default_message), "Feature \"%s\" not available", name); - msg = default_message; - } - pPlugin->SetErrorState(Plugin_Error, "%s", msg); - return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", msg); - } - - return 1; -} - -enum NumberType -{ - NumberType_Int8, - NumberType_Int16, - NumberType_Int32 -}; - -//memory addresses below 0x10000 are automatically considered invalid for dereferencing -#define VALID_MINIMUM_MEMORY_ADDRESS 0x10000 - -static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params) -{ - void *addr = reinterpret_cast(params[1]); - - if (addr == NULL) - { - return pContext->ThrowNativeError("Address cannot be null"); - } - else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) - { - return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); - } - NumberType size = static_cast(params[2]); - - switch(size) - { - case NumberType_Int8: - return *reinterpret_cast(addr); - case NumberType_Int16: - return *reinterpret_cast(addr); - case NumberType_Int32: - return *reinterpret_cast(addr); - default: - return pContext->ThrowNativeError("Invalid number types %d", size); - } -} - - -static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params) -{ - void *addr = reinterpret_cast(params[1]); - - if (addr == NULL) - { - return pContext->ThrowNativeError("Address cannot be null"); - } - else if (reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) - { - return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr); - } - cell_t data = params[2]; - - NumberType size = static_cast(params[3]); - - switch(size) - { - case NumberType_Int8: - SourceHook::SetMemAccess(addr, sizeof(uint8_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - *reinterpret_cast(addr) = data; - break; - case NumberType_Int16: - SourceHook::SetMemAccess(addr, sizeof(uint16_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - *reinterpret_cast(addr) = data; - break; - case NumberType_Int32: - SourceHook::SetMemAccess(addr, sizeof(uint32_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - *reinterpret_cast(addr) = data; - break; - default: - return pContext->ThrowNativeError("Invalid number types %d", size); - } - - return 0; -} - -REGISTER_NATIVES(coreNatives) -{ - {"AutoExecConfig", AutoExecConfig}, - {"GetPluginFilename", GetPluginFilename}, - {"GetPluginInfo", GetPluginInfo}, - {"GetPluginIterator", GetPluginIterator}, - {"GetPluginStatus", GetPluginStatus}, - {"GetSysTickCount", GetSysTickCount}, - {"GetTime", GetTime}, - {"IsPluginDebugging", IsPluginDebugging}, - {"MorePlugins", MorePlugins}, - {"ReadPlugin", ReadPlugin}, - {"ThrowError", ThrowError}, - {"SetFailState", SetFailState}, - {"FormatTime", FormatTime}, - {"MarkNativeAsOptional", MarkNativeAsOptional}, - {"RegPluginLibrary", RegPluginLibrary}, - {"LibraryExists", LibraryExists}, - {"LogAction", sm_LogAction}, - {"LogToFile", LogToFile}, - {"LogToFileEx", LogToFileEx}, - {"GetExtensionFileStatus", GetExtensionFileStatus}, - {"FindPluginByNumber", FindPluginByNumber}, - {"VerifyCoreVersion", VerifyCoreVersion}, - {"GetFeatureStatus", GetFeatureStatus}, - {"RequireFeature", RequireFeature}, - {"LoadFromAddress", LoadFromAddress}, - {"StoreToAddress", StoreToAddress}, - {NULL, NULL}, -}; - diff --git a/core/sourcemm_api.cpp b/core/sourcemm_api.cpp index 306965a8e..15a679a45 100644 --- a/core/sourcemm_api.cpp +++ b/core/sourcemm_api.cpp @@ -167,7 +167,7 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface) /* This shouldn't happen */ if (!iface) { - g_Logger.LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater."); + logger->LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater."); return; } diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index f31b7af6b..16dd1c89a 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -572,9 +572,9 @@ void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...) if (tag) { - g_Logger.LogMessage("[%s] %s", tag, buffer); + logger->LogMessage("[%s] %s", tag, buffer); } else { - g_Logger.LogMessage("%s", buffer); + logger->LogMessage("%s", buffer); } } @@ -591,9 +591,9 @@ void SourceModBase::LogError(IExtension *pExt, const char *format, ...) if (tag) { - g_Logger.LogError("[%s] %s", tag, buffer); + logger->LogError("[%s] %s", tag, buffer); } else { - g_Logger.LogError("%s", buffer); + logger->LogError("%s", buffer); } }