Move Logger and Core natives to Logic
This commit is contained in:
parent
f570fa414b
commit
17d5af0e2f
@ -31,7 +31,6 @@ project.sources += [
|
|||||||
'smn_console.cpp',
|
'smn_console.cpp',
|
||||||
'UserMessages.cpp',
|
'UserMessages.cpp',
|
||||||
'MenuManager.cpp',
|
'MenuManager.cpp',
|
||||||
'smn_core.cpp',
|
|
||||||
'smn_hudtext.cpp',
|
'smn_hudtext.cpp',
|
||||||
'smn_usermsgs.cpp',
|
'smn_usermsgs.cpp',
|
||||||
'MenuStyle_Base.cpp',
|
'MenuStyle_Base.cpp',
|
||||||
|
@ -195,7 +195,7 @@ class GenericCommandHooker : public IConCommandLinkListener
|
|||||||
size_t index;
|
size_t index;
|
||||||
if (!FindVtable(vtable, 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ public:
|
|||||||
|
|
||||||
if (dispatch.thisptroffs < 0)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ public:
|
|||||||
|
|
||||||
if (!vtables.size())
|
if (!vtables.size())
|
||||||
{
|
{
|
||||||
g_Logger.LogError("Command filter could not find any cvars!");
|
logger->LogError("Command filter could not find any cvars!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ void CoreConfig::Initialize()
|
|||||||
{
|
{
|
||||||
/* :TODO: This won't actually log or print anything :( - So fix that somehow */
|
/* :TODO: This won't actually log or print anything :( - So fix that somehow */
|
||||||
const char *error = textparsers->GetSMCErrorString(err);
|
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)
|
if (err == ConfigResult_Reject)
|
||||||
{
|
{
|
||||||
/* This is a fatal error */
|
/* 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;
|
return SMCResult_Continue;
|
||||||
@ -469,7 +469,7 @@ bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
|
|||||||
}
|
}
|
||||||
else
|
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;
|
return can_create;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ void CHalfLife2::InitLogicalEntData()
|
|||||||
if (!addr)
|
if (!addr)
|
||||||
{
|
{
|
||||||
// Key exists so notify if lookup fails, but try other method.
|
// 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
|
else
|
||||||
{
|
{
|
||||||
@ -186,7 +186,7 @@ void CHalfLife2::InitLogicalEntData()
|
|||||||
int offset;
|
int offset;
|
||||||
if (!g_pGameConf->GetOffset("gEntList", &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;
|
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 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))
|
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;
|
g_EntList = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -211,7 +211,7 @@ void CHalfLife2::InitLogicalEntData()
|
|||||||
|
|
||||||
if (!g_EntList && !g_pEntInfoList)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,7 +225,7 @@ void CHalfLife2::InitCommandLine()
|
|||||||
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error)));
|
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error)));
|
||||||
if (lib == NULL)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ void CHalfLife2::InitCommandLine()
|
|||||||
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error)));
|
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error)));
|
||||||
if (lib == NULL)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ void CHalfLife2::InitCommandLine()
|
|||||||
|
|
||||||
if (m_pGetCommandLine == NULL)
|
if (m_pGetCommandLine == NULL)
|
||||||
{
|
{
|
||||||
g_Logger.LogError("Could not locate any command line functionality");
|
logger->LogError("Could not locate any command line functionality");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
520
core/Logger.cpp
520
core/Logger.cpp
@ -39,61 +39,12 @@
|
|||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include <sourcemod_version.h>
|
#include <sourcemod_version.h>
|
||||||
|
|
||||||
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 *);
|
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)
|
static void HookLogPrint(const char *message)
|
||||||
{
|
{
|
||||||
g_in_game_log_hook = true;
|
g_in_game_log_hook = true;
|
||||||
@ -104,477 +55,16 @@ static void HookLogPrint(const char *message)
|
|||||||
RETURN_META(MRES_SUPERCEDE);
|
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);
|
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);
|
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)
|
void Engine_LogPrintWrapper(const char *msg)
|
||||||
{
|
{
|
||||||
if (g_in_game_log_hook)
|
if (g_in_game_log_hook)
|
||||||
|
@ -38,76 +38,13 @@
|
|||||||
|
|
||||||
using namespace SourceHook;
|
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
|
public: //SMGlobalClass
|
||||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
|
||||||
const char *value,
|
|
||||||
ConfigSource source,
|
|
||||||
char *error,
|
|
||||||
size_t maxlength);
|
|
||||||
void OnSourceModStartup(bool late);
|
void OnSourceModStartup(bool late);
|
||||||
void OnSourceModAllShutdown();
|
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);
|
void Engine_LogPrintWrapper(const char *msg);
|
||||||
|
|
||||||
extern bool g_in_game_log_hook;
|
|
||||||
extern Logger g_Logger;
|
|
||||||
|
|
||||||
#endif // _INCLUDE_SOURCEMOD_CLOGGER_H_
|
#endif // _INCLUDE_SOURCEMOD_CLOGGER_H_
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "sourcehook.h"
|
#include "sourcehook.h"
|
||||||
#include "sm_srvcmds.h"
|
#include "sm_srvcmds.h"
|
||||||
|
#include "logic_bridge.h"
|
||||||
|
|
||||||
NextMapManager g_NextMap;
|
NextMapManager g_NextMap;
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
|
|||||||
{
|
{
|
||||||
if (g_forcedChange)
|
if (g_forcedChange)
|
||||||
{
|
{
|
||||||
g_Logger.LogMessage("[SM] Changed map to \"%s\"", map);
|
logger->LogMessage("[SM] Changed map to \"%s\"", map);
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +142,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
|
|||||||
RETURN_META(MRES_IGNORED);
|
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_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
|
||||||
UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
|
UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
|
||||||
|
@ -1238,7 +1238,7 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
|
|||||||
if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0')
|
if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0')
|
||||||
{
|
{
|
||||||
unsigned int accountId = pPlayer->GetSteamAccountID();
|
unsigned int accountId = pPlayer->GetSteamAccountID();
|
||||||
g_Logger.LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
|
logger->LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
|
||||||
new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress());
|
new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress());
|
||||||
|
|
||||||
pPlayer->Kick("NetworkID spoofing detected.");
|
pPlayer->Kick("NetworkID spoofing detected.");
|
||||||
|
@ -66,6 +66,8 @@ binary.sources += [
|
|||||||
'sm_trie.cpp',
|
'sm_trie.cpp',
|
||||||
'smn_console.cpp',
|
'smn_console.cpp',
|
||||||
'ProfileTools.cpp',
|
'ProfileTools.cpp',
|
||||||
|
'Logger.cpp',
|
||||||
|
'smn_core.cpp',
|
||||||
]
|
]
|
||||||
if builder.target_platform == 'windows':
|
if builder.target_platform == 'windows':
|
||||||
binary.sources += ['thread/WinThreads.cpp']
|
binary.sources += ['thread/WinThreads.cpp']
|
||||||
|
@ -198,11 +198,11 @@ private:
|
|||||||
|
|
||||||
if (!m_bFileNameLogged)
|
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;
|
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:
|
private:
|
||||||
bool m_bFileNameLogged;
|
bool m_bFileNameLogged;
|
||||||
|
@ -89,11 +89,11 @@ void DBManager::OnSourceModLevelChange(const char *mapName)
|
|||||||
ke::AutoLock lock(&m_ConfigLock);
|
ke::AutoLock lock(&m_ConfigLock);
|
||||||
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
|
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)
|
if (err != SMCError_Custom)
|
||||||
{
|
{
|
||||||
const char *txt = textparsers->GetSMCErrorString(err);
|
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)
|
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;
|
s_OneTimeThreaderErrorMsg = true;
|
||||||
}
|
}
|
||||||
m_Worker = NULL;
|
m_Worker = NULL;
|
||||||
|
@ -606,7 +606,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn
|
|||||||
{
|
{
|
||||||
if (bErrorOnMissing || libsys->IsPathFile(p->GetPath()))
|
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);
|
p->SetError(error);
|
||||||
|
@ -301,8 +301,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
if (error[0] != '\0')
|
if (error[0] != '\0')
|
||||||
{
|
{
|
||||||
m_IgnoreLevel = 1;
|
m_IgnoreLevel = 1;
|
||||||
smcore.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
|
logger->LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
|
||||||
smcore.LogError("[SM] %s", error);
|
logger->LogError("[SM] %s", error);
|
||||||
} else {
|
} else {
|
||||||
m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY;
|
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)
|
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);
|
logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
|
||||||
smcore.LogError("[SM] Unrecognized platform \"%s\"", name);
|
logger->LogError("[SM] Unrecognized platform \"%s\"", name);
|
||||||
}
|
}
|
||||||
m_IgnoreLevel = 1;
|
m_IgnoreLevel = 1;
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
|
|||||||
}
|
}
|
||||||
else
|
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) {
|
} else if (strcmp(key, "signature") == 0) {
|
||||||
strncopy(m_AddressSignature, value, sizeof(m_AddressSignature));
|
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)
|
if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0)
|
||||||
&& (!m_Offsets.retrieve(m_offset)))
|
&& (!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_Class,
|
||||||
m_Prop,
|
m_Prop,
|
||||||
m_CurFile,
|
m_CurFile,
|
||||||
@ -556,7 +556,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
void *final_addr = NULL;
|
void *final_addr = NULL;
|
||||||
if (addrInBase == NULL)
|
if (addrInBase == NULL)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
|
logger->LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
|
||||||
s_TempSig.library,
|
s_TempSig.library,
|
||||||
m_CurFile);
|
m_CurFile);
|
||||||
}
|
}
|
||||||
@ -570,7 +570,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
if (VirtualQuery(addrInBase, &mem, sizeof(mem)))
|
if (VirtualQuery(addrInBase, &mem, sizeof(mem)))
|
||||||
final_addr = g_MemUtils.ResolveSymbol(mem.AllocationBase, &s_TempSig.sig[1]);
|
final_addr = g_MemUtils.ResolveSymbol(mem.AllocationBase, &s_TempSig.sig[1]);
|
||||||
else
|
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
|
#elif defined PLATFORM_POSIX
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
/* GNU only: returns 0 on error, inconsistent! >:[ */
|
/* 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]);
|
final_addr = dlsym(handle, &s_TempSig.sig[1]);
|
||||||
dlclose(handle);
|
dlclose(handle);
|
||||||
} else {
|
} else {
|
||||||
smcore.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
|
logger->LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
|
||||||
s_TempSig.library,
|
s_TempSig.library,
|
||||||
m_File);
|
m_File);
|
||||||
}
|
}
|
||||||
} else {
|
} 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,
|
s_TempSig.library,
|
||||||
m_File);
|
m_File);
|
||||||
}
|
}
|
||||||
@ -827,8 +827,8 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
|
|||||||
{
|
{
|
||||||
const char *msg = textparsers->GetSMCErrorString(err);
|
const char *msg = textparsers->GetSMCErrorString(err);
|
||||||
|
|
||||||
smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path);
|
logger->LogError("[SM] Error parsing master gameconf file \"%s\":", path);
|
||||||
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
|
logger->LogError("[SM] Error %d on line %d, col %d: %s",
|
||||||
err,
|
err,
|
||||||
state.line,
|
state.line,
|
||||||
state.col,
|
state.col,
|
||||||
@ -915,8 +915,8 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
|
|||||||
{
|
{
|
||||||
const char *msg = textparsers->GetSMCErrorString(err);
|
const char *msg = textparsers->GetSMCErrorString(err);
|
||||||
|
|
||||||
smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
|
logger->LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
|
||||||
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
|
logger->LogError("[SM] Error %d on line %d, col %d: %s",
|
||||||
err,
|
err,
|
||||||
state.line,
|
state.line,
|
||||||
state.col,
|
state.col,
|
||||||
|
@ -957,8 +957,8 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define HANDLE_LOG_VERY_BAD(message, ...) \
|
#define HANDLE_LOG_VERY_BAD(message, ...) \
|
||||||
smcore.LogFatal(message, ##__VA_ARGS__); \
|
logger->LogFatal(message, ##__VA_ARGS__); \
|
||||||
smcore.LogError(message, ##__VA_ARGS__);
|
logger->LogError(message, ##__VA_ARGS__);
|
||||||
|
|
||||||
bool HandleSystem::TryAndFreeSomeHandles()
|
bool HandleSystem::TryAndFreeSomeHandles()
|
||||||
{
|
{
|
||||||
|
@ -96,11 +96,11 @@ void CPhraseFile::ParseWarning(const char *message, ...)
|
|||||||
|
|
||||||
if (!m_FileLogged)
|
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;
|
m_FileLogged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogError("[SM] %s", buffer);
|
logger->LogError("[SM] %s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPhraseFile::ReparseFile()
|
void CPhraseFile::ReparseFile()
|
||||||
@ -142,8 +142,8 @@ void CPhraseFile::ReparseFile()
|
|||||||
msg = m_ParseError.c_str();
|
msg = m_ParseError.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
|
logger->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] Error (line %d, column %d): %s", states.line, states.col, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *code;
|
const char *code;
|
||||||
@ -175,10 +175,10 @@ void CPhraseFile::ReparseFile()
|
|||||||
msg = m_ParseError.c_str();
|
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,
|
code,
|
||||||
m_File.c_str());
|
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.line,
|
||||||
states.col,
|
states.col,
|
||||||
msg);
|
msg);
|
||||||
@ -831,13 +831,13 @@ void Translator::RebuildLanguageDatabase()
|
|||||||
str_err = m_CustomError.c_str();
|
str_err = m_CustomError.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogError("[SM] Failed to parse language header file: \"%s\"", path);
|
logger->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] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_LCodeLookup.retrieve(m_InitialLang, &m_ServerLang))
|
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));
|
smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
|
||||||
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
|
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
|
||||||
@ -845,7 +845,7 @@ void Translator::RebuildLanguageDatabase()
|
|||||||
|
|
||||||
if (!m_Languages.size())
|
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; i<m_Files.size(); i++)
|
for (size_t i=0; i<m_Files.size(); i++)
|
||||||
@ -872,7 +872,7 @@ SMCResult Translator::ReadSMC_NewSection(const SMCStates *states, const char *na
|
|||||||
|
|
||||||
if (!m_InLanguageSection)
|
if (!m_InLanguageSection)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
|
logger->LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SMCResult_Continue;
|
return SMCResult_Continue;
|
||||||
@ -1025,11 +1025,11 @@ bool CoreTranslate(char *buffer, size_t maxlength, const char *format, unsigned
|
|||||||
{
|
{
|
||||||
if (fail_phrase != NULL)
|
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
|
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;
|
return false;
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "ForwardSys.h"
|
#include "ForwardSys.h"
|
||||||
#include "AdminCache.h"
|
#include "AdminCache.h"
|
||||||
#include "ProfileTools.h"
|
#include "ProfileTools.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
sm_core_t smcore;
|
sm_core_t smcore;
|
||||||
IHandleSys *handlesys = &g_HandleSys;
|
IHandleSys *handlesys = &g_HandleSys;
|
||||||
@ -72,6 +73,7 @@ ISourcePawnEngine *g_pSourcePawn;
|
|||||||
ISourcePawnEngine2 *g_pSourcePawn2;
|
ISourcePawnEngine2 *g_pSourcePawn2;
|
||||||
CNativeOwner g_CoreNatives;
|
CNativeOwner g_CoreNatives;
|
||||||
IScriptManager *scripts = &g_PluginSys;
|
IScriptManager *scripts = &g_PluginSys;
|
||||||
|
ILogger *logger = &g_Logger;
|
||||||
|
|
||||||
static void AddCorePhraseFile(const char *filename)
|
static void AddCorePhraseFile(const char *filename)
|
||||||
{
|
{
|
||||||
@ -140,6 +142,7 @@ static sm_logic_t logic =
|
|||||||
&g_Forwards,
|
&g_Forwards,
|
||||||
&g_Admins,
|
&g_Admins,
|
||||||
NULL,
|
NULL,
|
||||||
|
&g_Logger,
|
||||||
-1.0f
|
-1.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +53,8 @@ extern IPlayerManager *playerhelpers;
|
|||||||
extern IAdminSystem *adminsys;
|
extern IAdminSystem *adminsys;
|
||||||
extern IGameHelpers *gamehelpers;
|
extern IGameHelpers *gamehelpers;
|
||||||
extern IScriptManager *scripts;
|
extern IScriptManager *scripts;
|
||||||
|
extern IExtensionSys *extsys;
|
||||||
|
extern ILogger *logger;
|
||||||
|
|
||||||
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
|
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ using namespace SourceHook;
|
|||||||
* Add 1 to the RHS of this expression to bump the intercom file
|
* Add 1 to the RHS of this expression to bump the intercom file
|
||||||
* This is to prevent mismatching core/logic binaries
|
* This is to prevent mismatching core/logic binaries
|
||||||
*/
|
*/
|
||||||
#define SM_LOGIC_MAGIC (0x0F47C0DE - 28)
|
#define SM_LOGIC_MAGIC (0x0F47C0DE - 29)
|
||||||
|
|
||||||
#if defined SM_LOGIC
|
#if defined SM_LOGIC
|
||||||
class IVEngineServer
|
class IVEngineServer
|
||||||
@ -213,6 +213,14 @@ public:
|
|||||||
virtual void FreeExtensionList(const CVector<IExtension *> *list) = 0;
|
virtual void FreeExtensionList(const CVector<IExtension *> *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
|
class AutoPluginList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -273,13 +281,10 @@ struct sm_core_t
|
|||||||
ConVar * (*FindConVar)(const char*);
|
ConVar * (*FindConVar)(const char*);
|
||||||
unsigned int (*strncopy)(char*, const char*, size_t);
|
unsigned int (*strncopy)(char*, const char*, size_t);
|
||||||
char * (*TrimWhitespace)(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 (*LogToGame)(const char *message);
|
||||||
void (*ConPrint)(const char *message);
|
void (*ConPrint)(const char *message);
|
||||||
const char * (*GetCvarString)(ConVar*);
|
const char * (*GetCvarString)(ConVar*);
|
||||||
|
bool (*GetCvarBool)(ConVar*);
|
||||||
size_t (*Format)(char*, size_t, const char*, ...);
|
size_t (*Format)(char*, size_t, const char*, ...);
|
||||||
size_t (*FormatArgs)(char*, size_t, const char*,va_list ap);
|
size_t (*FormatArgs)(char*, size_t, const char*,va_list ap);
|
||||||
bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **,
|
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);
|
char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool);
|
||||||
size_t (*DecodeHexString)(unsigned char *, size_t, const char *);
|
size_t (*DecodeHexString)(unsigned char *, size_t, const char *);
|
||||||
IGameConfig * (*GetCoreGameConfig)();
|
IGameConfig * (*GetCoreGameConfig)();
|
||||||
bool (*OnLogPrint)(const char *msg); // true to supercede
|
bool (*OnLogPrint)(const char *msg); // true to supersede
|
||||||
IDebugListener *debugger;
|
IDebugListener *debugger;
|
||||||
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
||||||
void (*AddNatives)(sp_nativeinfo_t *natives);
|
void (*AddNatives)(sp_nativeinfo_t *natives);
|
||||||
@ -339,6 +344,7 @@ struct sm_logic_t
|
|||||||
IForwardManager *forwardsys;
|
IForwardManager *forwardsys;
|
||||||
IAdminSystem *adminsys;
|
IAdminSystem *adminsys;
|
||||||
IdentityToken_t *core_ident;
|
IdentityToken_t *core_ident;
|
||||||
|
ILogger *logger;
|
||||||
float sentinel;
|
float sentinel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <ISourceMod.h>
|
#include <ISourceMod.h>
|
||||||
#include <ITranslator.h>
|
#include <ITranslator.h>
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
HandleType_t g_FileType;
|
HandleType_t g_FileType;
|
||||||
HandleType_t g_DirType;
|
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());
|
IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
|
||||||
smcore.Log("[%s] %s", pPlugin->GetFilename(), buffer);
|
g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -616,7 +617,7 @@ static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
|
IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
|
||||||
smcore.LogError("[%s] %s", pPlugin->GetFilename(), buffer);
|
g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -669,7 +670,7 @@ static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -699,7 +700,7 @@ static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogToFile(pFile, "%s", buffer);
|
g_Logger.LogToOpenFile(pFile, "%s", buffer);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -202,8 +202,8 @@ public:
|
|||||||
{
|
{
|
||||||
errmsg = "Unknown error";
|
errmsg = "Unknown error";
|
||||||
}
|
}
|
||||||
smcore.LogError("[SM] Could not parse file \"%s\"", m_ConfigFile);
|
logger->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] Error on line %d (col %d): %s", states.line, states.col, errmsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -120,7 +120,7 @@ public: //ICommandTargetProcessor
|
|||||||
Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL);
|
Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL);
|
||||||
AutoHandleCloner ahc(hndl, sec);
|
AutoHandleCloner ahc(hndl, sec);
|
||||||
if (ahc.getClone() == BAD_HANDLE) {
|
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;
|
delete array;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ IExtensionSys *extsys;
|
|||||||
IHandleSys *handlesys;
|
IHandleSys *handlesys;
|
||||||
IForwardManager *forwardsys;
|
IForwardManager *forwardsys;
|
||||||
IAdminSystem *adminsys;
|
IAdminSystem *adminsys;
|
||||||
|
ILogger *logger;
|
||||||
|
|
||||||
class VEngineServer_Logic : public IVEngineServer_Logic
|
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_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_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)
|
static ConVar *find_convar(const char *name)
|
||||||
{
|
{
|
||||||
return icvar->FindVar(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)
|
static void log_to_game(const char *message)
|
||||||
{
|
{
|
||||||
Engine_LogPrintWrapper(message);
|
Engine_LogPrintWrapper(message);
|
||||||
@ -306,6 +274,11 @@ static const char *get_cvar_string(ConVar* cvar)
|
|||||||
return cvar->GetString();
|
return cvar->GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool get_cvar_bool(ConVar* cvar)
|
||||||
|
{
|
||||||
|
return cvar->GetBool();
|
||||||
|
}
|
||||||
|
|
||||||
static bool get_game_name(char *buffer, size_t maxlength)
|
static bool get_game_name(char *buffer, size_t maxlength)
|
||||||
{
|
{
|
||||||
KeyValues *pGameInfo = new KeyValues("GameInfo");
|
KeyValues *pGameInfo = new KeyValues("GameInfo");
|
||||||
@ -561,13 +534,10 @@ static sm_core_t core_bridge =
|
|||||||
find_convar,
|
find_convar,
|
||||||
strncopy,
|
strncopy,
|
||||||
UTIL_TrimWhitespace,
|
UTIL_TrimWhitespace,
|
||||||
log_error,
|
|
||||||
log_fatal,
|
|
||||||
log_message,
|
|
||||||
log_to_file,
|
|
||||||
log_to_game,
|
log_to_game,
|
||||||
conprint,
|
conprint,
|
||||||
get_cvar_string,
|
get_cvar_string,
|
||||||
|
get_cvar_bool,
|
||||||
UTIL_Format,
|
UTIL_Format,
|
||||||
UTIL_FormatArgs,
|
UTIL_FormatArgs,
|
||||||
gnprintf,
|
gnprintf,
|
||||||
@ -636,6 +606,7 @@ void InitLogicBridge()
|
|||||||
handlesys = logicore.handlesys;
|
handlesys = logicore.handlesys;
|
||||||
forwardsys = logicore.forwardsys;
|
forwardsys = logicore.forwardsys;
|
||||||
adminsys = logicore.adminsys;
|
adminsys = logicore.adminsys;
|
||||||
|
logger = logicore.logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartLogicBridge(char *error, size_t maxlength)
|
bool StartLogicBridge(char *error, size_t maxlength)
|
||||||
|
@ -48,5 +48,6 @@ extern IExtensionSys *extsys;
|
|||||||
extern IHandleSys *handlesys;
|
extern IHandleSys *handlesys;
|
||||||
extern IForwardManager *forwardsys;
|
extern IForwardManager *forwardsys;
|
||||||
extern IAdminSystem *adminsys;
|
extern IAdminSystem *adminsys;
|
||||||
|
extern ILogger *logger;
|
||||||
|
|
||||||
#endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */
|
#endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */
|
||||||
|
@ -1216,7 +1216,7 @@ static cell_t AddCommandListener(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
if (strcasecmp(name, "sm") == 0)
|
if (strcasecmp(name, "sm") == 0)
|
||||||
{
|
{
|
||||||
g_Logger.LogError("Request to register \"sm\" command denied.");
|
logger->LogError("Request to register \"sm\" command denied.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* 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 <http://www.sourcemod.net/license.php>.
|
|
||||||
*
|
|
||||||
* Version: $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "sm_stringutil.h"
|
|
||||||
#include "sm_globals.h"
|
|
||||||
#include "sourcemod.h"
|
|
||||||
#include "LibrarySys.h"
|
|
||||||
#include "TimerSys.h"
|
|
||||||
#include "Logger.h"
|
|
||||||
#include <sh_memory.h>
|
|
||||||
#include "logic_bridge.h"
|
|
||||||
|
|
||||||
#if defined PLATFORM_WINDOWS
|
|
||||||
#include <windows.h>
|
|
||||||
#elif defined PLATFORM_POSIX
|
|
||||||
#include <limits.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/times.h>
|
|
||||||
#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<cell_t>(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<char *>(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<void*>(params[1]);
|
|
||||||
|
|
||||||
if (addr == NULL)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Address cannot be null");
|
|
||||||
}
|
|
||||||
else if (reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Invalid address 0x%x is pointing to reserved memory.", addr);
|
|
||||||
}
|
|
||||||
NumberType size = static_cast<NumberType>(params[2]);
|
|
||||||
|
|
||||||
switch(size)
|
|
||||||
{
|
|
||||||
case NumberType_Int8:
|
|
||||||
return *reinterpret_cast<uint8_t*>(addr);
|
|
||||||
case NumberType_Int16:
|
|
||||||
return *reinterpret_cast<uint16_t*>(addr);
|
|
||||||
case NumberType_Int32:
|
|
||||||
return *reinterpret_cast<uint32_t*>(addr);
|
|
||||||
default:
|
|
||||||
return pContext->ThrowNativeError("Invalid number types %d", size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
void *addr = reinterpret_cast<void*>(params[1]);
|
|
||||||
|
|
||||||
if (addr == NULL)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Address cannot be null");
|
|
||||||
}
|
|
||||||
else if (reinterpret_cast<uintptr_t>(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<NumberType>(params[3]);
|
|
||||||
|
|
||||||
switch(size)
|
|
||||||
{
|
|
||||||
case NumberType_Int8:
|
|
||||||
SourceHook::SetMemAccess(addr, sizeof(uint8_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
|
|
||||||
*reinterpret_cast<uint8_t*>(addr) = data;
|
|
||||||
break;
|
|
||||||
case NumberType_Int16:
|
|
||||||
SourceHook::SetMemAccess(addr, sizeof(uint16_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
|
|
||||||
*reinterpret_cast<uint16_t*>(addr) = data;
|
|
||||||
break;
|
|
||||||
case NumberType_Int32:
|
|
||||||
SourceHook::SetMemAccess(addr, sizeof(uint32_t), SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC);
|
|
||||||
*reinterpret_cast<uint32_t*>(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},
|
|
||||||
};
|
|
||||||
|
|
@ -167,7 +167,7 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface)
|
|||||||
/* This shouldn't happen */
|
/* This shouldn't happen */
|
||||||
if (!iface)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,9 +572,9 @@ void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...)
|
|||||||
|
|
||||||
if (tag)
|
if (tag)
|
||||||
{
|
{
|
||||||
g_Logger.LogMessage("[%s] %s", tag, buffer);
|
logger->LogMessage("[%s] %s", tag, buffer);
|
||||||
} else {
|
} else {
|
||||||
g_Logger.LogMessage("%s", buffer);
|
logger->LogMessage("%s", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,9 +591,9 @@ void SourceModBase::LogError(IExtension *pExt, const char *format, ...)
|
|||||||
|
|
||||||
if (tag)
|
if (tag)
|
||||||
{
|
{
|
||||||
g_Logger.LogError("[%s] %s", tag, buffer);
|
logger->LogError("[%s] %s", tag, buffer);
|
||||||
} else {
|
} else {
|
||||||
g_Logger.LogError("%s", buffer);
|
logger->LogError("%s", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user