- implemented amb855 - LogAction()

- changed base plugins to use LogAction() where appropriate

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401384
This commit is contained in:
David Anderson 2007-08-27 02:00:37 +00:00
parent 2930621b7d
commit aab0eeaa1e
12 changed files with 419 additions and 66 deletions

View File

@ -228,6 +228,39 @@ void Logger::CloseLogger()
_CloseFile(); _CloseFile();
} }
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
{
if (!m_Active)
{
return;
}
va_list ap;
va_start(ap, msg);
LogToOpenFileEx(fp, msg, ap);
va_end(ap);
}
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
char buffer[3072];
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
char date[32];
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
g_SMAPI->ConPrintf("L %s: %s\n", date, buffer);
}
void Logger::LogMessage(const char *vafmt, ...) void Logger::LogMessage(const char *vafmt, ...)
{ {
if (!m_Active) if (!m_Active)
@ -250,17 +283,9 @@ void Logger::LogMessage(const char *vafmt, ...)
_NewMapFile(); _NewMapFile();
} }
char msg[3072];
va_list ap;
va_start(ap, vafmt);
vsnprintf(msg, sizeof(msg), vafmt, ap);
va_end(ap);
char date[32];
time_t t; time_t t;
GetAdjustedTime(&t); GetAdjustedTime(&t);
tm *curtime = localtime(&t); tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
FILE *fp = NULL; FILE *fp = NULL;
if (m_Mode == LoggingMode_PerMap) if (m_Mode == LoggingMode_PerMap)
@ -291,16 +316,20 @@ void Logger::LogMessage(const char *vafmt, ...)
{ {
if (m_DailyPrintHdr) if (m_DailyPrintHdr)
{ {
char date[32];
m_DailyPrintHdr = false; m_DailyPrintHdr = false;
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SVN_FULL_VERSION); fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SVN_FULL_VERSION);
} }
fprintf(fp, "L %s: %s\n", date, msg); va_list ap;
va_start(ap, vafmt);
LogToOpenFileEx(fp, vafmt, ap);
va_end(ap);
fclose(fp); fclose(fp);
} else { } else {
goto print_error; goto print_error;
} }
g_SMAPI->ConPrintf("L %s: %s\n", date, msg);
return; return;
print_error: print_error:
g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n"); g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
@ -318,9 +347,6 @@ void Logger::LogError(const char *vafmt, ...)
GetAdjustedTime(&t); GetAdjustedTime(&t);
tm *curtime = localtime(&t); tm *curtime = localtime(&t);
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
if (curtime->tm_mday != m_CurDay) if (curtime->tm_mday != m_CurDay)
{ {
char _filename[256]; char _filename[256];
@ -330,30 +356,27 @@ void Logger::LogError(const char *vafmt, ...)
m_ErrMapStart = false; m_ErrMapStart = false;
} }
char msg[3072];
va_list ap;
va_start(ap, vafmt);
vsnprintf(msg, sizeof(msg), vafmt, ap);
va_end(ap);
FILE *fp = fopen(m_ErrFileName.c_str(), "a+"); FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
if (fp) if (fp)
{ {
if (!m_ErrMapStart) 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: 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); 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; m_ErrMapStart = true;
} }
fprintf(fp, "L %s: %s\n", date, msg); va_list ap;
va_start(ap, vafmt);
LogToOpenFileEx(fp, vafmt, ap);
va_end(ap);
fclose(fp); fclose(fp);
} else { } else {
g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n"); g_SMAPI->ConPrint("[SM] Unexpected fatal logging error. SourceMod logging disabled.\n");
m_Active = false; m_Active = false;
return; return;
} }
g_SMAPI->ConPrintf("L %s: %s\n", date, msg);
} }
void Logger::MapChange(const char *mapname) void Logger::MapChange(const char *mapname)

View File

@ -32,6 +32,7 @@
#ifndef _INCLUDE_SOURCEMOD_CLOGGER_H_ #ifndef _INCLUDE_SOURCEMOD_CLOGGER_H_
#define _INCLUDE_SOURCEMOD_CLOGGER_H_ #define _INCLUDE_SOURCEMOD_CLOGGER_H_
#include <stdio.h>
#include <sh_string.h> #include <sh_string.h>
#include "sm_globals.h" #include "sm_globals.h"
@ -75,6 +76,8 @@ public:
void LogMessage(const char *msg, ...); void LogMessage(const char *msg, ...);
void LogError(const char *msg, ...); void LogError(const char *msg, ...);
void LogFatal(const char *msg, ...); void LogFatal(const char *msg, ...);
void LogToOpenFile(FILE *fp, const char *msg, ...);
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
void MapChange(const char *mapname); void MapChange(const char *mapname);
const char *GetLogFileName(LogType type) const; const char *GetLogFileName(LogType type) const;
LoggingMode GetLoggingMode() const; LoggingMode GetLoggingMode() const;

View File

