/* IGameEventManager2::FireEvent hook */ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast) { EventHook *pHook; IChangeableForward *pForward; const char *name; cell_t res = Pl_Continue; /* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */ if (!pEvent) { RETURN_META_VALUE(MRES_IGNORED, false); } name = pEvent->GetName(); if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook))) { /* Push the event onto the event stack. The reference count is increased to make sure * the structure is not garbage collected in between now and the post hook. */ pHook->refCount++; m_EventStack.push(pHook); pForward = pHook->pPreHook; if (pForward) { EventInfo info(pEvent, NULL); HandleSecurity sec(NULL, g_pCoreIdent); Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); pForward->PushCell(hndl); pForward->PushString(name); pForward->PushCell(bDontBroadcast); pForward->Execute(&res, NULL); g_HandleSys.FreeHandle(hndl, &sec); } if (pHook->postCopy) { m_EventCopies.push(gameevents->DuplicateEvent(pEvent)); } if (res) { gameevents->FreeEvent(pEvent); RETURN_META_VALUE(MRES_SUPERCEDE, false); } } else { m_EventStack.push(NULL); } RETURN_META_VALUE(MRES_IGNORED, true); }
/* IGameEventManager2::FireEvent post hook */ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast) { IGameEvent *pEventCopy = NULL; EventHook *pHook; IChangeableForward *pForward; const char *name; Handle_t hndl = 0; /* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */ if (!pEvent) { RETURN_META_VALUE(MRES_IGNORED, false); } name = m_EventNames.front(); if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook))) { pForward = pHook->pPostHook; if (pForward) { EventInfo info = { pHook->pEventCopy, NULL }; if (pHook->postCopy) { hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); pForward->PushCell(hndl); } else { pForward->PushCell(BAD_HANDLE); } pForward->PushString(name); pForward->PushCell(bDontBroadcast); pForward->Execute(NULL); if (pHook->postCopy) { /* Free handle */ HandleSecurity sec(NULL, g_pCoreIdent); g_HandleSys.FreeHandle(hndl, &sec); /* Free event structure */ gameevents->FreeEvent(pEventCopy); pHook->pEventCopy = NULL; } } } m_EventNames.pop(); RETURN_META_VALUE(MRES_IGNORED, true); }
/* IGameEventManager2::FireEvent hook */ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast) { EventHook *pHook; IChangeableForward *pForward; const char *name; cell_t res = Pl_Continue; /* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */ if (!pEvent) { RETURN_META_VALUE(MRES_IGNORED, false); } /* Get the event name, we're going to need this for passing to post hooks */ name = pEvent->GetName(); m_EventNames.push(name); if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook))) { pForward = pHook->pPreHook; if (pForward) { EventInfo info = { pEvent, NULL }; Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); pForward->PushCell(hndl); pForward->PushString(name); pForward->PushCell(bDontBroadcast); pForward->Execute(&res, NULL); HandleSecurity sec(NULL, g_pCoreIdent); g_HandleSys.FreeHandle(hndl, &sec); } if (pHook->postCopy) { pHook->pEventCopy = gameevents->DuplicateEvent(pEvent); } if (res) { gameevents->FreeEvent(pEvent); RETURN_META_VALUE(MRES_SUPERCEDE, false); } } RETURN_META_VALUE(MRES_IGNORED, true); }
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue) { /* If the values are the same, exit early in order to not trigger callbacks */ if (strcmp(pConVar->GetString(), oldValue) == 0) { return; } ConVarInfo *pInfo; /* Find the convar in the lookup trie */ if (!convar_cache_lookup(pConVar->GetName(), &pInfo)) { return; } IChangeableForward *pForward = pInfo->pChangeForward; if (pInfo->changeListeners.size() != 0) { for (auto i = pInfo->changeListeners.begin(); i != pInfo->changeListeners.end(); i++) (*i)->OnConVarChanged(pConVar, oldValue, flOldValue); } if (pForward != NULL) { ConVarReentrancyGuard guard(pConVar); /* Now call forwards in plugins that have hooked this */ pForward->PushCell(pInfo->handle); pForward->PushString(oldValue); pForward->PushString(pConVar->GetString()); pForward->Execute(NULL); } }
static void PawnFrameAction(void *pData) { ke::AutoPtr<SMFrameActionData> frame(reinterpret_cast<SMFrameActionData *>(pData)); IPlugin *pPlugin = pluginsys->PluginFromHandle(frame->ownerhandle, NULL); if (!pPlugin) { return; } IChangeableForward *pForward; HandleSecurity sec(pPlugin->GetIdentity(), g_pCoreIdent); if (handlesys->ReadHandle(frame->handle, g_PrivateFwdType, &sec, (void **)&pForward) != HandleError_None) { return; } pForward->PushCell(frame->data); pForward->Execute(NULL); handlesys->FreeHandle(frame->handle, &sec); }
/* IGameEventManager2::FireEvent post hook */ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast) { EventHook *pHook; EventInfo info; IChangeableForward *pForward; Handle_t hndl = 0; /* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */ if (!pEvent) { RETURN_META_VALUE(MRES_IGNORED, false); } pHook = m_EventStack.front(); if (pHook != NULL) { pForward = pHook->pPostHook; if (pForward) { if (pHook->postCopy) { info.bDontBroadcast = bDontBroadcast; info.pEvent = m_EventCopies.front(); info.pOwner = NULL; hndl = handlesys->CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); pForward->PushCell(hndl); } else { pForward->PushCell(BAD_HANDLE); } pForward->PushString(pHook->name.chars()); pForward->PushCell(bDontBroadcast); pForward->Execute(NULL); if (pHook->postCopy) { /* Free handle */ HandleSecurity sec(NULL, g_pCoreIdent); handlesys->FreeHandle(hndl, &sec); /* Free event structure */ gameevents->FreeEvent(info.pEvent); m_EventCopies.pop(); } } /* Decrement reference count, check if a delayed delete is needed */ if (--pHook->refCount == 0) { assert(pHook->pPostHook == NULL); assert(pHook->pPreHook == NULL); m_EventHooks.remove(pHook->name.chars()); delete pHook; } } m_EventStack.pop(); RETURN_META_VALUE(MRES_IGNORED, true); }