changed the API around a bit to be more flexible
removed some ghastly unneeded stuff from the Translator added Logger::LogFatal, experimental --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40669
This commit is contained in:
parent
3b9c8e1410
commit
f93711bd82
@ -22,7 +22,7 @@
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file");
|
||||
#else
|
||||
#elif defined PLATFORM_LINUX
|
||||
ConVar sm_corecfgfile("sm_corecfgfile", "addons/sourcemod/configs/core.cfg", 0, "SourceMod core configuration file");
|
||||
#endif
|
||||
|
||||
@ -45,21 +45,13 @@ void CoreConfig::OnRootConsoleCommand(const char *command, unsigned int argcount
|
||||
const char *option = engine->Cmd_Argv(2);
|
||||
const char *value = engine->Cmd_Argv(3);
|
||||
|
||||
CoreConfigErr err = SetConfigOption(option, value);
|
||||
char error[255];
|
||||
|
||||
switch (err)
|
||||
ConfigResult err = SetConfigOption(option, value, ConfigSource_Console, error, sizeof(error));
|
||||
|
||||
if (err == ConfigResult_Reject)
|
||||
{
|
||||
case CoreConfig_NoRuntime:
|
||||
g_RootMenu.ConsolePrint("[SM] Cannot set \"%s\" while SourceMod is running.", option);
|
||||
break;
|
||||
case CoreConfig_InvalidValue:
|
||||
g_RootMenu.ConsolePrint("[SM] Invalid value \"%s\" specified for configuration option \"%s\"", value, option);
|
||||
break;
|
||||
case CoreConfig_InvalidOption:
|
||||
g_RootMenu.ConsolePrint("[SM] Invalid configuration option specified: %s", option);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
g_Logger.LogError("Could not set config option \"%s\" to \"%s\" (error: %s)", option, value, error);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -90,44 +82,39 @@ void CoreConfig::Initialize()
|
||||
!= SMCParse_Okay)
|
||||
{
|
||||
/* :TODO: This won't actually log or print anything :( - So fix that somehow */
|
||||
g_Logger.LogError("[SM] Error encountered parsing core config file: %s", g_TextParser.GetSMCErrorString(err));
|
||||
const char *error = g_TextParser.GetSMCErrorString(err);
|
||||
g_Logger.LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : "");
|
||||
}
|
||||
}
|
||||
|
||||
SMCParseResult CoreConfig::ReadSMC_KeyValue(const char *key, const char *value, bool key_quotes, bool value_quotes)
|
||||
{
|
||||
CoreConfigErr err = SetConfigOption(key, value);
|
||||
char error[255];
|
||||
ConfigResult err = SetConfigOption(key, value, ConfigSource_File, error, sizeof(error));
|
||||
|
||||
if (err == CoreConfig_InvalidOption)
|
||||
if (err == ConfigResult_Reject)
|
||||
{
|
||||
g_Logger.LogError("[SM] Warning: Ignoring invalid option \"%s\" in configuration file.", key);
|
||||
} else if (err == CoreConfig_InvalidValue) {
|
||||
g_Logger.LogError("[SM] Warning encountered parsing core configuration file.");
|
||||
g_Logger.LogError("[SM] Invalid value \"%s\" specified for option \"%s\"", value, key);
|
||||
/* This is a fatal error */
|
||||
g_Logger.LogFatal("%s", error);
|
||||
}
|
||||
|
||||
return SMCParse_Continue;
|
||||
}
|
||||
|
||||
CoreConfigErr CoreConfig::SetConfigOption(const char *option, const char *value)
|
||||
ConfigResult CoreConfig::SetConfigOption(const char *option, const char *value, ConfigSource source, char *error, size_t maxlength)
|
||||
{
|
||||
CoreConfigErr err = CoreConfig_TOTAL;
|
||||
CoreConfigErr currentErr;
|
||||
ConfigResult result;
|
||||
|
||||
/* Notify! */
|
||||
SMGlobalClass *pBase = SMGlobalClass::head;
|
||||
while (pBase)
|
||||
{
|
||||
currentErr = pBase->OnSourceModConfigChanged(option, value);
|
||||
|
||||
/* Lowest error code has priority */
|
||||
if (currentErr < err)
|
||||
if ((result = pBase->OnSourceModConfigChanged(option, value, source, error, maxlength)) != ConfigResult_Ignore)
|
||||
{
|
||||
err = currentErr;
|
||||
return result;
|
||||
}
|
||||
|
||||
pBase = pBase->m_pGlobalClassNext;
|
||||
}
|
||||
|
||||
return err;
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ private:
|
||||
/**
|
||||
* Sets configuration option by notifying SourceMod components that rely on core.cfg
|
||||
*/
|
||||
CoreConfigErr SetConfigOption(const char *option, const char *value);
|
||||
ConfigResult SetConfigOption(const char *option, const char *value, ConfigSource, char *Error, size_t maxlength);
|
||||
};
|
||||
|
||||
extern CoreConfig g_CoreConfig;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <time.h>
|
||||
#include "sourcemod.h"
|
||||
#include "sourcemm_api.h"
|
||||
#include "sm_stringutil.h"
|
||||
#include "Logger.h"
|
||||
#include "systems/LibrarySys.h"
|
||||
#include "sm_version.h"
|
||||
@ -25,31 +26,39 @@ Logger g_Logger;
|
||||
* :TODO: This should be creating the log folder if it doesn't exist
|
||||
*/
|
||||
|
||||
CoreConfigErr Logger::OnSourceModConfigChanged(const char *option, const char *value)
|
||||
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
if (strcasecmp(option, "Logging") == 0)
|
||||
if (strcasecmp(key, "Logging") == 0)
|
||||
{
|
||||
bool state = true;
|
||||
|
||||
if (strcasecmp(value, "on") == 0)
|
||||
{
|
||||
state = true;
|
||||
} else if (strcasecmp(value, "off") == 0) {
|
||||
state = false;
|
||||
} else {
|
||||
return CoreConfig_InvalidValue;
|
||||
UTIL_Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
if (m_FirstPass)
|
||||
if (source == ConfigSource_Console)
|
||||
{
|
||||
m_InitialState = state;
|
||||
m_FirstPass = false;
|
||||
if (state && !m_Active)
|
||||
{
|
||||
EnableLogging();
|
||||
} else if (!state && m_Active) {
|
||||
DisableLogging();
|
||||
}
|
||||
} else {
|
||||
state ? g_Logger.EnableLogging() : g_Logger.DisableLogging();
|
||||
m_InitialState = state;
|
||||
}
|
||||
|
||||
return CoreConfig_Okay;
|
||||
} else if (strcasecmp(option, "LogMode") == 0) {
|
||||
return ConfigResult_Accept;
|
||||
} else if (strcasecmp(key, "LogMode") == 0) {
|
||||
if (strcasecmp(value, "daily") == 0)
|
||||
{
|
||||
m_Mode = LoggingMode_Daily;
|
||||
@ -58,18 +67,19 @@ CoreConfigErr Logger::OnSourceModConfigChanged(const char *option, const char *v
|
||||
} else if (strcasecmp(value, "game") == 0) {
|
||||
m_Mode = LoggingMode_Game;
|
||||
} else {
|
||||
return CoreConfig_InvalidValue;
|
||||
UTIL_Format(error, maxlength, "Invalid value: must be [daily|map|game]");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
return CoreConfig_Okay;
|
||||
return ConfigResult_Accept;
|
||||
}
|
||||
|
||||
return CoreConfig_InvalidOption;
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
|
||||
void Logger::OnSourceModStartup(bool late)
|
||||
{
|
||||
InitLogger(m_Mode, m_InitialState);
|
||||
InitLogger(m_Mode);
|
||||
}
|
||||
|
||||
void Logger::OnSourceModAllShutdown()
|
||||
@ -155,10 +165,10 @@ void Logger::_CloseFile()
|
||||
m_ErrFileName.clear();
|
||||
}
|
||||
|
||||
void Logger::InitLogger(LoggingMode mode, bool startlogging)
|
||||
void Logger::InitLogger(LoggingMode mode)
|
||||
{
|
||||
m_Mode = mode;
|
||||
m_Active = startlogging;
|
||||
m_Active = m_InitialState;
|
||||
|
||||
time_t t;
|
||||
time(&t);
|
||||
@ -173,7 +183,7 @@ void Logger::InitLogger(LoggingMode mode, bool startlogging)
|
||||
{
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
if (!startlogging)
|
||||
if (!m_Active)
|
||||
{
|
||||
m_DelayedStart = true;
|
||||
}
|
||||
@ -414,3 +424,24 @@ void Logger::DisableLogging()
|
||||
LogMessage("Logging disabled manually by user.");
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
void Logger::LogFatal(const char *msg, ...)
|
||||
{
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
|
||||
FILE *fp = fopen(path, "at");
|
||||
if (!fp)
|
||||
{
|
||||
/* We're just doomed, aren't we... */
|
||||
return;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
vfprintf(fp, msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
fputs("\n", fp);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
@ -36,18 +36,27 @@ enum LoggingMode
|
||||
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), m_FirstPass(true) {}
|
||||
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
|
||||
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
|
||||
m_InitialState(true)
|
||||
{
|
||||
}
|
||||
public: //SMGlobalClass
|
||||
CoreConfigErr OnSourceModConfigChanged(const char *option, const char *value);
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength);
|
||||
void OnSourceModStartup(bool late);
|
||||
void OnSourceModAllShutdown();
|
||||
public:
|
||||
void InitLogger(LoggingMode mode, bool startlogging);
|
||||
void InitLogger(LoggingMode mode);
|
||||
void CloseLogger();
|
||||
void EnableLogging();
|
||||
void DisableLogging();
|
||||
void LogMessage(const char *msg, ...);
|
||||
void LogError(const char *msg, ...);
|
||||
void LogFatal(const char *msg, ...);
|
||||
void MapChange(const char *mapname);
|
||||
const char *GetLogFileName(LogType type) const;
|
||||
LoggingMode GetLoggingMode() const;
|
||||
@ -66,7 +75,6 @@ private:
|
||||
bool m_DelayedStart;
|
||||
bool m_DailyPrintHdr;
|
||||
bool m_InitialState;
|
||||
bool m_FirstPass;
|
||||
};
|
||||
|
||||
extern Logger g_Logger;
|
||||
|
@ -604,15 +604,30 @@ Translator::~Translator()
|
||||
delete m_pStringTab;
|
||||
}
|
||||
|
||||
CoreConfigErr Translator::OnSourceModConfigChanged(const char *option, const char *value)
|
||||
ConfigResult Translator::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
if (strcasecmp(option, "ServerLang") == 0)
|
||||
if (strcasecmp(value, "ServerLang") == 0)
|
||||
{
|
||||
if (source == ConfigSource_Console)
|
||||
{
|
||||
unsigned int index;
|
||||
if (!GetLanguageByCode(value, &index))
|
||||
{
|
||||
UTIL_Format(error, maxlength, "Language code \"%s\" is not registered", value);
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
}
|
||||
|
||||
strncopy(m_ServerLangCode, value, sizeof(m_ServerLangCode));
|
||||
return CoreConfig_Okay;
|
||||
|
||||
return ConfigResult_Accept;
|
||||
}
|
||||
|
||||
return CoreConfig_InvalidOption;
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
|
||||
void Translator::OnSourceModAllInitialized()
|
||||
@ -837,7 +852,20 @@ TransError Translator::CoreTrans(int client,
|
||||
return Trans_Okay;
|
||||
}
|
||||
|
||||
const char *Translator::GetServerLanguageCode() const
|
||||
unsigned int Translator::GetServerLanguageCode()
|
||||
{
|
||||
return m_ServerLangCode;
|
||||
void *serverLang;
|
||||
|
||||
/* :TODO: there is absolutely no reason this shouldn't be cached
|
||||
* I don't even know why it was returning a string originally
|
||||
*/
|
||||
|
||||
if (!sm_trie_retrieve(m_pLCodeLookup, m_ServerLangCode, &serverLang))
|
||||
{
|
||||
g_Logger.LogError("Server language was set to bad language \"%s\" -- reverting to English");
|
||||
strncopy(m_ServerLangCode, "en", sizeof(m_ServerLangCode));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (unsigned int)serverLang;
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ struct Translation
|
||||
int *fmt_order; /**< Format phrase order. */
|
||||
};
|
||||
|
||||
#define LANGUAGE_ENGLISH 0
|
||||
|
||||
enum TransError
|
||||
{
|
||||
Trans_Okay = 0,
|
||||
@ -100,7 +102,11 @@ public:
|
||||
Translator();
|
||||
~Translator();
|
||||
public: // SMGlobalClass
|
||||
CoreConfigErr OnSourceModConfigChanged(const char *option, const char *value);
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength);
|
||||
void OnSourceModAllInitialized();
|
||||
public: // ITextListener_SMC
|
||||
void ReadSMC_ParseStart();
|
||||
@ -121,7 +127,7 @@ public:
|
||||
const char *phrase,
|
||||
void **params,
|
||||
size_t *outlen=NULL);
|
||||
const char *GetServerLanguageCode() const;
|
||||
unsigned int GetServerLanguageCode();
|
||||
private:
|
||||
bool AddLanguage(const char *langcode, const char *description);
|
||||
private:
|
||||
|
@ -28,16 +28,19 @@ using namespace SourcePawn;
|
||||
using namespace SourceMod;
|
||||
|
||||
/**
|
||||
* @brief Lists error codes possible from attempting to set a core configuration option.
|
||||
*/
|
||||
enum CoreConfigErr
|
||||
* @brief Lists error codes possible from attempting to set a core configuration option.
|
||||
*/
|
||||
enum ConfigResult
|
||||
{
|
||||
CoreConfig_Okay = 0, /**< No error */
|
||||
CoreConfig_NoRuntime = 1, /**< Cannot set config option while SourceMod is running */
|
||||
CoreConfig_InvalidValue = 2, /**< Invalid value specified for config option */
|
||||
CoreConfig_InvalidOption = 3, /**< Invalid config option specified */
|
||||
/* -------------------- */
|
||||
CoreConfig_TOTAL /**< Total number of core config error codes */
|
||||
ConfigResult_Accept = 0,
|
||||
ConfigResult_Reject = 1,
|
||||
ConfigResult_Ignore = 2
|
||||
};
|
||||
|
||||
enum ConfigSource
|
||||
{
|
||||
ConfigSource_File = 0,
|
||||
ConfigSource_Console = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -83,9 +86,13 @@ public:
|
||||
* @note This is called once BEFORE OnSourceModStartup() when SourceMod is loading
|
||||
* @note It can then be called again when the 'sm config' command is used
|
||||
*/
|
||||
virtual CoreConfigErr OnSourceModConfigChanged(const char *option, const char *value)
|
||||
virtual ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
return CoreConfig_InvalidOption;
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
private:
|
||||
SMGlobalClass *m_pGlobalClassNext;
|
||||
|
@ -73,24 +73,9 @@ size_t Translate(char *buffer, size_t maxlen, IPluginContext *pCtx, const char *
|
||||
try_serverlang:
|
||||
if (target == LANG_SERVER)
|
||||
{
|
||||
langname = g_Translator.GetServerLanguageCode();
|
||||
if (!TryServerLanguage(langname ? langname : "en", &langid))
|
||||
{
|
||||
pCtx->ThrowNativeError("Translation failure: English language not found");
|
||||
goto error_out;
|
||||
}
|
||||
} else if ((target >= 1) && (target <= g_Players.GetMaxClients())) {
|
||||
langname = g_Translator.GetServerLanguageCode(); /* :TODO: read player's lang */
|
||||
if (!langname || !g_Translator.GetLanguageByCode(langname, &langid))
|
||||
{
|
||||
if (langname && !strcmp(langname, "en"))
|
||||
{
|
||||
pCtx->ThrowNativeError("Translation failure: English language not found");
|
||||
goto error_out;
|
||||
}
|
||||
target = LANG_SERVER;
|
||||
goto try_serverlang;
|
||||
}
|
||||
langid = g_Translator.GetServerLanguageCode();
|
||||
} else if ((target >= 1) && (target <= g_Players.GetMaxClients())) {
|
||||
langid = g_Translator.GetServerLanguageCode();
|
||||
} else {
|
||||
pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Translation failed: invalid client index %d", target);
|
||||
goto error_out;
|
||||
@ -102,9 +87,8 @@ try_serverlang:
|
||||
{
|
||||
target = LANG_SERVER;
|
||||
goto try_serverlang;
|
||||
} else {
|
||||
if (!g_Translator.GetLanguageByCode("en", &langid)
|
||||
|| !TryTranslation(pl, key, langid, langcount, &pTrans))
|
||||
} else if (langid != LANGUAGE_ENGLISH) {
|
||||
if (!TryTranslation(pl, key, LANGUAGE_ENGLISH, langcount, &pTrans))
|
||||
{
|
||||
pCtx->ThrowNativeErrorEx(SP_ERROR_PARAM, "Language phrase \"%s\" not found", key);
|
||||
goto error_out;
|
||||
@ -900,6 +884,19 @@ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list ap)
|
||||
{
|
||||
size_t len = vsnprintf(buffer, maxlength, fmt, ap);
|
||||
|
||||
if (len >= maxlength)
|
||||
{
|
||||
buffer[maxlength - 1] = '\0';
|
||||
return (maxlength - 1);
|
||||
} else {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
char *sm_strdup(const char *str)
|
||||
{
|
||||
char *ptr = new char[strlen(str)+1];
|
||||
|
@ -30,6 +30,7 @@ const char *stristr(const char *str, const char *substr);
|
||||
unsigned int strncopy(char *dest, const char *src, size_t count);
|
||||
size_t gnprintf(char *buffer, size_t maxlen, const char *format, void **args);
|
||||
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
|
||||
size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list ap);
|
||||
char *sm_strdup(const char *str);
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_STRINGUTIL_H_
|
||||
|
@ -69,24 +69,32 @@ SourceModBase::SourceModBase()
|
||||
m_GotBasePath = false;
|
||||
}
|
||||
|
||||
CoreConfigErr SourceModBase::OnSourceModConfigChanged(const char *option, const char *value)
|
||||
ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength)
|
||||
{
|
||||
if (strcasecmp(option, "BasePath") == 0)
|
||||
if (strcasecmp(value, "BasePath") == 0)
|
||||
{
|
||||
if (source == ConfigSource_Console)
|
||||
{
|
||||
UTIL_Format(error, maxlength, "Cannot be set at runtime");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
if (!m_GotBasePath)
|
||||
{
|
||||
g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/%s", g_BaseDir.c_str(), value);
|
||||
g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), value);
|
||||
|
||||
m_GotBasePath = true;
|
||||
|
||||
return CoreConfig_Okay;
|
||||
} else {
|
||||
return CoreConfig_NoRuntime;
|
||||
}
|
||||
|
||||
return ConfigResult_Accept;
|
||||
}
|
||||
|
||||
return CoreConfig_InvalidOption;
|
||||
return ConfigResult_Ignore;
|
||||
}
|
||||
|
||||
bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
|
||||
@ -97,7 +105,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
|
||||
g_CoreConfig.Initialize();
|
||||
|
||||
/* This shouldn't happen, but can't hurt to be safe */
|
||||
if (!m_GotBasePath || !g_LibSys.PathExists(m_SMBaseDir))
|
||||
if (!g_LibSys.PathExists(m_SMBaseDir) || !m_GotBasePath)
|
||||
{
|
||||
g_LibSys.PathFormat(m_SMBaseDir, sizeof(m_SMBaseDir), "%s/addons/sourcemod", g_BaseDir.c_str());
|
||||
g_LibSys.PathFormat(m_SMRelDir, sizeof(m_SMRelDir), "addons/sourcemod");
|
||||
|
@ -78,7 +78,11 @@ public:
|
||||
*/
|
||||
void SetAuthChecking(bool set);
|
||||
public: // SMGlobalClass
|
||||
CoreConfigErr OnSourceModConfigChanged(const char *option, const char *value);
|
||||
ConfigResult OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
char *error,
|
||||
size_t maxlength);
|
||||
public: // ISourceMod
|
||||
const char *GetModPath() const;
|
||||
const char *GetSourceModPath() const;
|
||||
|
Loading…
Reference in New Issue
Block a user