@ -39,6 +39,8 @@
#include "HandleSys.h" #include "HandleSys.h"
#include "LibrarySys.h" #include "LibrarySys.h"
#include "TimerSys.h" #include "TimerSys.h"
#include "ForwardSys.h"
#include "Logger.h"
#if defined PLATFORM_WINDOWS #if defined PLATFORM_WINDOWS
#include <windows.h> #include <windows.h>
@ -50,6 +52,7 @@
HandleType_t g_PlIter; HandleType_t g_PlIter;
ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules"); ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules");
IForward *g_OnLogAction = NULL;
class CoreNativeHelpers : class CoreNativeHelpers :
public SMGlobalClass, public SMGlobalClass,
@ -63,6 +66,16 @@ public:
hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER; hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
g_PlIter = g_HandleSys.CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL); g_PlIter = g_HandleSys.CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL);
g_OnLogAction = g_Forwards.CreateForward("OnLogAction",
ET_Hook,
5,
NULL,
Param_Cell,
Param_Cell,
Param_Cell,
Param_Cell,
Param_String);
} }
void OnHandleDestroy(HandleType_t type, void *object) void OnHandleDestroy(HandleType_t type, void *object)
{ {
@ -71,10 +84,44 @@ public:
} }
void OnSourceModShutdown() void OnSourceModShutdown()
{ {
g_Forwards.ReleaseForward(g_OnLogAction);
g_HandleSys.RemoveType(g_PlIter, g_pCoreIdent); g_HandleSys.RemoveType(g_PlIter, g_pCoreIdent);
} }
} g_CoreNativeHelpers; } g_CoreNativeHelpers;
void LogAction(Handle_t hndl, int type, int client, int target, const char *message)
{
if (!g_OnLogAction->GetFunctionCount())
{
return;
}
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 = g_PluginSys.PluginFromHandle(hndl, &err);
if (pPlugin)
{
logtag = pPlugin->GetFilename();
}
}
g_Logger.LogMessage("[%s] %s", logtag, message);
}
static cell_t ThrowError(IPluginContext *pContext, const cell_t *params) static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
{ {
@ -420,6 +467,88 @@ static cell_t LibraryExists(IPluginContext *pContext, const cell_t *params)
return g_PluginSys.LibraryExists(str) ? 1 : 0; return g_PluginSys.LibraryExists(str) ? 1 : 0;
} }
static cell_t sm_LogAction(IPluginContext *pContext, const cell_t *params)
{
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
return 0;
}
CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(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(LANG_SERVER);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
fclose(fp);
return 0;
}
CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(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(LANG_SERVER);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
fclose(fp);
return 0;
}
g_Logger.LogToOpenFile(fp, "%s", buffer);
fclose(fp);
return 1;
}
REGISTER_NATIVES(coreNatives) REGISTER_NATIVES(coreNatives)
{ {
{"AutoExecConfig", AutoExecConfig}, {"AutoExecConfig", AutoExecConfig},
@ -438,5 +567,8 @@ REGISTER_NATIVES(coreNatives)
{"MarkNativeAsOptional", MarkNativeAsOptional}, {"MarkNativeAsOptional", MarkNativeAsOptional},
{"RegPluginLibrary", RegPluginLibrary}, {"RegPluginLibrary", RegPluginLibrary},
{"LibraryExists", LibraryExists}, {"LibraryExists", LibraryExists},
{"LogAction", sm_LogAction},
{"LogToFile", LogToFile},
{"LogToFileEx", LogToFileEx},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -69,8 +69,7 @@ public:
g_LibSys.CloseDirectory(pDir); g_LibSys.CloseDirectory(pDir);
} }
} }
}; } s_FileNatives;
static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params) static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
{ {
@ -503,6 +502,11 @@ static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params)
char buffer[1024]; char buffer[1024];
size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
return 0;
}
if (len >= sizeof(buffer)-2) if (len >= sizeof(buffer)-2)
{ {
buffer[1022] = '\n'; buffer[1022] = '\n';
@ -524,7 +528,12 @@ static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params)
char buffer[1024]; char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext()); if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
return 0;
}
CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer); g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer);
return 1; return 1;
@ -537,7 +546,12 @@ static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params)
char buffer[1024]; char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext()); if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
return 0;
}
CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer); g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer);
return 1; return 1;
@ -586,7 +600,66 @@ static cell_t sm_GetFileTime(IPluginContext *pContext, const cell_t *params)
return -1; return -1;
} }
static FileNatives s_FileNatives; static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
FILE *pFile;
sec.pOwner = NULL;
sec.pIdentity = g_pCoreIdent;
if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
return 0;
}
CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
g_Logger.LogToOpenFile(pFile, "[%s] %s", pPlugin->GetFilename(), buffer);
return 1;
}
static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
FILE *pFile;
sec.pOwner = NULL;
sec.pIdentity = g_pCoreIdent;
if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(LANG_SERVER);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetContext()->n_err != SP_ERROR_NONE)
{
return 0;
}
g_Logger.LogToOpenFile(pFile, "%s", buffer);
return 1;
}
REGISTER_NATIVES(filesystem) REGISTER_NATIVES(filesystem)
{ {
@ -610,5 +683,6 @@ REGISTER_NATIVES(filesystem)
{"LogError", sm_LogError}, {"LogError", sm_LogError},
{"FlushFile", sm_FlushFile}, {"FlushFile", sm_FlushFile},
{"GetFileTime", sm_GetFileTime}, {"GetFileTime", sm_GetFileTime},
{"LogToOpenFile", sm_LogToOpenFile},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -112,12 +112,12 @@ public Action:Command_SayChat(client, args)
if (msgStart == 1 && CheckAdminForChat(client)) // sm_say alias if (msgStart == 1 && CheckAdminForChat(client)) // sm_say alias
{ {
SendChatToAll(name, message); SendChatToAll(name, message);
LogMessage("%L triggered sm_say (text %s)", client, message); LogAction(client, -1, "%L triggered sm_say (text %s)", client, message);
} }
else if (msgStart == 3 && CheckAdminForChat(client)) // sm_csay alias else if (msgStart == 3 && CheckAdminForChat(client)) // sm_csay alias
{ {
PrintCenterTextAll("%s: %s", name, message); PrintCenterTextAll("%s: %s", name, message);
LogMessage("%L triggered sm_csay (text %s)", client, text); LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text);
} }
else if (msgStart == 2 && (CheckAdminForChat(client) || GetConVarBool(g_Cvar_Psaymode))) // sm_psay alias else if (msgStart == 2 && (CheckAdminForChat(client) || GetConVarBool(g_Cvar_Psaymode))) // sm_psay alias
{ {
@ -143,7 +143,7 @@ public Action:Command_SayChat(client, args)
PrintToChat(target, "(Private to %s) %s: %s", name2, name, message[len]); PrintToChat(target, "(Private to %s) %s: %s", name2, name, message[len]);
} }
LogMessage("%L triggered sm_psay to %L (text %s)", client, target, message); LogAction(client, -1, "%L triggered sm_psay to %L (text %s)", client, target, message);
} }
else else
return Plugin_Continue; return Plugin_Continue;
@ -176,7 +176,7 @@ public Action:Command_SayAdmin(client, args)
GetClientName(client, name, sizeof(name)); GetClientName(client, name, sizeof(name));
SendChatToAdmins(name, message); SendChatToAdmins(name, message);
LogMessage("%L triggered sm_chat (text %s)", client, message); LogAction(client, -1, "%L triggered sm_chat (text %s)", client, message);
return Plugin_Handled; return Plugin_Handled;
} }
@ -196,7 +196,7 @@ public Action:Command_SmSay(client, args)
GetClientName(client, name, sizeof(name)); GetClientName(client, name, sizeof(name));
SendChatToAll(name, text); SendChatToAll(name, text);
LogMessage("%L triggered sm_say (text %s)", client, text); LogAction(client, -1, "%L triggered sm_say (text %s)", client, text);
return Plugin_Handled; return Plugin_Handled;
} }
@ -216,7 +216,7 @@ public Action:Command_SmCsay(client, args)
GetClientName(client, name, sizeof(name)); GetClientName(client, name, sizeof(name));
PrintCenterTextAll("%s: %s", name, text); PrintCenterTextAll("%s: %s", name, text);
LogMessage("%L triggered sm_csay (text %s)", client, text); LogAction(client, -1, "%L triggered sm_csay (text %s)", client, text);
return Plugin_Handled; return Plugin_Handled;
} }
@ -236,7 +236,7 @@ public Action:Command_SmHsay(client, args)
GetClientName(client, name, sizeof(name)); GetClientName(client, name, sizeof(name));
PrintHintTextToAll("%s: %s", name, text); PrintHintTextToAll("%s: %s", name, text);
LogMessage("%L triggered sm_hsay (text %s)", client, text); LogAction(client, -1, "%L triggered sm_hsay (text %s)", client, text);
return Plugin_Handled; return Plugin_Handled;
} }
@ -264,7 +264,7 @@ public Action:Command_SmTsay(client, args)
else else
SendDialogToAll(color, "%s: %s", name, text[len]); SendDialogToAll(color, "%s: %s", name, text[len]);
LogMessage("%L triggered sm_tsay (text %s)", client, text); LogAction(client, -1, "%L triggered sm_tsay (text %s)", client, text);
return Plugin_Handled; return Plugin_Handled;
} }
@ -284,7 +284,7 @@ public Action:Command_SmChat(client, args)
GetClientName(client, name, sizeof(name)); GetClientName(client, name, sizeof(name));
SendChatToAdmins(name, text); SendChatToAdmins(name, text);
LogMessage("%L triggered sm_chat (text %s)", client, text); LogAction(client, -1, "%L triggered sm_chat (text %s)", client, text);
return Plugin_Handled; return Plugin_Handled;
} }
@ -323,7 +323,7 @@ public Action:Command_SmPsay(client, args)
PrintToChat(target, "(Private: %s) %s: %s", name2, name, message); PrintToChat(target, "(Private: %s) %s: %s", name2, name, message);
} }
LogMessage("%L triggered sm_psay to %L (text %s)", client, target, message); LogAction(client, -1, "%L triggered sm_psay to %L (text %s)", client, target, message);
return Plugin_Handled; return Plugin_Handled;
} }
@ -344,7 +344,7 @@ public Action:Command_SmMsay(client, args)
SendPanelToAll(name, text); SendPanelToAll(name, text);
LogMessage("%L triggered sm_msay (text %s)", client, text); LogAction(client, -1, "%L triggered sm_msay (text %s)", client, text);
return Plugin_Handled; return Plugin_Handled;
} }

