diff --git a/amxmodx/CEvent.h b/amxmodx/CEvent.h index d94b7c2d..b856ee04 100755 --- a/amxmodx/CEvent.h +++ b/amxmodx/CEvent.h @@ -26,12 +26,6 @@ enum // class EventsMngr // ***************************************************** -enum ForwardState -{ - FSTATE_ACTIVE, - FSTATE_STOP -}; - class EventsMngr { enum MsgParamType @@ -154,7 +148,7 @@ public: struct EventHook { - EventHook(EventsMngr::ClEvent *event) : m_event(event) {} + explicit EventHook(EventsMngr::ClEvent *event) : m_event(event) {} EventsMngr::ClEvent *m_event; }; diff --git a/amxmodx/CLogEvent.cpp b/amxmodx/CLogEvent.cpp index aef64490..944f7ab5 100755 --- a/amxmodx/CLogEvent.cpp +++ b/amxmodx/CLogEvent.cpp @@ -10,6 +10,8 @@ #include "amxmodx.h" #include "CLogEvent.h" +NativeHandle LogEventHandles; + // ***************************************************** // class LogEventsMngr // ***************************************************** @@ -164,18 +166,37 @@ void LogEventsMngr::parseLogString() } } -LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos) +void LogEventsMngr::CLogEvent::setForwardState(ForwardState state) +{ + m_State = state; +} + +int LogEventsMngr::registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos) { if (pos < 1 || pos > MAX_LOGARGS) + { return 0; + } arelogevents = true; - CLogEvent** d = &logevents[pos]; - + auto d = &logevents[pos]; + while (*d) + { d = &(*d)->next; - - return *d = new CLogEvent(plugin, func, this); + } + + auto logevent = new CLogEvent(plugin, func, this); + auto handle = LogEventHandles.create(logevent); + + if (!handle) + { + return 0; + } + + *d = logevent; + + return handle; } void LogEventsMngr::executeLogEvents() @@ -184,8 +205,13 @@ void LogEventsMngr::executeLogEvents() for (CLogEvent* a = logevents[logArgc]; a; a = a->next) { + if (a->m_State != FSTATE_ACTIVE) + { + continue; + } + valid = true; - + for (CLogEvent::LogCond* b = a->filters; b; b = b->next) { valid = false; @@ -198,11 +224,11 @@ void LogEventsMngr::executeLogEvents() break; } } - - if (!valid) + + if (!valid) break; } - + if (valid) { executeForwards(a->func); @@ -227,6 +253,8 @@ void LogEventsMngr::clearLogEvents() } clearConditions(); + + LogEventHandles.clear(); } void LogEventsMngr::clearConditions() diff --git a/amxmodx/CLogEvent.h b/amxmodx/CLogEvent.h index 9f5cac90..fda56625 100755 --- a/amxmodx/CLogEvent.h +++ b/amxmodx/CLogEvent.h @@ -13,6 +13,7 @@ #define MAX_LOGARGS 12 #include +#include "natives_handles.h" // ***************************************************** // class LogEventsMngr @@ -95,13 +96,16 @@ public: LogCond *filters; LogEventsMngr* parent; - + + ForwardState m_State; + CLogEvent *next; - CLogEvent(CPluginMngr::CPlugin *p, int f, LogEventsMngr* ppp) : plugin(p), func(f), filters(0), parent(ppp), next(0) {} + CLogEvent(CPluginMngr::CPlugin *p, int f, LogEventsMngr* ppp) : plugin(p), func(f), filters(nullptr), parent(ppp), m_State(FSTATE_ACTIVE), next(nullptr) {} ~CLogEvent(); public: inline CPluginMngr::CPlugin *getPlugin() { return plugin; } void registerFilter(char* filter); + void setForwardState(ForwardState value); inline int getFunction() { return func; } }; @@ -116,7 +120,7 @@ public: ~LogEventsMngr(); // Interface - CLogEvent* registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos); + int registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos); inline bool logEventsExist() { return arelogevents; } void setLogString(const char* frmt, va_list& vaptr); @@ -153,4 +157,12 @@ public: inline iterator end() { return iterator(0, this); } }; +struct LogEventHook +{ + explicit LogEventHook(LogEventsMngr::CLogEvent *logevent) : m_logevent(logevent) {} + LogEventsMngr::CLogEvent *m_logevent; +}; + +extern NativeHandle LogEventHandles; + #endif //LOGEVENTS_H diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index ff3eb4f4..4ac58441 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -3076,29 +3076,66 @@ static cell AMX_NATIVE_CALL parse_loguser(AMX *amx, cell *params) return 1; } +// native register_logevent(const function[], argsnum, ...); static cell AMX_NATIVE_CALL register_logevent(AMX *amx, cell *params) { - CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx); - int a, iFunc; - char* temp = get_amxstring(amx, params[1], 0, a); + int length; + auto callback = get_amxstring(amx, params[1], 0, length); - iFunc = registerSPForwardByName(amx, temp, FP_DONE); - - if (iFunc == -1) + auto forwardId = registerSPForwardByName(amx, callback, FP_DONE); + + if (forwardId == -1) { - LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp); + LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", callback); return 0; } - LogEventsMngr::CLogEvent* r = g_logevents.registerLogEvent(plugin, iFunc, params[2]); + auto handle = g_logevents.registerLogEvent(g_plugins.findPluginFast(amx), forwardId, params[2]); - if (r == 0) + if (!handle) + { return 0; + } - int numparam = *params / sizeof(cell); + auto logevent = LogEventHandles.lookup(handle)->m_logevent; + auto numparam = *params / sizeof(cell); - for (int i = 3; i <= numparam; ++i) - r->registerFilter(get_amxstring(amx, params[i], 0, a)); + for (auto i = 3; i <= numparam; ++i) + { + logevent->registerFilter(get_amxstring(amx, params[i], 0, length)); + } + + return handle; +} + +// native enable_logevent(handle); +static cell AMX_NATIVE_CALL enable_logevent(AMX *amx, cell *params) +{ + auto handle = LogEventHandles.lookup(params[1]); + + if (!handle) + { + LogError(amx, AMX_ERR_NATIVE, "Invalid log event handle %d", params[1]); + return 0; + } + + handle->m_logevent->setForwardState(FSTATE_ACTIVE); + + return 1; +} + +// native disable_logevent(handle); +static cell AMX_NATIVE_CALL disable_logevent(AMX *amx, cell *params) +{ + auto handle = LogEventHandles.lookup(params[1]); + + if (!handle) + { + LogError(amx, AMX_ERR_NATIVE, "Invalid log event handle: %d", params[1]); + return 0; + } + + handle->m_logevent->setForwardState(FSTATE_STOP); return 1; } @@ -4671,6 +4708,8 @@ AMX_NATIVE_INFO amxmodx_Natives[] = {"enable_event", enable_event}, {"disable_event", disable_event}, {"register_logevent", register_logevent}, + {"enable_logevent", enable_logevent}, + {"disable_logevent", disable_logevent}, {"register_menucmd", register_menucmd}, {"register_menuid", register_menuid}, {"register_plugin", register_plugin}, diff --git a/amxmodx/natives_handles.h b/amxmodx/natives_handles.h index 068b394e..530d1faf 100644 --- a/amxmodx/natives_handles.h +++ b/amxmodx/natives_handles.h @@ -113,4 +113,10 @@ class NativeHandle } }; +enum ForwardState +{ + FSTATE_ACTIVE, + FSTATE_STOP +}; + #endif // _NATIVES_NATIVES_HANDLES_H_ diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index fe6f1c6d..5d06bc6c 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -566,12 +566,32 @@ native disable_event(handle); * - "&" for substring comparison * The argument is compared to the specified string accordingly * - * @return 1 on successfully registering event, 0 on failure + * @return Log event handle * @error If an invalid callback function is provided, an error will * be thrown. */ native register_logevent(const function[], argsnum, ...); +/** + * Enables a function hook of a game log event which has been previously registered with register_logevent(). + * + * @param handle Value returned from register_logevent() + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native enable_logevent(handle); + +/** + * Disables a function hook of a game log event which has been previously registered with register_logevent(). + * + * @param handle Value returned from register_logevent() + * + * @noreturn + * @error If an invalid handle is provided, an error will be thrown. + */ +native disable_logevent(handle); + /** * Sets display parameters for hudmessages. *