static cell_t sm_RemoveAllFromForward(IPluginContext *pContext, const cell_t *params)
{
	Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
	Handle_t plHandle = static_cast<Handle_t>(params[2]);
	HandleError err;
	IChangeableForward *pForward;
	IPlugin *pPlugin;

	if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
		!= HandleError_None)
	{
		return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
	}

	if (plHandle == 0)
	{
		pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
	} else {
		pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);

		if (!pPlugin)
		{
			return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
		}
	}

	return pForward->RemoveFunctionsOfPlugin(pPlugin);
}
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 cell_t sm_RemoveFromForward(IPluginContext *pContext, const cell_t *params)
{
	Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
	Handle_t plHandle = static_cast<Handle_t>(params[2]);
	HandleError err;
	IChangeableForward *pForward;
	IPlugin *pPlugin;

	if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
		!= HandleError_None)
	{
		return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
	}

	if (plHandle == 0)
	{
		pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
	} else {
		pPlugin = pluginsys->PluginFromHandle(plHandle, &err);

		if (!pPlugin)
		{
			return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
		}
	}

	IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);

	if (!pFunction)
	{
		return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
	}

	return pForward->RemoveFunction(pFunction);
}
Exemple #4
0
/* 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 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);
}
Exemple #6
0
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);
}
void ConVarManager::HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction)
{
	ConVarInfo *pInfo;
	IChangeableForward *pForward;

	/* Find the convar in the lookup trie */
	if (convar_cache_lookup(pConVar->GetName(), &pInfo))
	{
		/* Get the forward */
		pForward = pInfo->pChangeForward;

		/* If forward does not exist, create it */
		if (!pForward)
		{
			pForward = forwardsys->CreateForwardEx(NULL, ET_Ignore, 3, CONVARCHANGE_PARAMS);
			pInfo->pChangeForward = pForward;
		}

		/* Add function to forward's list */
		pForward->AddFunction(pFunction);
	}
}
void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFunction)
{
	ConVarInfo *pInfo;
	IChangeableForward *pForward;
	IPluginContext *pContext = pFunction->GetParentContext();

	/* Find the convar in the lookup trie */
	if (convar_cache_lookup(pConVar->GetName(), &pInfo))
	{
		/* Get the forward */
		pForward = pInfo->pChangeForward;

		/* If the forward doesn't exist, we can't unhook anything */
		if (!pForward)
		{
			pContext->ThrowNativeError("Convar \"%s\" has no active hook", pConVar->GetName());
			return;
		}

		/* Remove the function from the forward's list */
		if (!pForward->RemoveFunction(pFunction))
		{
			pContext->ThrowNativeError("Invalid hook callback specified for convar \"%s\"", pConVar->GetName());
			return;
		}

		/* If the forward now has 0 functions in it... */
		if (pForward->GetFunctionCount() == 0 &&
			!ConVarReentrancyGuard::IsCvarInChain(pConVar))
		{
			/* Free this forward */
			forwardsys->ReleaseForward(pForward);
			pInfo->pChangeForward = NULL;
		}
	}
}
Exemple #9
0
static cell_t sm_AddFrameAction(IPluginContext *pContext, const cell_t *params)
{
	IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
	IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[1]);
	if (!pFunction)
	{
		return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
	}

	IChangeableForward *pForward = forwardsys->CreateForwardEx(NULL, ET_Ignore, 1, NULL, Param_Cell);
	IdentityToken_t *pIdentity = pContext->GetIdentity();
	Handle_t Handle = handlesys->CreateHandle(g_PrivateFwdType, pForward, pIdentity, g_pCoreIdent, NULL);
	if (Handle == BAD_HANDLE)
	{
		forwardsys->ReleaseForward(pForward);
		return 0;
	}

	pForward->AddFunction(pFunction);

	SMFrameActionData *pData = new SMFrameActionData(Handle, pPlugin->GetMyHandle(), params[2]);
	g_pSM->AddFrameAction(PawnFrameAction, pData);
	return 1;
}
/* 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);
}
Exemple #11
0
/* 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);
}