View File

@ -76,7 +76,7 @@ public Action:Command_ReloadAdmins(client, args)
DumpAdminCache(AdminCache_Groups, true); DumpAdminCache(AdminCache_Groups, true);
DumpAdminCache(AdminCache_Overrides, true); DumpAdminCache(AdminCache_Overrides, true);
LogMessage("\"%L\" refreshed the admin cache.", client); LogAction(client, -1, "\"%L\" refreshed the admin cache.", client);
ReplyToCommand(client, "[SM] %t", "Admin cache refreshed"); ReplyToCommand(client, "[SM] %t", "Admin cache refreshed");
return Plugin_Handled; return Plugin_Handled;
@ -113,16 +113,16 @@ public Action:Command_BanIp(client, args)
has_rcon = (id == INVALID_ADMIN_ID) ? false : GetAdminFlag(id, Admin_RCON); has_rcon = (id == INVALID_ADMIN_ID) ? false : GetAdminFlag(id, Admin_RCON);
} }
new bool:hit_client = false; new hit_client = -1;
if (numClients == 1 if (numClients == 1
&& !IsFakeClient(clients[0]) && !IsFakeClient(clients[0])
&& (has_rcon || CanUserTarget(client, clients[0]))) && (has_rcon || CanUserTarget(client, clients[0])))
{ {
GetClientIP(clients[0], arg, sizeof(arg)); GetClientIP(clients[0], arg, sizeof(arg));
hit_client = true; hit_client = clients[0];
} }
if (!hit_client && !has_rcon) if (hit_client == -1 && !has_rcon)
{ {
ReplyToCommand(client, "[SM] %t", "No Access"); ReplyToCommand(client, "[SM] %t", "No Access");
return Plugin_Handled; return Plugin_Handled;
@ -146,7 +146,7 @@ public Action:Command_BanIp(client, args)
if (act < Plugin_Handled) if (act < Plugin_Handled)
{ {
LogMessage("\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")", client, minutes, arg, reason); LogAction(client, hit_client, "\"%L\" added ban (minutes \"%d\") (ip \"%s\") (reason \"%s\")", client, minutes, arg, reason);
ReplyToCommand(client, "[SM] %t", "Ban added"); ReplyToCommand(client, "[SM] %t", "Ban added");
} }
@ -189,7 +189,7 @@ public Action:Command_AddBan(client, args)
if (act < Plugin_Handled) if (act < Plugin_Handled)
{ {
LogMessage("\"%L\" added ban (minutes \"%d\") (id \"%s\") (reason \"%s\")", client, minutes, arg, reason); LogAction(client, -1, "\"%L\" added ban (minutes \"%d\") (id \"%s\") (reason \"%s\")", client, minutes, arg, reason);
ReplyToCommand(client, "[SM] %t", "Ban added"); ReplyToCommand(client, "[SM] %t", "Ban added");
} }
@ -243,7 +243,7 @@ public Action:Command_Unban(client, args)
if (act < Plugin_Handled) if (act < Plugin_Handled)
{ {
LogMessage("\"%L\" removed ban (filter \"%s\")", client, new_arg); LogAction(client, -1, "\"%L\" removed ban (filter \"%s\")", client, new_arg);
ReplyToCommand(client, "[SM] %t", "Removed bans matching", new_arg); ReplyToCommand(client, "[SM] %t", "Removed bans matching", new_arg);
} }
@ -317,7 +317,7 @@ public Action:Command_Ban(client, args)
ShowActivity(client, "%t", "Banned player reason", arg, time, reason); ShowActivity(client, "%t", "Banned player reason", arg, time, reason);
} }
} }
LogMessage("\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason); LogAction(client, target, "\"%L\" banned \"%L\" (minutes \"%d\") (reason \"%s\")", client, target, time, reason);
} }
if (act < Plugin_Stop) if (act < Plugin_Stop)
@ -491,7 +491,7 @@ public Action:Command_ExecCfg(client, args)
ShowActivity(client, "%t", "Executed config", path[4]); ShowActivity(client, "%t", "Executed config", path[4]);
LogMessage("\"%L\" executed config (file \"%s\")", client, path[4]); LogAction(client, -1, "\"%L\" executed config (file \"%s\")", client, path[4]);
ServerCommand("exec \"%s\"", path[4]); ServerCommand("exec \"%s\"", path[4]);
@ -569,7 +569,7 @@ public Action:Command_Cvar(client, args)
ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value); ReplyToCommand(client, "[SM] %t", "Cvar changed", cvarname, value);
} }
LogMessage("\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value); LogAction(client, -1, "\"%L\" changed cvar (cvar \"%s\") (value \"%s\")", client, cvarname, value);
SetConVarString(hndl, value, true); SetConVarString(hndl, value, true);
@ -587,7 +587,7 @@ public Action:Command_Rcon(client, args)
decl String:argstring[255]; decl String:argstring[255];
GetCmdArgString(argstring, sizeof(argstring)); GetCmdArgString(argstring, sizeof(argstring));
LogMessage("\"%L\" console command (cmdline \"%s\")", client, argstring); LogAction(client, -1, "\"%L\" console command (cmdline \"%s\")", client, argstring);
ServerCommand("%s", argstring); ServerCommand("%s", argstring);
@ -613,7 +613,7 @@ public Action:Command_Map(client, args)
ShowActivity(client, "%t", "Changing map", map); ShowActivity(client, "%t", "Changing map", map);
LogMessage("\"%L\" changed map to \"%s\"", client, map); LogAction(client, -1, "\"%L\" changed map to \"%s\"", client, map);
new Handle:dp; new Handle:dp;
CreateDataTimer(3.0, Timer_ChangeMap, dp); CreateDataTimer(3.0, Timer_ChangeMap, dp);
@ -665,7 +665,7 @@ public Action:Command_Kick(client, args)
} }
ShowActivity(client, "%t", "Kicked player", arg); ShowActivity(client, "%t", "Kicked player", arg);
LogMessage("\"%L\" kicked \"%L\" (reason \"%s\")", client, target, Arguments[len]); LogAction(client, target, "\"%L\" kicked \"%L\" (reason \"%s\")", client, target, Arguments[len]);
KickClient(target, "%s", Arguments[len]); KickClient(target, "%s", Arguments[len]);

