diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index 0855fd4a..e77b19dd 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -251,6 +251,10 @@ RelativePath="..\smn_string.cpp" > + + diff --git a/core/smn_textparse.cpp b/core/smn_textparse.cpp new file mode 100644 index 00000000..7f1f1d5f --- /dev/null +++ b/core/smn_textparse.cpp @@ -0,0 +1,285 @@ +#include "sm_globals.h" +#include "CTextParsers.h" +#include "HandleSys.h" + +HandleType_t g_TypeSMC = 0; + +class ParseInfo : public ITextListener_SMC +{ +public: + ParseInfo() + { + parse_start = NULL; + parse_end = NULL; + new_section = NULL; + key_value = NULL; + end_section = NULL; + raw_line = NULL; + handle = 0; + } +public: + void ReadSMC_ParseStart() + { + if (parse_start) + { + cell_t result; + parse_start->PushCell(handle); + parse_start->Execute(&result); + } + } + + void ReadSMC_ParseEnd(bool halted, bool failed) + { + if (parse_end) + { + cell_t result; + parse_start->PushCell(handle); + parse_end->PushCell(halted ? 1 : 0); + parse_end->PushCell(failed ? 1 : 0); + parse_end->Execute(&result); + } + } + + SMCParseResult ReadSMC_NewSection(const char *name, bool opt_quotes) + { + cell_t result = SMCParse_Continue; + + if (new_section) + { + new_section->PushCell(handle); + new_section->PushString(name); + new_section->PushCell(opt_quotes ? 1 : 0); + new_section->Execute(&result); + } + + return (SMCParseResult)result; + } + + SMCParseResult ReadSMC_KeyValue(const char *key, const char *value, bool key_quotes, bool value_quotes) + { + cell_t result = SMCParse_Continue; + + if (key_value) + { + key_value->PushCell(handle); + key_value->PushString(key); + key_value->PushString(value); + key_value->PushCell(key_quotes ? 1 : 0); + key_value->PushCell(value_quotes ? 1 : 0); + key_value->Execute(&result); + } + + return (SMCParseResult)result; + } + + SMCParseResult ReadSMC_LeavingSection() + { + cell_t result = SMCParse_Continue; + + if (end_section) + { + end_section->PushCell(handle); + end_section->Execute(&result); + } + + return (SMCParseResult)result; + } + + SMCParseResult ReadSMC_RawLine(const char *line, unsigned int curline) + { + cell_t result = SMCParse_Continue; + + if (raw_line) + { + raw_line->PushCell(handle); + raw_line->PushString(line); + raw_line->PushCell(curline); + raw_line->Execute(&result); + } + + return (SMCParseResult)result; + } +public: + IPluginFunction *parse_start; + IPluginFunction *parse_end; + IPluginFunction *new_section; + IPluginFunction *key_value; + IPluginFunction *end_section; + IPluginFunction *raw_line; + Handle_t handle; +}; + +class TextParseGlobals : + public SMGlobalClass, + public IHandleTypeDispatch +{ +public: + void OnSourceModAllInitialized() + { + HandleAccess sec; + + /* These cannot be cloned, because they are locked to a specific plugin. + * However, we let anyone read them because we don't care. + */ + g_HandleSys.InitAccessDefaults(NULL, &sec); + sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY; + sec.access[HandleAccess_Read] = 0; + + g_TypeSMC = g_HandleSys.CreateType("SMCParser", this, 0, NULL, &sec, g_pCoreIdent, NULL); + } + + void OnSourceModShutdown() + { + g_HandleSys.RemoveType(g_TypeSMC, g_pCoreIdent); + } + + void OnHandleDestroy(HandleType_t type, void *object) + { + ParseInfo *parse = (ParseInfo *)object; + delete parse; + } +}; + +TextParseGlobals g_TextParseGlobals; + +static cell_t SMC_CreateParse(IPluginContext *pContext, const cell_t *params) +{ + ParseInfo *pInfo = new ParseInfo(); + + Handle_t hndl = g_HandleSys.CreateHandle(g_TypeSMC, pInfo, pContext->GetIdentity(), g_pCoreIdent, NULL); + + /* Should never happen */ + if (!hndl) + { + delete pInfo; + return 0; + } + + pInfo->handle = hndl; + + return hndl; +} + +static cell_t SMC_SetParseStart(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + ParseInfo *parse; + + if ((err=g_HandleSys.ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); + } + + parse->parse_start = pContext->GetFunctionById((funcid_t)params[2]); + + return 1; +} + +static cell_t SMC_SetParseEnd(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + ParseInfo *parse; + + if ((err=g_HandleSys.ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); + } + + parse->parse_end = pContext->GetFunctionById((funcid_t)params[2]); + + return 1; +} + +static cell_t SMC_SetReaders(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + ParseInfo *parse; + + if ((err=g_HandleSys.ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); + } + + parse->new_section = pContext->GetFunctionById((funcid_t)params[2]); + parse->key_value = pContext->GetFunctionById((funcid_t)params[3]); + parse->end_section = pContext->GetFunctionById((funcid_t)params[4]); + + return 1; +} + +static cell_t SMC_SetRawLine(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + ParseInfo *parse; + + if ((err=g_HandleSys.ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); + } + + parse->raw_line = pContext->GetFunctionById((funcid_t)params[2]); + + return 1; +} + +static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params) +{ + Handle_t hndl = (Handle_t)params[1]; + HandleError err; + ParseInfo *parse; + + if ((err=g_HandleSys.ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err); + } + + char *file; + pContext->LocalToString(params[2], &file); + + char path[PLATFORM_MAX_PATH]; + g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file); + + unsigned int line = 0, col = 0; + SMCParseError p_err = g_TextParser.ParseFile_SMC(path, parse, &line, &col); + + cell_t *c_line, *c_col; + pContext->LocalToPhysAddr(params[3], &c_line); + pContext->LocalToPhysAddr(params[4], &c_col); + + return (cell_t)p_err; +} + +static cell_t SMC_GetErrorString(IPluginContext *pContext, const cell_t *params) +{ + const char *str = g_TextParser.GetSMCErrorString((SMCParseError)params[1]); + + if (!str) + { + return 0; + } + + pContext->StringToLocal(params[2], params[3], str); + + return 1; +} + +REGISTER_NATIVES(textNatives) +{ + {"SMC_CreateParse", SMC_CreateParse}, + {"SMC_ParseFile", SMC_ParseFile}, + {"SMC_GetErrorString", SMC_GetErrorString}, + {"SMC_SetParseStart", SMC_SetParseStart}, + {"SMC_SetParseEnd", SMC_SetParseEnd}, + {"SMC_SetReaders", SMC_SetReaders}, + {"SMC_SetRawLine", SMC_SetRawLine}, + {NULL, NULL}, +}; diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index b87b34eb..4b635679 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -8,6 +8,7 @@ #include "ShareSys.h" #include "CLogger.h" #include "ExtensionSys.h" +#include "AdminCache.h" SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); @@ -169,6 +170,8 @@ bool SourceModBase::LevelInit(char const *pMapName, char const *pMapEntities, ch m_IsMapLoading = false; + g_Admins.DumpAdminCache(ADMIN_CACHE_GROUPS|ADMIN_CACHE_ADMINS|ADMIN_CACHE_OVERRIDES, true); + RETURN_META_VALUE(MRES_IGNORED, true); } diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index c6f99289..2404a20b 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -238,7 +238,7 @@ void CPlugin::Call_OnPluginInit() m_status = Plugin_Running; cell_t result; - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginInit"); + IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginStart"); if (!pFunction) { return; @@ -256,7 +256,7 @@ void CPlugin::Call_OnPluginUnload() } cell_t result; - IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginUnload"); + IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginEnd"); if (!pFunction) { return; @@ -1369,8 +1369,12 @@ void CPluginManager::OnRootConsoleCommand(const char *command, unsigned int argc assert(pl->GetStatus() != Plugin_Created); int len = 0; const sm_plugininfo_t *info = pl->GetPublicInfo(); - - len += UTIL_Format(buffer, sizeof(buffer), " %02d <%s>", id, GetStatusText(pl->GetStatus())); + if (pl->GetStatus() != Pl_Running) + { + len += UTIL_Format(buffer, sizeof(buffer), " %02d <%s>", id, GetStatusText(pl->GetStatus())); + } else { + len += UTIL_Format(buffer, sizeof(buffer), " %02d", id); + } len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename()); if (IS_STR_FILLED(info->version)) {