Add ability to change dontBroadcast status on hooked events (bug 3886, r=ds).

This commit is contained in:
David Anderson 2009-12-19 18:16:41 -08:00
parent fe405df704
commit 02a99f1e51
6 changed files with 74 additions and 3 deletions

View File

@ -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<EventHook *> 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);

View File

@ -53,6 +53,7 @@ struct EventInfo
}
IGameEvent *pEvent;
IdentityToken_t *pOwner;
bool bDontBroadcast;
};
struct EventHook

View File

@ -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<num_params; i++)
{
int err = SP_ERROR_PARAM;

View File

@ -61,6 +61,14 @@ struct FwdParamInfo
ParamType pushedas;
};
class SourceMod::IForwardFilter
{
public:
virtual void Preprocess(IPluginFunction *fun, FwdParamInfo *params)
{
}
};
class CForward : public IChangeableForward
{
public: //ICallable

View File

@ -348,6 +348,23 @@ static cell_t sm_SetEventString(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t sm_SetEventBroadcast(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(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}
};

View File

@ -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);