View File

@ -95,7 +95,7 @@ public Action:Command_Play(client, args)
GetClientName(target, Arg, sizeof(Arg)); GetClientName(target, Arg, sizeof(Arg));
ShowActivity(client, "%t", "Played Sound", Arg); ShowActivity(client, "%t", "Played Sound", Arg);
LogMessage("\"%L\" played sound on \"%L\" (file \"%s\")", client, target, Arguments[len]); LogAction(client, target, "\"%L\" played sound on \"%L\" (file \"%s\")", client, target, Arguments[len]);
ClientCommand(target, "playgamesound \"%s\"", Arguments[len]); ClientCommand(target, "playgamesound \"%s\"", Arguments[len]);
@ -140,7 +140,7 @@ public Action:Command_Burn(client, args)
} }
ShowActivity(client, "%t", "Ignited player", arg); ShowActivity(client, "%t", "Ignited player", arg);
LogMessage("\"%L\" ignited \"%L\" (seconds \"%f\")", client, target, seconds); LogAction(client, target, "\"%L\" ignited \"%L\" (seconds \"%f\")", client, target, seconds);
IgniteEntity(target, seconds); IgniteEntity(target, seconds);
return Plugin_Handled; return Plugin_Handled;
@ -184,7 +184,7 @@ public Action:Command_Slap(client, args)
} }
ShowActivity(client, "%t", "Slapped player", arg); ShowActivity(client, "%t", "Slapped player", arg);
LogMessage("\"%L\" slapped \"%L\" (damage \"%d\")", client, target, damage); LogAction(client, target, "\"%L\" slapped \"%L\" (damage \"%d\")", client, target, damage);
SlapPlayer(target, damage, true); SlapPlayer(target, damage, true);
return Plugin_Handled; return Plugin_Handled;
@ -216,7 +216,7 @@ public Action:Command_Slay(client, args)
} }
ShowActivity(client, "%t", "Slayed player", arg); ShowActivity(client, "%t", "Slayed player", arg);
LogMessage("\"%L\" slayed \"%L\"", client, target); LogAction(client, target, "\"%L\" slayed \"%L\"", client, target);
ForcePlayerSuicide(target); ForcePlayerSuicide(target);
return Plugin_Handled; return Plugin_Handled;

