Initial import of event stuff: Natives to hook and fire game events
Also made some minor internal changes to convars --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40582
This commit is contained in:
parent
510b764d43
commit
68f40e96f2
@ -88,7 +88,7 @@ void CConVarManager::OnPluginDestroyed(IPlugin *plugin)
|
|||||||
CVector<ConVar *> *cvarList;
|
CVector<ConVar *> *cvarList;
|
||||||
|
|
||||||
// If plugin has a convar list, free its memory
|
// If plugin has a convar list, free its memory
|
||||||
if (plugin->GetProperty("ConVar", reinterpret_cast<void **>(&cvarList), true))
|
if (plugin->GetProperty("ConVarList", reinterpret_cast<void **>(&cvarList), true))
|
||||||
{
|
{
|
||||||
delete cvarList;
|
delete cvarList;
|
||||||
}
|
}
|
||||||
@ -97,21 +97,21 @@ void CConVarManager::OnPluginDestroyed(IPlugin *plugin)
|
|||||||
void CConVarManager::OnHandleDestroy(HandleType_t type, void *object)
|
void CConVarManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||||
{
|
{
|
||||||
ConVarInfo *info;
|
ConVarInfo *info;
|
||||||
ConVar *cvar = static_cast<ConVar *>(object);
|
ConVar *pConVar = static_cast<ConVar *>(object);
|
||||||
|
|
||||||
// Find convar in lookup trie
|
// Find convar in lookup trie
|
||||||
sm_trie_retrieve(m_ConVarCache, cvar->GetName(), reinterpret_cast<void **>(&info));
|
sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info));
|
||||||
|
|
||||||
// If convar was created by SourceMod plugin...
|
// If convar was created by SourceMod plugin...
|
||||||
if (info->sourceMod)
|
if (info->sourceMod)
|
||||||
{
|
{
|
||||||
// Delete string allocations
|
// Delete string allocations
|
||||||
delete [] cvar->GetName();
|
delete [] pConVar->GetName();
|
||||||
delete [] cvar->GetDefault();
|
delete [] pConVar->GetDefault();
|
||||||
delete [] cvar->GetHelpText();
|
delete [] pConVar->GetHelpText();
|
||||||
|
|
||||||
// Then unregister it
|
// Then unlink it from SourceMM
|
||||||
g_SMAPI->UnregisterConCmdBase(g_PLAPI, cvar);
|
g_SMAPI->UnregisterConCmdBase(g_PLAPI, pConVar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,8 +151,8 @@ void CConVarManager::OnRootConsoleCommand(const char *command, unsigned int argc
|
|||||||
// Iterate convar list and display each one
|
// Iterate convar list and display each one
|
||||||
for (size_t i = 0; i < cvarList->size(); i++, id++)
|
for (size_t i = 0; i < cvarList->size(); i++, id++)
|
||||||
{
|
{
|
||||||
ConVar *cvar = (*cvarList)[i];
|
ConVar *pConVar = (*cvarList)[i];
|
||||||
g_RootMenu.ConsolePrint(" %02d \"%s\" = \"%s\"", id, cvar->GetName(), cvar->GetString());
|
g_RootMenu.ConsolePrint(" %02d \"%s\" = \"%s\"", id, pConVar->GetName(), pConVar->GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -164,16 +164,16 @@ void CConVarManager::OnRootConsoleCommand(const char *command, unsigned int argc
|
|||||||
|
|
||||||
Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText, int flags, bool hasMin, float min, bool hasMax, float max)
|
Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *helpText, int flags, bool hasMin, float min, bool hasMax, float max)
|
||||||
{
|
{
|
||||||
ConVar *cvar = NULL;
|
ConVar *pConVar = NULL;
|
||||||
ConVarInfo *info = NULL;
|
ConVarInfo *info = NULL;
|
||||||
CVector<ConVar *> *cvarList = NULL;
|
CVector<ConVar *> *cvarList = NULL;
|
||||||
Handle_t hndl = 0;
|
Handle_t hndl = 0;
|
||||||
|
|
||||||
// Find out if the convar exists already
|
// Find out if the convar exists already
|
||||||
cvar = icvar->FindVar(name);
|
pConVar = icvar->FindVar(name);
|
||||||
|
|
||||||
// If the convar already exists...
|
// If the convar already exists...
|
||||||
if (cvar != NULL)
|
if (pConVar != NULL)
|
||||||
{
|
{
|
||||||
// First check if we already have a handle to it
|
// First check if we already have a handle to it
|
||||||
if (sm_trie_retrieve(m_ConVarCache, name, reinterpret_cast<void **>(&info)))
|
if (sm_trie_retrieve(m_ConVarCache, name, reinterpret_cast<void **>(&info)))
|
||||||
@ -182,13 +182,13 @@ Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name
|
|||||||
return info->handle;
|
return info->handle;
|
||||||
} else {
|
} else {
|
||||||
// If we don't, then create a new handle from the convar
|
// If we don't, then create a new handle from the convar
|
||||||
hndl = g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
info = new ConVarInfo;
|
info = new ConVarInfo;
|
||||||
info->handle = hndl;
|
info->handle = hndl;
|
||||||
info->sourceMod = false;
|
info->sourceMod = false;
|
||||||
info->changeForward = NULL;
|
info->changeForward = NULL;
|
||||||
info->origCallback = cvar->GetCallback();
|
info->origCallback = pConVar->GetCallback();
|
||||||
|
|
||||||
m_ConVars.push_back(info);
|
m_ConVars.push_back(info);
|
||||||
|
|
||||||
@ -210,27 +210,27 @@ Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Since we didn't find an existing convar (or concmd with the same name), now we can finally create it!
|
// Since we didn't find an existing convar (or concmd with the same name), now we can finally create it!
|
||||||
cvar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(helpText), hasMin, min, hasMax, max);
|
pConVar = new ConVar(sm_strdup(name), sm_strdup(defaultVal), flags, sm_strdup(helpText), hasMin, min, hasMax, max);
|
||||||
|
|
||||||
// Find plugin creating convar
|
// Find plugin creating convar
|
||||||
IPlugin *pl = g_PluginSys.FindPluginByContext(pContext->GetContext());
|
IPlugin *pl = g_PluginSys.FindPluginByContext(pContext->GetContext());
|
||||||
|
|
||||||
// Get convar list from 'ConVar' property of plugin
|
// Get convar list from 'ConVar' property of plugin
|
||||||
pl->GetProperty("ConVar", reinterpret_cast<void **>(&cvarList));
|
pl->GetProperty("ConVarList", reinterpret_cast<void **>(&cvarList));
|
||||||
|
|
||||||
// If 'ConVar' property doesn't exist...
|
// If 'ConVar' property doesn't exist...
|
||||||
if (cvarList == NULL)
|
if (cvarList == NULL)
|
||||||
{
|
{
|
||||||
// Then create it
|
// Then create it
|
||||||
cvarList = new CVector<ConVar *>;
|
cvarList = new CVector<ConVar *>;
|
||||||
pl->SetProperty("ConVar", cvarList);
|
pl->SetProperty("ConVarList", cvarList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new convar to plugin's list
|
// Add new convar to plugin's list
|
||||||
cvarList->push_back(cvar);
|
cvarList->push_back(pConVar);
|
||||||
|
|
||||||
// Create a handle from the new convar
|
// Create a handle from the new convar
|
||||||
hndl = g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
info = new ConVarInfo;
|
info = new ConVarInfo;
|
||||||
info->handle = hndl;
|
info->handle = hndl;
|
||||||
@ -248,15 +248,15 @@ Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name
|
|||||||
|
|
||||||
Handle_t CConVarManager::FindConVar(const char *name)
|
Handle_t CConVarManager::FindConVar(const char *name)
|
||||||
{
|
{
|
||||||
ConVar *cvar = NULL;
|
ConVar *pConVar = NULL;
|
||||||
ConVarInfo *info = NULL;
|
ConVarInfo *info = NULL;
|
||||||
Handle_t hndl = 0;
|
Handle_t hndl = 0;
|
||||||
|
|
||||||
// Search for convar
|
// Search for convar
|
||||||
cvar = icvar->FindVar(name);
|
pConVar = icvar->FindVar(name);
|
||||||
|
|
||||||
// If it doesn't exist, then return an invalid handle
|
// If it doesn't exist, then return an invalid handle
|
||||||
if (cvar == NULL)
|
if (pConVar == NULL)
|
||||||
{
|
{
|
||||||
return BAD_HANDLE;
|
return BAD_HANDLE;
|
||||||
}
|
}
|
||||||
@ -269,13 +269,13 @@ Handle_t CConVarManager::FindConVar(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we don't, then create a new handle from the convar
|
// If we don't, then create a new handle from the convar
|
||||||
hndl = g_HandleSys.CreateHandle(m_ConVarType, cvar, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_ConVarType, pConVar, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
info = new ConVarInfo;
|
info = new ConVarInfo;
|
||||||
info->handle = hndl;
|
info->handle = hndl;
|
||||||
info->sourceMod = false;
|
info->sourceMod = false;
|
||||||
info->changeForward = NULL;
|
info->changeForward = NULL;
|
||||||
info->origCallback = cvar->GetCallback();
|
info->origCallback = pConVar->GetCallback();
|
||||||
|
|
||||||
m_ConVars.push_back(info);
|
m_ConVars.push_back(info);
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ Handle_t CConVarManager::FindConVar(const char *name)
|
|||||||
return hndl;
|
return hndl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *cvar, funcid_t funcid)
|
void CConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid)
|
||||||
{
|
{
|
||||||
IPluginFunction *func = pContext->GetFunctionById(funcid);
|
IPluginFunction *func = pContext->GetFunctionById(funcid);
|
||||||
IChangeableForward *fwd = NULL;
|
IChangeableForward *fwd = NULL;
|
||||||
@ -300,7 +300,7 @@ void CConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *cvar, fu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a forward name
|
// Create a forward name
|
||||||
UTIL_Format(fwdName, sizeof(fwdName), "ConVar.%s", cvar->GetName());
|
UTIL_Format(fwdName, sizeof(fwdName), "ConVar.%s", pConVar->GetName());
|
||||||
|
|
||||||
// First find out if the forward already exists
|
// First find out if the forward already exists
|
||||||
g_Forwards.FindForward(fwdName, &fwd);
|
g_Forwards.FindForward(fwdName, &fwd);
|
||||||
@ -315,13 +315,13 @@ void CConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *cvar, fu
|
|||||||
fwd = g_Forwards.CreateForwardEx(fwdName, ET_Ignore, 3, p);
|
fwd = g_Forwards.CreateForwardEx(fwdName, ET_Ignore, 3, p);
|
||||||
|
|
||||||
// Find the convar in the lookup trie
|
// Find the convar in the lookup trie
|
||||||
if (sm_trie_retrieve(m_ConVarCache, cvar->GetName(), reinterpret_cast<void **>(&info)))
|
if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info)))
|
||||||
{
|
{
|
||||||
// Set the convar's forward to the newly created one
|
// Set the convar's forward to the newly created one
|
||||||
info->changeForward = fwd;
|
info->changeForward = fwd;
|
||||||
|
|
||||||
// Set the convar's callback to our static one
|
// Set the convar's callback to our static one
|
||||||
cvar->InstallChangeCallback(OnConVarChanged);
|
pConVar->InstallChangeCallback(OnConVarChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ void CConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *cvar, fu
|
|||||||
fwd->AddFunction(func);
|
fwd->AddFunction(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *cvar, funcid_t funcid)
|
void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid)
|
||||||
{
|
{
|
||||||
IPluginFunction *func = pContext->GetFunctionById(funcid);
|
IPluginFunction *func = pContext->GetFunctionById(funcid);
|
||||||
IChangeableForward *fwd = NULL;
|
IChangeableForward *fwd = NULL;
|
||||||
@ -343,7 +343,7 @@ void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *cvar,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the convar in the lookup trie
|
// Find the convar in the lookup trie
|
||||||
if (sm_trie_retrieve(m_ConVarCache, cvar->GetName(), reinterpret_cast<void **>(&info)))
|
if (sm_trie_retrieve(m_ConVarCache, pConVar->GetName(), reinterpret_cast<void **>(&info)))
|
||||||
{
|
{
|
||||||
// Get the forward
|
// Get the forward
|
||||||
fwd = info->changeForward;
|
fwd = info->changeForward;
|
||||||
@ -351,14 +351,14 @@ void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *cvar,
|
|||||||
// If the forward doesn't exist, we can't unhook anything
|
// If the forward doesn't exist, we can't unhook anything
|
||||||
if (fwd == NULL)
|
if (fwd == NULL)
|
||||||
{
|
{
|
||||||
pContext->ThrowNativeError("Convar \"%s\" has no active hook", cvar->GetName());
|
pContext->ThrowNativeError("Convar \"%s\" has no active hook", pConVar->GetName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the function from the forward's list
|
// Remove the function from the forward's list
|
||||||
if (!fwd->RemoveFunction(func))
|
if (!fwd->RemoveFunction(func))
|
||||||
{
|
{
|
||||||
pContext->ThrowNativeError("Invalid hook callback specified for convar \"%s\"", cvar->GetName());
|
pContext->ThrowNativeError("Invalid hook callback specified for convar \"%s\"", pConVar->GetName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,15 +370,15 @@ void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *cvar,
|
|||||||
info->changeForward = NULL;
|
info->changeForward = NULL;
|
||||||
|
|
||||||
// Put the back the original convar callback
|
// Put the back the original convar callback
|
||||||
cvar->InstallChangeCallback(info->origCallback);
|
pConVar->InstallChangeCallback(info->origCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConVarManager::OnConVarChanged(ConVar *cvar, const char *oldValue)
|
void CConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
|
||||||
{
|
{
|
||||||
// If the values are the same...
|
// If the values are the same...
|
||||||
if (strcmp(cvar->GetString(), oldValue) == 0)
|
if (strcmp(pConVar->GetString(), oldValue) == 0)
|
||||||
{
|
{
|
||||||
// Exit early in order to not trigger callbacks
|
// Exit early in order to not trigger callbacks
|
||||||
return;
|
return;
|
||||||
@ -388,7 +388,7 @@ void CConVarManager::OnConVarChanged(ConVar *cvar, const char *oldValue)
|
|||||||
ConVarInfo *info;
|
ConVarInfo *info;
|
||||||
|
|
||||||
// Find the convar in the lookup trie
|
// Find the convar in the lookup trie
|
||||||
sm_trie_retrieve(cache, cvar->GetName(), reinterpret_cast<void **>(&info));
|
sm_trie_retrieve(cache, pConVar->GetName(), reinterpret_cast<void **>(&info));
|
||||||
|
|
||||||
FnChangeCallback origCallback = info->origCallback;
|
FnChangeCallback origCallback = info->origCallback;
|
||||||
IChangeableForward *fwd = info->changeForward;
|
IChangeableForward *fwd = info->changeForward;
|
||||||
@ -396,12 +396,12 @@ void CConVarManager::OnConVarChanged(ConVar *cvar, const char *oldValue)
|
|||||||
// If there was a change callback installed previously, call it
|
// If there was a change callback installed previously, call it
|
||||||
if (origCallback)
|
if (origCallback)
|
||||||
{
|
{
|
||||||
origCallback(cvar, oldValue);
|
origCallback(pConVar, oldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now call forwards in plugins that have hooked this
|
// Now call forwards in plugins that have hooked this
|
||||||
fwd->PushCell(info->handle);
|
fwd->PushCell(info->handle);
|
||||||
fwd->PushString(cvar->GetString());
|
fwd->PushString(pConVar->GetString());
|
||||||
fwd->PushString(oldValue);
|
fwd->PushString(oldValue);
|
||||||
fwd->Execute(NULL);
|
fwd->Execute(NULL);
|
||||||
}
|
}
|
||||||
|
@ -85,17 +85,17 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Add a function to call when the specified convar changes.
|
* Add a function to call when the specified convar changes.
|
||||||
*/
|
*/
|
||||||
void HookConVarChange(IPluginContext *pContext, ConVar *cvar, funcid_t funcid);
|
void HookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a function from the forward that will be called when the specified convar changes.
|
* Remove a function from the forward that will be called when the specified convar changes.
|
||||||
*/
|
*/
|
||||||
void UnhookConVarChange(IPluginContext *pContext, ConVar *cvar, funcid_t funcid);
|
void UnhookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Static callback that Valve's ConVar class executes when the convar's value changes.
|
* Static callback that Valve's ConVar class executes when the convar's value changes.
|
||||||
*/
|
*/
|
||||||
static void OnConVarChanged(ConVar *cvar, const char *oldValue);
|
static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
|
||||||
private:
|
private:
|
||||||
HandleType_t m_ConVarType;
|
HandleType_t m_ConVarType;
|
||||||
List<ConVarInfo *> m_ConVars;
|
List<ConVarInfo *> m_ConVars;
|
||||||
|
363
core/EventManager.cpp
Normal file
363
core/EventManager.cpp
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
/**
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EventManager.h"
|
||||||
|
#include "ForwardSys.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
#include "sm_stringutil.h"
|
||||||
|
|
||||||
|
EventManager g_EventManager;
|
||||||
|
|
||||||
|
SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, bool);
|
||||||
|
|
||||||
|
typedef List<EventHook *> EventHookList;
|
||||||
|
|
||||||
|
const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
|
||||||
|
|
||||||
|
EventManager::EventManager() : m_EventCopy(NULL), m_NotifyState(true)
|
||||||
|
{
|
||||||
|
/* Create an event lookup trie */
|
||||||
|
m_EventHooks = sm_trie_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
EventManager::~EventManager()
|
||||||
|
{
|
||||||
|
sm_trie_destroy(m_EventHooks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventManager::OnSourceModAllInitialized()
|
||||||
|
{
|
||||||
|
/* Add a hook for IGameEventManager2::FireEvent() */
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent, false);
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent_Post, true);
|
||||||
|
|
||||||
|
HandleAccess sec;
|
||||||
|
|
||||||
|
/* Handle access security for 'GameEvent' handle type */
|
||||||
|
sec.access[HandleAccess_Read] = 0;
|
||||||
|
sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
|
||||||
|
sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
|
||||||
|
|
||||||
|
/* Create the 'GameEvent' handle type */
|
||||||
|
m_EventType = g_HandleSys.CreateType("GameEvent", this, 0, NULL, &sec, g_pCoreIdent, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventManager::OnSourceModShutdown()
|
||||||
|
{
|
||||||
|
/* Remove hook for IGameEventManager2::FireEvent() */
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent, false);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent_Post, true);
|
||||||
|
|
||||||
|
/* Remove the 'GameEvent' handle type */
|
||||||
|
g_HandleSys.RemoveType(m_EventType, g_pCoreIdent);
|
||||||
|
|
||||||
|
/* Remove ourselves as listener for events */
|
||||||
|
gameevents->RemoveListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||||
|
{
|
||||||
|
if (type == m_EventType)
|
||||||
|
{
|
||||||
|
EventInfo *pInfo = static_cast<EventInfo *>(object);
|
||||||
|
|
||||||
|
if (pInfo->canDelete)
|
||||||
|
{
|
||||||
|
gameevents->FreeEvent(pInfo->pEvent);
|
||||||
|
delete pInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventManager::OnPluginUnloaded(IPlugin *plugin)
|
||||||
|
{
|
||||||
|
EventHookList *pHookList;
|
||||||
|
EventHook *pHook;
|
||||||
|
|
||||||
|
// If plugin has an event hook list...
|
||||||
|
if (plugin->GetProperty("EventHooks", reinterpret_cast<void **>(&pHookList), true))
|
||||||
|
{
|
||||||
|
for (EventHookList::iterator iter = pHookList->begin(); iter != pHookList->end(); iter++)
|
||||||
|
{
|
||||||
|
pHook = (*iter);
|
||||||
|
|
||||||
|
if (--pHook->refCount == 0)
|
||||||
|
{
|
||||||
|
if (pHook->pPreHook)
|
||||||
|
{
|
||||||
|
g_Forwards.ReleaseForward(pHook->pPreHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pHook->pPostHook)
|
||||||
|
{
|
||||||
|
g_Forwards.ReleaseForward(pHook->pPostHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pHook;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete pHookList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IGameEventListener2::FireGameEvent */
|
||||||
|
void EventManager::FireGameEvent(IGameEvent *pEvent)
|
||||||
|
{
|
||||||
|
/* Not going to do anything here.
|
||||||
|
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode)
|
||||||
|
{
|
||||||
|
EventHook *pHook;
|
||||||
|
|
||||||
|
/* If we aren't listening to this event... */
|
||||||
|
if (!gameevents->FindListener(this, name))
|
||||||
|
{
|
||||||
|
/* Then add ourselves */
|
||||||
|
if (!gameevents->AddListener(this, name, true))
|
||||||
|
{
|
||||||
|
/* If event doesn't exist... */
|
||||||
|
return EventHookErr_InvalidEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If a hook structure does not exist... */
|
||||||
|
if (!sm_trie_retrieve(m_EventHooks, name, (void **)&pHook))
|
||||||
|
{
|
||||||
|
EventHookList *pHookList;
|
||||||
|
IPlugin *plugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
|
||||||
|
/* Check plugin for an existing EventHook list */
|
||||||
|
if (!plugin->GetProperty("EventHooks", (void **)&pHookList))
|
||||||
|
{
|
||||||
|
pHookList = new EventHookList();
|
||||||
|
plugin->SetProperty("EventHooks", pHookList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create new GameEventHook structure */
|
||||||
|
pHook = new EventHook();
|
||||||
|
|
||||||
|
if (mode == EventHookMode_Pre)
|
||||||
|
{
|
||||||
|
/* Create forward for a pre hook */
|
||||||
|
pHook->pPreHook = g_Forwards.CreateForwardEx(NULL, ET_Event, 3, GAMEEVENT_PARAMS);
|
||||||
|
/* Add to forward list */
|
||||||
|
pHook->pPreHook->AddFunction(pFunction);
|
||||||
|
} else {
|
||||||
|
/* Create forward for a post hook */
|
||||||
|
pHook->pPostHook = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, GAMEEVENT_PARAMS);
|
||||||
|
/* Should we copy data from a pre hook to the post hook? */
|
||||||
|
pHook->postCopy = (mode == EventHookMode_Post);
|
||||||
|
/* Add to forward list */
|
||||||
|
pHook->pPostHook->AddFunction(pFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase reference count */
|
||||||
|
pHook->refCount++;
|
||||||
|
|
||||||
|
/* Add hook structure to hook lists */
|
||||||
|
pHookList->push_back(pHook);
|
||||||
|
sm_trie_insert(m_EventHooks, name, pHook);
|
||||||
|
|
||||||
|
return EventHookErr_Okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hook structure already exists at this point */
|
||||||
|
|
||||||
|
if (mode == EventHookMode_Pre)
|
||||||
|
{
|
||||||
|
/* Create pre hook forward if necessary */
|
||||||
|
if (!pHook->pPreHook)
|
||||||
|
{
|
||||||
|
pHook->pPreHook = g_Forwards.CreateForwardEx(NULL, ET_Event, 3, GAMEEVENT_PARAMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add plugin function to forward list */
|
||||||
|
pHook->pPreHook->AddFunction(pFunction);
|
||||||
|
} else {
|
||||||
|
/* Create post hook forward if necessary */
|
||||||
|
if (!pHook->pPostHook)
|
||||||
|
{
|
||||||
|
pHook->pPostHook = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, GAMEEVENT_PARAMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If postCopy is false, then we may want to set it to true */
|
||||||
|
if (!pHook->postCopy)
|
||||||
|
{
|
||||||
|
pHook->postCopy = (mode == EventHookMode_Post);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add plugin function to forward list */
|
||||||
|
pHook->pPostHook->AddFunction(pFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase reference count */
|
||||||
|
pHook->refCount++;
|
||||||
|
|
||||||
|
return EventHookErr_Okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode)
|
||||||
|
{
|
||||||
|
EventHook *pHook;
|
||||||
|
IChangeableForward **pEventForward;
|
||||||
|
|
||||||
|
/* If hook does not exist at all */
|
||||||
|
if (!sm_trie_retrieve(m_EventHooks, name, (void **)&pHook))
|
||||||
|
{
|
||||||
|
return EventHookErr_NotActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* One forward to rule them all */
|
||||||
|
if (mode == EventHookMode_Pre)
|
||||||
|
{
|
||||||
|
pEventForward = &pHook->pPreHook;
|
||||||
|
} else {
|
||||||
|
pEventForward = &pHook->pPostHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove function from forward's list */
|
||||||
|
if (*pEventForward == NULL || !(*pEventForward)->RemoveFunction(pFunction))
|
||||||
|
{
|
||||||
|
return EventHookErr_InvalidCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If forward's list contains 0 functions now, free it */
|
||||||
|
if ((*pEventForward)->GetFunctionCount() == 0)
|
||||||
|
{
|
||||||
|
g_Forwards.ReleaseForward(*pEventForward);
|
||||||
|
*pEventForward = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement reference count */
|
||||||
|
if (--pHook->refCount == 0)
|
||||||
|
{
|
||||||
|
/* If reference count is now 0, free hook structure */
|
||||||
|
|
||||||
|
EventHookList *pHookList;
|
||||||
|
IPlugin *plugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
|
||||||
|
/* Get plugin's event hook list */
|
||||||
|
plugin->GetProperty("EventHooks", (void**)&pHookList);
|
||||||
|
|
||||||
|
/* Remove current structure from plugin's list */
|
||||||
|
pHookList->remove(pHook);
|
||||||
|
|
||||||
|
/* Delete entry in trie */
|
||||||
|
sm_trie_delete(m_EventHooks, name);
|
||||||
|
|
||||||
|
/* And finally free structure memory */
|
||||||
|
delete pHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EventHookErr_Okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IGameEventManager2::FireEvent hook */
|
||||||
|
bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
||||||
|
{
|
||||||
|
EventHook *pHook;
|
||||||
|
IChangeableForward *pForward;
|
||||||
|
cell_t res = Pl_Continue;
|
||||||
|
|
||||||
|
if (!m_NotifyState)
|
||||||
|
{
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the event name, we're going to need this for passing to post hooks */
|
||||||
|
m_EventName = pEvent->GetName();
|
||||||
|
|
||||||
|
if (sm_trie_retrieve(m_EventHooks, m_EventName, reinterpret_cast<void **>(&pHook)))
|
||||||
|
{
|
||||||
|
pForward = pHook->pPreHook;
|
||||||
|
|
||||||
|
if (pForward)
|
||||||
|
{
|
||||||
|
EventInfo info = {pEvent, false};
|
||||||
|
|
||||||
|
Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
||||||
|
pForward->PushCell(hndl);
|
||||||
|
pForward->PushString(m_EventName);
|
||||||
|
pForward->PushCell(bDontBroadcast);
|
||||||
|
pForward->Execute(&res, NULL);
|
||||||
|
|
||||||
|
HandleSecurity sec = { NULL, g_pCoreIdent };
|
||||||
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pHook->postCopy)
|
||||||
|
{
|
||||||
|
m_EventCopy = gameevents->DuplicateEvent(pEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
gameevents->FreeEvent(pEvent);
|
||||||
|
RETURN_META_VALUE(MRES_SUPERCEDE, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IGameEventManager2::FireEvent post hook */
|
||||||
|
bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
||||||
|
{
|
||||||
|
EventHook *pHook;
|
||||||
|
IChangeableForward *pForward;
|
||||||
|
Handle_t hndl;
|
||||||
|
|
||||||
|
if (!m_NotifyState)
|
||||||
|
{
|
||||||
|
m_NotifyState = true;
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sm_trie_retrieve(m_EventHooks, m_EventName, reinterpret_cast<void **>(&pHook)))
|
||||||
|
{
|
||||||
|
pForward = pHook->pPostHook;
|
||||||
|
|
||||||
|
if (pForward)
|
||||||
|
{
|
||||||
|
if (pHook->postCopy)
|
||||||
|
{
|
||||||
|
EventInfo info = {m_EventCopy, false};
|
||||||
|
hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
||||||
|
pForward->PushCell(hndl);
|
||||||
|
} else {
|
||||||
|
pForward->PushCell(BAD_HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pForward->PushString(m_EventName);
|
||||||
|
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(m_EventCopy);
|
||||||
|
m_EventCopy = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
|
}
|
119
core/EventManager.h
Normal file
119
core/EventManager.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_CGAMEEVENTMANAGER_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_CGAMEEVENTMANAGER_H_
|
||||||
|
|
||||||
|
#include "sm_globals.h"
|
||||||
|
#include "sourcemm_api.h"
|
||||||
|
#include "sm_trie.h"
|
||||||
|
#include <sh_list.h>
|
||||||
|
#include <IHandleSys.h>
|
||||||
|
#include <IForwardSys.h>
|
||||||
|
#include <IPluginSys.h>
|
||||||
|
|
||||||
|
using namespace SourceHook;
|
||||||
|
|
||||||
|
//#define EVENT_PASSTHRU (1<<0)
|
||||||
|
#define EVENT_PASSTHRU_ALL (1<<1)
|
||||||
|
|
||||||
|
struct EventInfo
|
||||||
|
{
|
||||||
|
IGameEvent *pEvent;
|
||||||
|
bool canDelete;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EventHook
|
||||||
|
{
|
||||||
|
EventHook()
|
||||||
|
{
|
||||||
|
pPreHook = NULL;
|
||||||
|
pPostHook = NULL;
|
||||||
|
postCopy = false;
|
||||||
|
refCount = 0;
|
||||||
|
}
|
||||||
|
IChangeableForward *pPreHook;
|
||||||
|
IChangeableForward *pPostHook;
|
||||||
|
bool postCopy;
|
||||||
|
unsigned int refCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EventHookMode
|
||||||
|
{
|
||||||
|
EventHookMode_Pre,
|
||||||
|
EventHookMode_Post,
|
||||||
|
EventHookMode_PostNoCopy
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EventHookError
|
||||||
|
{
|
||||||
|
EventHookErr_Okay = 0, /**< No error */
|
||||||
|
EventHookErr_InvalidEvent, /**< Specified event does not exist */
|
||||||
|
EventHookErr_NotActive, /**< Specified event has no active hook */
|
||||||
|
EventHookErr_InvalidCallback, /**< Specified event does not fire specified callback */
|
||||||
|
};
|
||||||
|
|
||||||
|
class EventManager :
|
||||||
|
public SMGlobalClass,
|
||||||
|
public IHandleTypeDispatch,
|
||||||
|
public IPluginsListener,
|
||||||
|
public IGameEventListener2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EventManager();
|
||||||
|
~EventManager();
|
||||||
|
public: // SMGlobalClass
|
||||||
|
void OnSourceModAllInitialized();
|
||||||
|
void OnSourceModShutdown();
|
||||||
|
public: // IHandleTypeDispatch
|
||||||
|
void OnHandleDestroy(HandleType_t type, void *object);
|
||||||
|
public: // IPluginsListener
|
||||||
|
void OnPluginUnloaded(IPlugin *plugin);
|
||||||
|
public: // IGameEventListener2
|
||||||
|
void FireGameEvent(IGameEvent *pEvent);
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Get the 'GameEvent' handle type ID.
|
||||||
|
*/
|
||||||
|
inline HandleType_t GetHandleType()
|
||||||
|
{
|
||||||
|
return EventManager::m_EventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current SourceMod event notification state.
|
||||||
|
*
|
||||||
|
* If notify is set to true, SourceMod plugins will be notified of events. If false, they will not.
|
||||||
|
* This is temporarily used to make EVENT_PASSTHRU work when firing events from plugins.
|
||||||
|
*/
|
||||||
|
inline void SetNotifyState(bool notify)
|
||||||
|
{
|
||||||
|
m_NotifyState = notify;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
EventHookError HookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode=EventHookMode_Post);
|
||||||
|
EventHookError UnhookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode=EventHookMode_Post);
|
||||||
|
private: // IGameEventManager2 hooks
|
||||||
|
bool OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast);
|
||||||
|
bool OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast);
|
||||||
|
private:
|
||||||
|
HandleType_t m_EventType;
|
||||||
|
Trie *m_EventHooks;
|
||||||
|
bool m_NotifyState;
|
||||||
|
IGameEvent *m_EventCopy;
|
||||||
|
const char *m_EventName;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern EventManager g_EventManager;
|
||||||
|
|
||||||
|
#endif // _INCLUDE_SOURCEMOD_CGAMEEVENTMANAGER_H_
|
@ -227,6 +227,10 @@
|
|||||||
RelativePath="..\CUserMessages.cpp"
|
RelativePath="..\CUserMessages.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\EventManager.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\sm_autonatives.cpp"
|
RelativePath="..\sm_autonatives.cpp"
|
||||||
>
|
>
|
||||||
@ -317,6 +321,10 @@
|
|||||||
RelativePath="..\CUserMessages.h"
|
RelativePath="..\CUserMessages.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\EventManager.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\sm_autonatives.h"
|
RelativePath="..\sm_autonatives.h"
|
||||||
>
|
>
|
||||||
@ -689,6 +697,10 @@
|
|||||||
RelativePath="..\smn_entities.cpp"
|
RelativePath="..\smn_entities.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\smn_events.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\smn_filesystem.cpp"
|
RelativePath="..\smn_filesystem.cpp"
|
||||||
>
|
>
|
||||||
|
@ -62,15 +62,15 @@ static cell_t sm_HookConVarChange(IPluginContext *pContext, const cell_t *params
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ConVarManager.HookConVarChange(pContext, cvar, static_cast<funcid_t>(params[2]));
|
g_ConVarManager.HookConVarChange(pContext, pConVar, static_cast<funcid_t>(params[2]));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -79,15 +79,15 @@ static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *para
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ConVarManager.UnhookConVarChange(pContext, cvar, static_cast<funcid_t>(params[2]));
|
g_ConVarManager.UnhookConVarChange(pContext, pConVar, static_cast<funcid_t>(params[2]));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -96,30 +96,30 @@ static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cvar->GetBool();
|
return pConVar->GetBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
|
static cell_t sm_GetConVarInt(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cvar->GetInt();
|
return pConVar->GetInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This handles both SetConVarBool() and SetConVarInt() */
|
/* This handles both SetConVarBool() and SetConVarInt() */
|
||||||
@ -127,15 +127,15 @@ static cell_t sm_SetConVarNum(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar->SetValue(params[2]);
|
pConVar->SetValue(params[2]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -144,15 +144,15 @@ static cell_t sm_GetConVarFloat(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
float value = cvar->GetFloat();
|
float value = pConVar->GetFloat();
|
||||||
|
|
||||||
return sp_ftoc(value);
|
return sp_ftoc(value);
|
||||||
}
|
}
|
||||||
@ -161,16 +161,16 @@ static cell_t sm_SetConVarFloat(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
float value = sp_ctof(params[2]);
|
float value = sp_ctof(params[2]);
|
||||||
cvar->SetValue(value);
|
pConVar->SetValue(value);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -179,15 +179,15 @@ static cell_t sm_GetConVarString(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pContext->StringToLocalUTF8(params[2], params[3], cvar->GetString(), NULL);
|
pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetString(), NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -196,9 +196,9 @@ static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
@ -207,7 +207,7 @@ static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
|
|||||||
char *value;
|
char *value;
|
||||||
pContext->LocalToString(params[2], &value);
|
pContext->LocalToString(params[2], &value);
|
||||||
|
|
||||||
cvar->SetValue(value);
|
pConVar->SetValue(value);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -216,30 +216,30 @@ static cell_t sm_GetConVarFlags(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cvar->GetFlags();
|
return pConVar->GetFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
|
static cell_t sm_SetConVarFlags(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar->SetFlags(params[2]);
|
pConVar->SetFlags(params[2]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -248,9 +248,9 @@ static cell_t sm_GetConVarMin(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
@ -262,7 +262,7 @@ static cell_t sm_GetConVarMin(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
pContext->LocalToPhysAddr(params[2], &addr);
|
pContext->LocalToPhysAddr(params[2], &addr);
|
||||||
|
|
||||||
hasMin = cvar->GetMin(min);
|
hasMin = pConVar->GetMin(min);
|
||||||
*addr = sp_ftoc(min);
|
*addr = sp_ftoc(min);
|
||||||
|
|
||||||
return hasMin;
|
return hasMin;
|
||||||
@ -272,9 +272,9 @@ static cell_t sm_GetConVarMax(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
@ -286,7 +286,7 @@ static cell_t sm_GetConVarMax(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
pContext->LocalToPhysAddr(params[2], &addr);
|
pContext->LocalToPhysAddr(params[2], &addr);
|
||||||
|
|
||||||
hasMax = cvar->GetMax(max);
|
hasMax = pConVar->GetMax(max);
|
||||||
*addr = sp_ftoc(max);
|
*addr = sp_ftoc(max);
|
||||||
|
|
||||||
return hasMax;
|
return hasMax;
|
||||||
@ -296,15 +296,15 @@ static cell_t sm_GetConVarName(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pContext->StringToLocalUTF8(params[2], params[3], cvar->GetName(), NULL);
|
pContext->StringToLocalUTF8(params[2], params[3], pConVar->GetName(), NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -313,15 +313,15 @@ static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
|
|||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ConVar *cvar;
|
ConVar *pConVar;
|
||||||
|
|
||||||
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&cvar))
|
if ((err=g_HandleSys.ReadHandle(hndl, g_ConVarManager.GetHandleType(), NULL, (void **)&pConVar))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar->Revert();
|
pConVar->Revert();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
337
core/smn_events.cpp
Normal file
337
core/smn_events.cpp
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/**
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is not open source and may not be copied without explicit
|
||||||
|
* written permission of AlliedModders LLC. This file may not be redistributed
|
||||||
|
* in whole or significant part.
|
||||||
|
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sm_globals.h"
|
||||||
|
#include "sourcemm_api.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
#include "EventManager.h"
|
||||||
|
|
||||||
|
static cell_t sm_HookEvent(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
IPluginFunction *pFunction;
|
||||||
|
|
||||||
|
pContext->LocalToString(params[1], &name);
|
||||||
|
pFunction = pContext->GetFunctionById(params[2]);
|
||||||
|
|
||||||
|
if (!pFunction)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_EventManager.HookEvent(name, pFunction, static_cast<EventHookMode>(params[3])) == EventHookErr_InvalidEvent)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Game event \"%s\" does not exist", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_UnhookEvent(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
IPluginFunction *pFunction;
|
||||||
|
|
||||||
|
pContext->LocalToString(params[1], &name);
|
||||||
|
pFunction = pContext->GetFunctionById(params[2]);
|
||||||
|
|
||||||
|
if (!pFunction)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHookError err = g_EventManager.UnhookEvent(name, pFunction, static_cast<EventHookMode>(params[3]));
|
||||||
|
|
||||||
|
/* Possible errors that UnhookGameEvent can return */
|
||||||
|
if (err == EventHookErr_NotActive)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Game event \"%s\" has no active hook", name);
|
||||||
|
} else if (err == EventHookErr_InvalidCallback) {
|
||||||
|
return pContext->ThrowNativeError("Invalid hook callback specified for game event \"%s\"", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CreateEvent(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
IGameEvent *pEvent;
|
||||||
|
EventInfo *pInfo;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
pContext->LocalToString(params[1], &name);
|
||||||
|
|
||||||
|
pEvent = gameevents->CreateEvent(name, true);
|
||||||
|
|
||||||
|
if (pEvent)
|
||||||
|
{
|
||||||
|
pInfo = new EventInfo;
|
||||||
|
pInfo->pEvent = pEvent;
|
||||||
|
pInfo->canDelete = true;
|
||||||
|
|
||||||
|
return g_HandleSys.CreateHandle(g_EventManager.GetHandleType(), pInfo, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_FireEvent(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((params[3] & EVENT_PASSTHRU_ALL) == false)
|
||||||
|
{
|
||||||
|
/* Set whether or not SourceMod plugins should be notified */
|
||||||
|
g_EventManager.SetNotifyState(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fire game event */
|
||||||
|
gameevents->FireEvent(pInfo->pEvent, params[2] ? true : false);
|
||||||
|
|
||||||
|
pInfo->canDelete = false;
|
||||||
|
|
||||||
|
/* Free handle on game event */
|
||||||
|
HandleSecurity sec = { pContext->GetIdentity(), g_pCoreIdent };
|
||||||
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
|
||||||
|
/* Free EventInfo memory */
|
||||||
|
delete pInfo;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_CancelCreatedEvent(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
gameevents->FreeEvent(pInfo->pEvent);
|
||||||
|
|
||||||
|
// Free GameEventInfo memory
|
||||||
|
delete pInfo;
|
||||||
|
|
||||||
|
// Free handle on game event
|
||||||
|
HandleSecurity sec = { pContext->GetIdentity(), g_pCoreIdent };
|
||||||
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_GetEventName(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pEvent->GetName(), NULL);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_GetEventBool(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
return pInfo->pEvent->GetBool(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_GetEventInt(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
return pInfo->pEvent->GetInt(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_GetEventFloat(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
float value = pInfo->pEvent->GetFloat(key);
|
||||||
|
|
||||||
|
return sp_ftoc(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_GetEventString(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
pContext->StringToLocalUTF8(params[3], params[4], pInfo->pEvent->GetString(key), NULL);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_SetEventBool(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
pInfo->pEvent->SetBool(key, params[3] ? true : false);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_SetEventInt(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
pInfo->pEvent->SetInt(key, params[3]);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_SetEventFloat(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
|
float value = sp_ctof(params[3]);
|
||||||
|
pInfo->pEvent->SetFloat(key, value);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell_t sm_SetEventString(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 GameEvent Handle %x (error %d)", hndl, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *key, *value;
|
||||||
|
pContext->LocalToString(params[2], &key);
|
||||||
|
pContext->LocalToString(params[3], &value);
|
||||||
|
|
||||||
|
pInfo->pEvent->SetString(key, value);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_NATIVES(gameEventNatives)
|
||||||
|
{
|
||||||
|
{"HookEvent", sm_HookEvent},
|
||||||
|
{"UnhookEvent", sm_UnhookEvent},
|
||||||
|
{"CreateEvent", sm_CreateEvent},
|
||||||
|
{"FireEvent", sm_FireEvent},
|
||||||
|
{"CancelCreatedEvent", sm_CancelCreatedEvent},
|
||||||
|
{"GetEventName", sm_GetEventName},
|
||||||
|
{"GetEventBool", sm_GetEventBool},
|
||||||
|
{"GetEventInt", sm_GetEventInt},
|
||||||
|
{"GetEventFloat", sm_GetEventFloat},
|
||||||
|
{"GetEventString", sm_GetEventString},
|
||||||
|
{"SetEventBool", sm_SetEventBool},
|
||||||
|
{"SetEventInt", sm_SetEventInt},
|
||||||
|
{"SetEventFloat", sm_SetEventFloat},
|
||||||
|
{"SetEventString", sm_SetEventString},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
@ -207,7 +207,7 @@ native GetCmdArgString(String:buffer[], maxlength);
|
|||||||
* @param name Name of new convar.
|
* @param name Name of new convar.
|
||||||
* @param defaultValue String containing the default value of new convar.
|
* @param defaultValue String containing the default value of new convar.
|
||||||
* @param helpText Optional description of the convar.
|
* @param helpText Optional description of the convar.
|
||||||
* @param flags Optional bitstream of flags determining how the convar should be handled. (See FCVAR_* constants for more details)
|
* @param flags Optional bitstring of flags determining how the convar should be handled. See FCVAR_* constants for more details.
|
||||||
* @param hasMin Optional boolean that determines if the convar has a minimum value.
|
* @param hasMin Optional boolean that determines if the convar has a minimum value.
|
||||||
* @param min Minimum floating point value that the convar can have if hasMin is true.
|
* @param min Minimum floating point value that the convar can have if hasMin is true.
|
||||||
* @param hasMax Optional boolean that determines if the convar has a maximum value.
|
* @param hasMax Optional boolean that determines if the convar has a maximum value.
|
||||||
|
205
plugins/include/events.inc
Normal file
205
plugins/include/events.inc
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* ===============================================================
|
||||||
|
* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
|
||||||
|
* ===============================================================
|
||||||
|
*
|
||||||
|
* This file is part of the SourceMod/SourcePawn SDK. This file may only be used
|
||||||
|
* or modified under the Terms and Conditions of its License Agreement, which is found
|
||||||
|
* in LICENSE.txt. The Terms and Conditions for making SourceMod extensions/plugins
|
||||||
|
* may change at any time. To view the latest information, see:
|
||||||
|
* http://www.sourcemod.net/license.php
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined _events_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _events_included
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags for firing game events
|
||||||
|
*/
|
||||||
|
#define EVENT_PASSTHRU_ALL (1<<1) /**< Event will pass through other SourceMM plugins AND SourceMod */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event hook modes determining how hooking should be handled
|
||||||
|
*/
|
||||||
|
enum EventHookMode
|
||||||
|
{
|
||||||
|
EventHookMode_Pre, /**< Hook callback fired before event is fired */
|
||||||
|
EventHookMode_Post, /**< Hook callback fired after event is fired */
|
||||||
|
EventHookMode_PostNoCopy /**< Hook callback fired after event is fired, but event data won't be copied */
|
||||||
|
};
|
||||||
|
|
||||||
|
funcenum EventHook
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Called when a game event is fired.
|
||||||
|
*
|
||||||
|
* @param event Handle to event. This could be INVALID_HANDLE if every plugin hooking
|
||||||
|
* this event has set the hook mode EventHookMode_PostNoCopy.
|
||||||
|
* @param name String containing the name of the event.
|
||||||
|
* @param dontBroadcast True if event was not broadcast to clients, false otherwise.
|
||||||
|
* @return Ignored for post hooks. Plugin_Handled will block event if hooked as pre.
|
||||||
|
*/
|
||||||
|
Action:public(Handle:event, const String:name[], bool:dontBroadcast),
|
||||||
|
/**
|
||||||
|
* Called when a game event is fired.
|
||||||
|
*
|
||||||
|
* @param event Handle to event. This could be INVALID_HANDLE if every plugin hooking
|
||||||
|
* this event has set the hook mode EventHookMode_PostNoCopy.
|
||||||
|
* @param name String containing the name of the event.
|
||||||
|
* @param dontBroadcast True if event was not broadcast to clients, false otherwise.
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
public(Handle:event, const String:name[], bool:dontBroadcast),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a hook for when a game event is fired.
|
||||||
|
*
|
||||||
|
* @param name Name of event.
|
||||||
|
* @param callback An EventHook function pointer.
|
||||||
|
* @param mode Optional EventHookMode determining the type of hook.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid event name or invalid callback function.
|
||||||
|
*/
|
||||||
|
native HookEvent(const String:name[], EventHook:callback, EventHookMode:mode=EventHookMode_Post);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a hook for when a game event is fired.
|
||||||
|
*
|
||||||
|
* @param name Name of event.
|
||||||
|
* @param callback An EventHook function pointer.
|
||||||
|
* @param mode Optional EventHookMode determining the type of hook.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid callback function or no active hook for specified event.
|
||||||
|
*/
|
||||||
|
native UnhookEvent(const String:name[], EventHook:callback, EventHookMode:mode=EventHookMode_Post);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a game event to be fired later.
|
||||||
|
*
|
||||||
|
* @param name Name of event.
|
||||||
|
* @return Handle to event or INVALID_HANDLE if event doesn't exist.
|
||||||
|
*/
|
||||||
|
native Handle:CreateEvent(const String:name[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires a game event.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param dontBroadcast Optional boolean that determines if event should be broadcast to clients.
|
||||||
|
* @param flags Optional bitstring flags. See EVENT_* constants for more details.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native FireEvent(Handle:event, bool:dontBroadcast=false, flags=0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels a previously created game event that has not been fired.
|
||||||
|
*
|
||||||
|
* @param event Handled to the event.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native CancelCreatedEvent(Handle:event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the boolean value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @return The boolean value of the specfied event key.
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native bool:GetEventBool(Handle:event, const String:key[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the boolean value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @param value New boolean value.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native SetEventBool(Handle:event, const String:key[], bool:value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the integer value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @return The integer value of the specfied event key.
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native GetEventInt(Handle:event, const String:key[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the integer value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @param value New integer value.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native SetEventInt(Handle:event, const String:key[], value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @return The floating point value of the specfied event key.
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native Float:GetEventFloat(Handle:event, const String:key[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the floating point value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @param value New floating point value.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native SetEventFloat(Handle:event, const String:key[], Float:value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the string value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @param value Buffer to store the value of the specified event key.
|
||||||
|
* @param maxlength Maximum length of string buffer.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native GetEventString(Handle:event, const String:key[], String:value[], maxlength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string value of a game event's key.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param key Name of event key.
|
||||||
|
* @param value New string value.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native SetEventString(Handle:event, const String:key[], const String:value[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the name of a game event.
|
||||||
|
*
|
||||||
|
* @param event Handle to the event.
|
||||||
|
* @param value Buffer to store the name of the event.
|
||||||
|
* @param maxlength Maximum length of string buffer.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid or corrupt Handle.
|
||||||
|
*/
|
||||||
|
native GetEventName(Handle:event, String:name[], maxlength);
|
@ -37,6 +37,8 @@ struct Plugin
|
|||||||
#include <bitbuffer>
|
#include <bitbuffer>
|
||||||
#include <sorting>
|
#include <sorting>
|
||||||
#include <clients>
|
#include <clients>
|
||||||
|
#include <usermessages>
|
||||||
|
#include <events>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare this as a struct in your plugin to expose its information.
|
* Declare this as a struct in your plugin to expose its information.
|
||||||
@ -219,6 +221,5 @@ native GetGameDescription(String:buffer[], maxlength, bool:original=false);
|
|||||||
*/
|
*/
|
||||||
native GetCurrentMap(String:buffer[], maxlength);
|
native GetCurrentMap(String:buffer[], maxlength);
|
||||||
|
|
||||||
#include <usermessages>
|
|
||||||
#include <helpers>
|
#include <helpers>
|
||||||
#include <entity>
|
#include <entity>
|
||||||
|
Loading…
Reference in New Issue
Block a user