From 02a99f1e51b8d7a70cd322f44ca9898f26bfe785 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 19 Dec 2009 18:16:41 -0800 Subject: [PATCH] Add ability to change dontBroadcast status on hooked events (bug 3886, r=ds). --- core/EventManager.cpp | 30 ++++++++++++++++++++++++++++-- core/EventManager.h | 1 + core/ForwardSys.cpp | 5 ++++- core/ForwardSys.h | 8 ++++++++ core/smn_events.cpp | 19 +++++++++++++++++++ plugins/include/events.inc | 14 ++++++++++++++ 6 files changed, 74 insertions(+), 3 deletions(-) diff --git a/core/EventManager.cpp b/core/EventManager.cpp index a95e78c9..ebfcd8c7 100644 --- a/core/EventManager.cpp +++ b/core/EventManager.cpp @@ -1,5 +1,5 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. @@ -42,6 +42,20 @@ SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell}; typedef List EventHookList; +class EventForwardFilter : public IForwardFilter +{ + EventInfo *pEventInfo; +public: + EventForwardFilter(EventInfo *pEventInfo) : pEventInfo(pEventInfo) + { + } + + void Preprocess(IPluginFunction *fun, FwdParamInfo *params) + { + params[2].val = pEventInfo->bDontBroadcast ? 1 : 0; + } +}; + EventManager::EventManager() : m_EventType(0) { /* Create an event lookup trie */ @@ -327,6 +341,7 @@ EventInfo *EventManager::CreateEvent(IPluginContext *pContext, const char *name, pInfo->pEvent = pEvent; pInfo->pOwner = pContext->GetIdentity(); + pInfo->bDontBroadcast = false; return pInfo; } @@ -365,6 +380,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast) IChangeableForward *pForward; const char *name; cell_t res = Pl_Continue; + bool broadcast = bDontBroadcast; /* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */ if (!pEvent) @@ -390,10 +406,16 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast) HandleSecurity sec(NULL, g_pCoreIdent); Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); + info.bDontBroadcast = bDontBroadcast; + + EventForwardFilter filter(&info); + pForward->PushCell(hndl); pForward->PushString(name); pForward->PushCell(bDontBroadcast); - pForward->Execute(&res, NULL); + pForward->Execute(&res, &filter); + + broadcast = info.bDontBroadcast; g_HandleSys.FreeHandle(hndl, &sec); } @@ -414,6 +436,9 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast) m_EventStack.push(NULL); } + if (broadcast != bDontBroadcast) + RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, true, &IGameEventManager2::FireEvent, (pEvent, broadcast)); + RETURN_META_VALUE(MRES_IGNORED, true); } @@ -441,6 +466,7 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast) { if (pHook->postCopy) { + info.bDontBroadcast = bDontBroadcast; info.pEvent = m_EventCopies.front(); info.pOwner = NULL; hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); diff --git a/core/EventManager.h b/core/EventManager.h index 6ed3dda3..684cbbc5 100644 --- a/core/EventManager.h +++ b/core/EventManager.h @@ -53,6 +53,7 @@ struct EventInfo } IGameEvent *pEvent; IdentityToken_t *pOwner; + bool bDontBroadcast; }; struct EventHook diff --git a/core/ForwardSys.cpp b/core/ForwardSys.cpp index 02eeb057..16245222 100644 --- a/core/ForwardSys.cpp +++ b/core/ForwardSys.cpp @@ -1,5 +1,5 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= * SourceMod * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. @@ -308,6 +308,9 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter) { func = (*iter); + if (filter) + filter->Preprocess(func, temp_info); + for (unsigned int i=0; i(params[1]); + HandleError err; + EventInfo *pInfo; + + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err); + } + + pInfo->bDontBroadcast = params[2] ? true : false; + + return 1; +} + REGISTER_NATIVES(gameEventNatives) { {"HookEvent", sm_HookEvent}, @@ -365,5 +382,7 @@ REGISTER_NATIVES(gameEventNatives) {"SetEventInt", sm_SetEventInt}, {"SetEventFloat", sm_SetEventFloat}, {"SetEventString", sm_SetEventString}, + {"SetEventBroadcast", sm_SetEventBroadcast}, {NULL, NULL} }; + diff --git a/plugins/include/events.inc b/plugins/include/events.inc index 07630794..91bcbbc4 100644 --- a/plugins/include/events.inc +++ b/plugins/include/events.inc @@ -241,3 +241,17 @@ native SetEventString(Handle:event, const String:key[], const String:value[]); * @error Invalid or corrupt Handle. */ native GetEventName(Handle:event, String:name[], maxlength); + +/** + * Sets whether an event's broadcasting will be disabled or not. + * + * This has no effect on events Handles that are not from HookEvent + * or HookEventEx callbacks. + * + * @param event Handle to an event from an event hook. + * @param dontBroadcast True to disable broadcasting, false otherwise. + * @noreturn + * @error Invalid Handle. + */ +native SetEventBroadcast(Handle:event, bool:dontBroadcast); +