View File

@ -156,6 +156,7 @@ public Action:Command_VoteGravity(client, args)
} }
} }
LogAction(client, -1, "\"%L\" initiated a gravity vote.", client);
ShowActivity(client, "%t", "Initiated Vote Gravity"); ShowActivity(client, "%t", "Initiated Vote Gravity");
g_voteType = voteType:gravity; g_voteType = voteType:gravity;
@ -226,6 +227,7 @@ public Action:Command_VoteBurn(client, args)
g_voteClient[VOTE_CLIENTID] = target; g_voteClient[VOTE_CLIENTID] = target;
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[])); GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
LogAction(client, target, "\"%L\" initiated a burn vote against \"%L\"", client, target);
ShowActivity(client, "%t", "Initiated Vote Burn", g_voteInfo[VOTE_NAME]); ShowActivity(client, "%t", "Initiated Vote Burn", g_voteInfo[VOTE_NAME]);
g_voteType = voteType:burn; g_voteType = voteType:burn;
@ -279,6 +281,7 @@ public Action:Command_VoteSlay(client, args)
g_voteClient[VOTE_CLIENTID] = target; g_voteClient[VOTE_CLIENTID] = target;
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[])); GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
LogAction(client, target, "\"%L\" initiated a slay vote against \"%L\"", client, target);
ShowActivity(client, "%t", "Initiated Vote Slay", g_voteInfo[VOTE_NAME]); ShowActivity(client, "%t", "Initiated Vote Slay", g_voteInfo[VOTE_NAME]);
g_voteType = voteType:slay; g_voteType = voteType:slay;
@ -312,6 +315,7 @@ public Action:Command_VoteAlltalk(client, args)
return Plugin_Handled; return Plugin_Handled;
} }
LogAction(client, -1, "\"%L\" initiated an alltalk vote.", client);
ShowActivity(client, "%t", "Initiated Vote Alltalk"); ShowActivity(client, "%t", "Initiated Vote Alltalk");
g_voteType = voteType:alltalk; g_voteType = voteType:alltalk;
@ -355,6 +359,7 @@ public Action:Command_VoteFF(client, args)
return Plugin_Handled; return Plugin_Handled;
} }
LogAction(client, -1, "\"%L\" initiated a friendly fire vote.", client);
ShowActivity(client, "%t", "Initiated Vote FF"); ShowActivity(client, "%t", "Initiated Vote FF");
g_voteType = voteType:ff; g_voteType = voteType:ff;
@ -434,10 +439,15 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
limit = GetConVarFloat(g_Cvar_Limits[g_voteType]); limit = GetConVarFloat(g_Cvar_Limits[g_voteType]);
/* :TODO: g_voteClient[userid] needs to be checked.
*/
// A multi-argument vote is "always successful", but have to check if its a Yes/No vote. // A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1)) if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
{ {
LogMessage("Vote failed."); /* :TODO: g_voteClient[userid] should be used here and set to -1 if not applicable.
*/
LogAction(-1, -1, "Vote failed.");
PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes); PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes);
} }
else else
@ -449,14 +459,14 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
case (voteType:gravity): case (voteType:gravity):
{ {
PrintToChatAll("[SM] %t", "Cvar changed", "sv_gravity", item); PrintToChatAll("[SM] %t", "Cvar changed", "sv_gravity", item);
LogMessage("Changing gravity to %s due to vote.", item); LogAction(-1, -1, "Changing gravity to %s due to vote.", item);
SetConVarInt(g_Cvar_Gravity, StringToInt(item)); SetConVarInt(g_Cvar_Gravity, StringToInt(item));
} }
case (voteType:burn): case (voteType:burn):
{ {
PrintToChatAll("[SM] %t", "Ignited player", g_voteInfo[VOTE_NAME]); PrintToChatAll("[SM] %t", "Ignited player", g_voteInfo[VOTE_NAME]);
LogMessage("Vote burn successful, igniting \"%L\"", g_voteClient[VOTE_CLIENTID]); LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote burn successful, igniting \"%L\"", g_voteClient[VOTE_CLIENTID]);
IgniteEntity(g_voteClient[VOTE_CLIENTID], 19.8); IgniteEntity(g_voteClient[VOTE_CLIENTID], 19.8);
} }
@ -464,7 +474,7 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
case (voteType:slay): case (voteType:slay):
{ {
PrintToChatAll("[SM] %t", "Slayed player", g_voteInfo[VOTE_NAME]); PrintToChatAll("[SM] %t", "Slayed player", g_voteInfo[VOTE_NAME]);
LogMessage("Vote slay successful, slaying \"%L\"", g_voteClient[VOTE_CLIENTID]); LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote slay successful, slaying \"%L\"", g_voteClient[VOTE_CLIENTID]);
ExtinguishEntity(g_voteClient[VOTE_CLIENTID]); ExtinguishEntity(g_voteClient[VOTE_CLIENTID]);
ForcePlayerSuicide(g_voteClient[VOTE_CLIENTID]); ForcePlayerSuicide(g_voteClient[VOTE_CLIENTID]);
@ -473,14 +483,14 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
case (voteType:alltalk): case (voteType:alltalk):
{ {
PrintToChatAll("[SM] %t", "Cvar changed", "sv_alltalk", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1")); PrintToChatAll("[SM] %t", "Cvar changed", "sv_alltalk", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1"));
LogMessage("Changing alltalk to %s due to vote.", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1")); LogAction(-1, -1, "Changing alltalk to %s due to vote.", (GetConVarBool(g_Cvar_Alltalk) ? "0" : "1"));
SetConVarBool(g_Cvar_Alltalk, !GetConVarBool(g_Cvar_Alltalk)); SetConVarBool(g_Cvar_Alltalk, !GetConVarBool(g_Cvar_Alltalk));
} }
case (voteType:ff): case (voteType:ff):
{ {
PrintToChatAll("[SM] %t", "Cvar changed", "mp_friendlyfire", (GetConVarBool(g_Cvar_FF) ? "0" : "1")); PrintToChatAll("[SM] %t", "Cvar changed", "mp_friendlyfire", (GetConVarBool(g_Cvar_FF) ? "0" : "1"));
LogMessage("Changing friendly fire to %s due to vote.", (GetConVarBool(g_Cvar_FF) ? "0" : "1")); LogAction(-1, -1, "Changing friendly fire to %s due to vote.", (GetConVarBool(g_Cvar_FF) ? "0" : "1"));
SetConVarBool(g_Cvar_FF, !GetConVarBool(g_Cvar_FF)); SetConVarBool(g_Cvar_FF, !GetConVarBool(g_Cvar_FF));
} }
} }

