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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
@ -97,21 +97,21 @@ void CConVarManager::OnPluginDestroyed(IPlugin *plugin)
|
||||
void CConVarManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
ConVarInfo *info;
|
||||
ConVar *cvar = static_cast<ConVar *>(object);
|
||||
ConVar *pConVar = static_cast<ConVar *>(object);
|
||||
|
||||
// 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 (info->sourceMod)
|
||||
{
|
||||
// Delete string allocations
|
||||
delete [] cvar->GetName();
|
||||
delete [] cvar->GetDefault();
|
||||
delete [] cvar->GetHelpText();
|
||||
delete [] pConVar->GetName();
|
||||
delete [] pConVar->GetDefault();
|
||||
delete [] pConVar->GetHelpText();
|
||||
|
||||
// Then unregister it
|
||||
g_SMAPI->UnregisterConCmdBase(g_PLAPI, cvar);
|
||||
// Then unlink it from SourceMM
|
||||
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
|
||||
for (size_t i = 0; i < cvarList->size(); i++, id++)
|
||||
{
|
||||
ConVar *cvar = (*cvarList)[i];
|
||||
g_RootMenu.ConsolePrint(" %02d \"%s\" = \"%s\"", id, cvar->GetName(), cvar->GetString());
|
||||
ConVar *pConVar = (*cvarList)[i];
|
||||
g_RootMenu.ConsolePrint(" %02d \"%s\" = \"%s\"", id, pConVar->GetName(), pConVar->GetString());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ConVar *cvar = NULL;
|
||||
ConVar *pConVar = NULL;
|
||||
ConVarInfo *info = NULL;
|
||||
CVector<ConVar *> *cvarList = NULL;
|
||||
Handle_t hndl = 0;
|
||||
|
||||
// Find out if the convar exists already
|
||||
cvar = icvar->FindVar(name);
|
||||
pConVar = icvar->FindVar(name);
|
||||
|
||||
// If the convar already exists...
|
||||
if (cvar != NULL)
|
||||
if (pConVar != NULL)
|
||||
{
|
||||
// First check if we already have a handle to it
|
||||
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;
|
||||
} else {
|
||||
// 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->handle = hndl;
|
||||
info->sourceMod = false;
|
||||
info->changeForward = NULL;
|
||||
info->origCallback = cvar->GetCallback();
|
||||
info->origCallback = pConVar->GetCallback();
|
||||
|
||||
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!
|
||||
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
|
||||
IPlugin *pl = g_PluginSys.FindPluginByContext(pContext->GetContext());
|
||||
|
||||
// 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 (cvarList == NULL)
|
||||
{
|
||||
// Then create it
|
||||
cvarList = new CVector<ConVar *>;
|
||||
pl->SetProperty("ConVar", cvarList);
|
||||
pl->SetProperty("ConVarList", cvarList);
|
||||
}
|
||||
|
||||
// Add new convar to plugin's list
|
||||
cvarList->push_back(cvar);
|
||||
cvarList->push_back(pConVar);
|
||||
|
||||
// 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->handle = hndl;
|
||||
@ -248,15 +248,15 @@ Handle_t CConVarManager::CreateConVar(IPluginContext *pContext, const char *name
|
||||
|
||||
Handle_t CConVarManager::FindConVar(const char *name)
|
||||
{
|
||||
ConVar *cvar = NULL;
|
||||
ConVar *pConVar = NULL;
|
||||
ConVarInfo *info = NULL;
|
||||
Handle_t hndl = 0;
|
||||
|
||||
// Search for convar
|
||||
cvar = icvar->FindVar(name);
|
||||
pConVar = icvar->FindVar(name);
|
||||
|
||||
// If it doesn't exist, then return an invalid handle
|
||||
if (cvar == NULL)
|
||||
if (pConVar == NULL)
|
||||
{
|
||||
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
|
||||
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->handle = hndl;
|
||||
info->sourceMod = false;
|
||||
info->changeForward = NULL;
|
||||
info->origCallback = cvar->GetCallback();
|
||||
info->origCallback = pConVar->GetCallback();
|
||||
|
||||
m_ConVars.push_back(info);
|
||||
|
||||
@ -285,7 +285,7 @@ Handle_t CConVarManager::FindConVar(const char *name)
|
||||
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);
|
||||
IChangeableForward *fwd = NULL;
|
||||
@ -300,7 +300,7 @@ void CConVarManager::HookConVarChange(IPluginContext *pContext, ConVar *cvar, fu
|
||||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// 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
|
||||
info->changeForward = fwd;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
IChangeableForward *fwd = NULL;
|
||||
@ -343,7 +343,7 @@ void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *cvar,
|
||||
}
|
||||
|
||||
// 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
|
||||
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 (fwd == NULL)
|
||||
{
|
||||
pContext->ThrowNativeError("Convar \"%s\" has no active hook", cvar->GetName());
|
||||
pContext->ThrowNativeError("Convar \"%s\" has no active hook", pConVar->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the function from the forward's list
|
||||
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;
|
||||
}
|
||||
|
||||
@ -370,15 +370,15 @@ void CConVarManager::UnhookConVarChange(IPluginContext *pContext, ConVar *cvar,
|
||||
info->changeForward = NULL;
|
||||
|
||||
// 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 (strcmp(cvar->GetString(), oldValue) == 0)
|
||||
if (strcmp(pConVar->GetString(), oldValue) == 0)
|
||||
{
|
||||
// Exit early in order to not trigger callbacks
|
||||
return;
|
||||
@ -388,7 +388,7 @@ void CConVarManager::OnConVarChanged(ConVar *cvar, const char *oldValue)
|
||||
ConVarInfo *info;
|
||||
|
||||
// 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;
|
||||
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 (origCallback)
|
||||
{
|
||||
origCallback(cvar, oldValue);
|
||||
origCallback(pConVar, oldValue);
|
||||
}
|
||||
|
||||
// Now call forwards in plugins that have hooked this
|
||||
fwd->PushCell(info->handle);
|
||||
fwd->PushString(cvar->GetString());
|
||||
fwd->PushString(pConVar->GetString());
|
||||
fwd->PushString(oldValue);
|
||||
fwd->Execute(NULL);
|
||||
}
|
||||
|
@ -85,17 +85,17 @@ public:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void UnhookConVarChange(IPluginContext *pContext, ConVar *cvar, funcid_t funcid);
|
||||
void UnhookConVarChange(IPluginContext *pContext, ConVar *pConVar, funcid_t funcid);
|
||||
private:
|
||||
/**
|
||||
* Static callback that Valve's ConVar class executes when the convar's value changes.
|
||||
*/
|
||||
static void OnConVarChanged(ConVar *cvar, const char *oldValue);
|
||||
* Static callback that Valve's ConVar class executes when the convar's value changes.
|
||||
*/
|
||||
static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
|
||||
private:
|
||||
HandleType_t m_ConVarType;
|
||||
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"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\EventManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sm_autonatives.cpp"
|
||||
>
|
||||
@ -317,6 +321,10 @@
|
||||
RelativePath="..\CUserMessages.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\EventManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sm_autonatives.h"
|
||||
>
|
||||
@ -689,6 +697,10 @@
|
||||
RelativePath="..\smn_entities.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\smn_events.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -79,15 +79,15 @@ static cell_t sm_UnhookConVarChange(IPluginContext *pContext, const cell_t *para
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -96,30 +96,30 @@ static cell_t sm_GetConVarBool(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
return cvar->GetInt();
|
||||
return pConVar->GetInt();
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
cvar->SetValue(params[2]);
|
||||
pConVar->SetValue(params[2]);
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
float value = cvar->GetFloat();
|
||||
float value = pConVar->GetFloat();
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
float value = sp_ctof(params[2]);
|
||||
cvar->SetValue(value);
|
||||
pConVar->SetValue(value);
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -196,9 +196,9 @@ static cell_t sm_SetConVarString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
pContext->LocalToString(params[2], &value);
|
||||
|
||||
cvar->SetValue(value);
|
||||
pConVar->SetValue(value);
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
cvar->SetFlags(params[2]);
|
||||
pConVar->SetFlags(params[2]);
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
hasMin = cvar->GetMin(min);
|
||||
hasMin = pConVar->GetMin(min);
|
||||
*addr = sp_ftoc(min);
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
hasMax = cvar->GetMax(max);
|
||||
hasMax = pConVar->GetMax(max);
|
||||
*addr = sp_ftoc(max);
|
||||
|
||||
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]);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -313,15 +313,15 @@ static cell_t sm_ResetConVar(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid ConVar Handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
cvar->Revert();
|
||||
pConVar->Revert();
|
||||
|
||||
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 defaultValue String containing the default value of new 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 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.
|
||||
|
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 <sorting>
|
||||
#include <clients>
|
||||
#include <usermessages>
|
||||
#include <events>
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#include <usermessages>
|
||||
#include <helpers>
|
||||
#include <entity>
|
||||
|
Loading…
Reference in New Issue
Block a user