View File

@ -148,6 +148,7 @@ public Action:Command_Votemap(client, args)
} }
} }
LogAction(client, -1, "\"%L\" initiated a map vote.", client);
ShowActivity(client, "%t", "Initiated Vote Map"); ShowActivity(client, "%t", "Initiated Vote Map");
g_voteType = voteType:map; g_voteType = voteType:map;
@ -217,6 +218,7 @@ public Action:Command_Vote(client, args)
} }
} }
LogAction(client, -1, "\"%L\" initiated a generic vote.", client);
ShowActivity(client, "%t", "Initiate Vote", g_voteArg); ShowActivity(client, "%t", "Initiate Vote", g_voteArg);
g_voteType = voteType:question; g_voteType = voteType:question;
@ -287,6 +289,7 @@ public Action:Command_Votekick(client, args)
GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[])); GetClientName(target, g_voteInfo[VOTE_NAME], sizeof(g_voteInfo[]));
LogAction(client, target, "\"%L\" initiated a kick vote against \"%L\"", client, target);
ShowActivity(client, "%t", "Initiated Vote Kick", g_voteInfo[VOTE_NAME]); ShowActivity(client, "%t", "Initiated Vote Kick", g_voteInfo[VOTE_NAME]);
g_voteType = voteType:kick; g_voteType = voteType:kick;
@ -347,6 +350,7 @@ public Action:Command_Voteban(client, args)
GetClientAuthString(target, g_voteInfo[VOTE_AUTHID], sizeof(g_voteInfo[])); GetClientAuthString(target, g_voteInfo[VOTE_AUTHID], sizeof(g_voteInfo[]));
GetClientIP(target, g_voteInfo[VOTE_IP], sizeof(g_voteInfo[])); GetClientIP(target, g_voteInfo[VOTE_IP], sizeof(g_voteInfo[]));
LogAction(client, target, "\"%L\" initiated a ban vote against \"%L\"", client, target);
ShowActivity(client, "%t", "Initiated Vote Ban", g_voteInfo[VOTE_NAME]); ShowActivity(client, "%t", "Initiated Vote Ban", g_voteInfo[VOTE_NAME]);
g_voteType = voteType:ban; g_voteType = voteType:ban;
@ -422,10 +426,14 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
limit = GetConVarFloat(g_Cvar_Limits[g_voteType]); limit = GetConVarFloat(g_Cvar_Limits[g_voteType]);
} }
/* :TODO: g_voteClient[userid] needs to be checked */
// A multi-argument vote is "always successful", but have to check if its a Yes/No vote. // A multi-argument vote is "always successful", but have to check if its a Yes/No vote.
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1)) if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent,limit) < 0 && param1 == 0) || (strcmp(item, VOTE_NO) == 0 && param1 == 1))
{ {
LogMessage("Vote failed."); /* :TODO: g_voteClient[userid] should be used here and set to -1 if not applicable.
*/
LogAction(-1, -1, "Vote failed.");
PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes); PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0*limit), RoundToNearest(100.0*percent), totalVotes);
} }
else else
@ -446,7 +454,7 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
case (voteType:map): case (voteType:map):
{ {
LogMessage("Changing map to %s due to vote.", item); LogAction(-1, -1, "Changing map to %s due to vote.", item);
PrintToChatAll("[SM] %t", "Changing map", item); PrintToChatAll("[SM] %t", "Changing map", item);
new Handle:dp; new Handle:dp;
CreateDataTimer(5.0, Timer_ChangeMap, dp); CreateDataTimer(5.0, Timer_ChangeMap, dp);
@ -461,7 +469,7 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
} }
PrintToChatAll("[SM] %t", "Kicked player", g_voteInfo[VOTE_NAME]); PrintToChatAll("[SM] %t", "Kicked player", g_voteInfo[VOTE_NAME]);
LogMessage("Vote kick successful, kicked \"%L\" (reason \"%s\")", g_voteClient[VOTE_CLIENTID], g_voteArg); LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote kick successful, kicked \"%L\" (reason \"%s\")", g_voteClient[VOTE_CLIENTID], g_voteArg);
ServerCommand("kickid %d \"%s\"", g_voteClient[VOTE_USERID], g_voteArg); ServerCommand("kickid %d \"%s\"", g_voteClient[VOTE_USERID], g_voteArg);
} }
@ -482,7 +490,7 @@ public Handler_VoteCallback(Handle:menu, MenuAction:action, param1, param2)
} }
PrintToChatAll("[SM] %t", "Banned player", g_voteInfo[VOTE_NAME], 30); PrintToChatAll("[SM] %t", "Banned player", g_voteInfo[VOTE_NAME], 30);
LogMessage("Vote ban successful, banned \"%L\" (minutes \"30\") (reason \"%s\")", g_voteClient[VOTE_CLIENTID], g_voteArg); LogAction(-1, g_voteClient[VOTE_CLIENTID], "Vote ban successful, banned \"%L\" (minutes \"30\") (reason \"%s\")", g_voteClient[VOTE_CLIENTID], g_voteArg);
ServerCommand("banid %d %s", 30, g_voteClient[VOTE_AUTHID]); ServerCommand("banid %d %s", 30, g_voteClient[VOTE_AUTHID]);
ServerCommand("kickid %d \"%s\"", g_voteClient[VOTE_USERID], g_voteArg); ServerCommand("kickid %d \"%s\"", g_voteClient[VOTE_USERID], g_voteArg);

View File

@ -62,6 +62,16 @@ enum Action
Plugin_Stop = 4, /**< Immediately stop the hook chain and handle the original */ Plugin_Stop = 4, /**< Immediately stop the hook chain and handle the original */
}; };
/**
* Specifies identity types.
*/
enum Identity
{
Identity_Core = 0,
Identity_Extension = 1,
Identity_Plugin = 2
};
public PlVers:__version = public PlVers:__version =
{ {
version = SOURCEMOD_PLUGINAPI_VERSION, version = SOURCEMOD_PLUGINAPI_VERSION,

View File

@ -232,3 +232,28 @@ native bool:WriteFileLine(Handle:hndl, const String:format[], any:...);
* @return Time value, or -1 on failure. * @return Time value, or -1 on failure.
*/ */
native GetFileTime(const String:file[], FileTimeMode:tmode); native GetFileTime(const String:file[], FileTimeMode:tmode);
/**
* Same as LogToFile(), except uses an open file Handle. The file must
* be opened in text appending mode.
*
* @param hndl Handle to the file.
* @param message Message format.
* @param ... Message format parameters.
* @noreturn
* @error Invalid Handle.
*/
native LogToOpenFile(Handle:hndl, const String:message[], any:...);
/**
* Same as LogToFileEx(), except uses an open file Handle. The file must
* be opened in text appending mode.
*
* @param hndl Handle to the file.
* @param message Message format.
* @param ... Message format parameters.
* @noreturn
* @error Invalid Handle.
*/
native LogToOpenFileEx(Handle:hndl, const String:message[], any:...);

View File

@ -166,6 +166,26 @@ forward OnServerCfg();
*/ */
forward OnAllPluginsLoaded(); forward OnAllPluginsLoaded();
/**
* Called when an action is going to be logged.
*
* @param source Handle to the object logging the action, or INVALID_HANDLE
* if Core is logging the action.
* @param ident Type of object logging the action (plugin, ext, or core).
* @param client Client the action is from; 0 for server, -1 if not applicable.
* @param target Client the action is targetting, or -1 if not applicable.
* @param message Message that is being logged.
* @return Plugin_Continue will cause Core to defaulty log the message.
* Plugin_Handled will stop Core from logging the message.
* Plugin_Stop is the same as Handled, but prevents any other
* plugins from handling the message.
*/
forward Action:OnLogAction(Handle:source,
Identity:ident,
client,
target,
const String:message[]);
/** /**
* Returns the calling plugin's Handle. * Returns the calling plugin's Handle.
* *
@ -264,7 +284,8 @@ native SetFailState(const String:string[]);
native ThrowError(const String:fmt[], any:...); native ThrowError(const String:fmt[], any:...);
/** /**
* Logs a plugin message to the SourceMod logs. * Logs a plugin message to the SourceMod logs. The log message will be
* prefixed by the plugin's logtag (filename).
* *
* @param format String format. * @param format String format.
* @param ... Format arguments. * @param ... Format arguments.
@ -272,6 +293,53 @@ native ThrowError(const String:fmt[], any:...);
*/ */
native LogMessage(const String:format[], any:...); native LogMessage(const String:format[], any:...);
/**
* Logs a message to the SourceMod logs without any plugin logtag. This is
* useful for re-routing messages from other plugins, for example, messages
* from LogAction().
*
* @param format String format.
* @param ... Format arguments.
* @noreturn
*/
native LogMessageEx(const String:format[], any:...);
/**
* Logs a message to any file. The log message will be in the normal
* SourceMod format, with the plugin logtag prepended.
*
* @param file File to write the log message in.
* @param format String format.
* @param ... Format arguments.
* @noreturn
* @error File could not be opened/written.
*/
native LogToFile(const String:file[], const String:format[], any:...);
/**
* Same as LogToFile(), except no plugin logtag is prepended.
*
* @param file File to write the log message in.
* @param format String format.
* @param ... Format arguments.
* @noreturn
* @error File could not be opened/written.
*/
native LogToFileEx(const String:file[], const String:format[], any:...);
/**
* Logs an action from a command or event whereby interception and routing may
* be important. This is intended to be a logging version of ShowActivity().
*
* @param client Client performing the action, 0 for server, or -1 if not
* applicable.
* @param target Client being targetted, or -1 if not applicable.
* @param message Message format.
* @param ... Message formatting parameters.
* @noreturn
*/
native LogAction(client, target, const String:message[], any:...);
/** /**
* Logs a plugin error message to the SourceMod logs. * Logs a plugin error message to the SourceMod logs.
* *