Improved user message interception API (bug 3631, r=pred).
This commit is contained in:
parent
0c028ca9d0
commit
96a3671bb6
@ -273,13 +273,13 @@ bool CPlugin::UpdateInfo()
|
|||||||
|
|
||||||
base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&info);
|
base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&info);
|
||||||
m_FileVersion = info->version;
|
m_FileVersion = info->version;
|
||||||
if (m_FileVersion >= 3)
|
if (m_FileVersion >= 4)
|
||||||
{
|
{
|
||||||
base->LocalToString(info->date, (char **)&pDate);
|
base->LocalToString(info->date, (char **)&pDate);
|
||||||
base->LocalToString(info->time, (char **)&pTime);
|
base->LocalToString(info->time, (char **)&pTime);
|
||||||
UTIL_Format(m_DateTime, sizeof(m_DateTime), "%s %s", pDate, pTime);
|
UTIL_Format(m_DateTime, sizeof(m_DateTime), "%s %s", pDate, pTime);
|
||||||
}
|
}
|
||||||
if (m_FileVersion > 4)
|
if (m_FileVersion > 5)
|
||||||
{
|
{
|
||||||
base->LocalToString(info->filevers, (char **)&pFileVers);
|
base->LocalToString(info->filevers, (char **)&pFileVers);
|
||||||
SetErrorState(Plugin_Failed, "Newer SourceMod required (%s or higher)", pFileVers);
|
SetErrorState(Plugin_Failed, "Newer SourceMod required (%s or higher)", pFileVers);
|
||||||
|
@ -205,7 +205,31 @@ bool UserMessages::EndMessage()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UserMessages::HookUserMessage2(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept)
|
||||||
|
{
|
||||||
|
return InternalHook(msg_id, pListener, intercept, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserMessages::UnhookUserMessage2(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept)
|
||||||
|
{
|
||||||
|
return InternalUnhook(msg_id, pListener, intercept, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
|
bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
|
||||||
|
{
|
||||||
|
return InternalHook(msg_id, pListener, intercept, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
|
||||||
|
{
|
||||||
|
return InternalUnhook(msg_id, pListener, intercept, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
|
||||||
{
|
{
|
||||||
if (msg_id < 0 || msg_id >= 255)
|
if (msg_id < 0 || msg_id >= 255)
|
||||||
{
|
{
|
||||||
@ -224,6 +248,7 @@ bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener,
|
|||||||
pInfo->Callback = pListener;
|
pInfo->Callback = pListener;
|
||||||
pInfo->IsHooked = false;
|
pInfo->IsHooked = false;
|
||||||
pInfo->KillMe = false;
|
pInfo->KillMe = false;
|
||||||
|
pInfo->IsNew = isNew;
|
||||||
|
|
||||||
if (!m_HookCount++)
|
if (!m_HookCount++)
|
||||||
{
|
{
|
||||||
@ -243,8 +268,8 @@ bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
|
bool UserMessages::InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
|
||||||
{
|
{
|
||||||
MsgList *pList;
|
MsgList *pList;
|
||||||
MsgIter iter;
|
MsgIter iter;
|
||||||
ListenerInfo *pInfo;
|
ListenerInfo *pInfo;
|
||||||
@ -259,7 +284,7 @@ bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener
|
|||||||
for (iter=pList->begin(); iter!=pList->end(); iter++)
|
for (iter=pList->begin(); iter!=pList->end(); iter++)
|
||||||
{
|
{
|
||||||
pInfo = (*iter);
|
pInfo = (*iter);
|
||||||
if (pInfo->Callback == pListener)
|
if (pInfo->Callback == pListener && pInfo->IsNew == isNew)
|
||||||
{
|
{
|
||||||
if (pInfo->IsHooked)
|
if (pInfo->IsHooked)
|
||||||
{
|
{
|
||||||
@ -339,7 +364,7 @@ bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_ty
|
|||||||
|
|
||||||
void UserMessages::OnMessageEnd_Post()
|
void UserMessages::OnMessageEnd_Post()
|
||||||
{
|
{
|
||||||
if (!m_InHook || m_BlockEndPost)
|
if (!m_InHook)
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
@ -354,8 +379,16 @@ void UserMessages::OnMessageEnd_Post()
|
|||||||
for (iter=pList->begin(); iter!=pList->end(); )
|
for (iter=pList->begin(); iter!=pList->end(); )
|
||||||
{
|
{
|
||||||
pInfo = (*iter);
|
pInfo = (*iter);
|
||||||
|
if (m_BlockEndPost && !pInfo->IsNew)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pInfo->IsHooked = true;
|
pInfo->IsHooked = true;
|
||||||
pInfo->Callback->OnUserMessageSent(m_CurId);
|
pInfo->Callback->OnUserMessageSent(m_CurId);
|
||||||
|
if (pInfo->IsNew)
|
||||||
|
{
|
||||||
|
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
|
||||||
|
}
|
||||||
|
|
||||||
if (pInfo->KillMe)
|
if (pInfo->KillMe)
|
||||||
{
|
{
|
||||||
@ -373,8 +406,16 @@ void UserMessages::OnMessageEnd_Post()
|
|||||||
for (iter=pList->begin(); iter!=pList->end(); )
|
for (iter=pList->begin(); iter!=pList->end(); )
|
||||||
{
|
{
|
||||||
pInfo = (*iter);
|
pInfo = (*iter);
|
||||||
|
if (m_BlockEndPost && !pInfo->IsNew)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pInfo->IsHooked = true;
|
pInfo->IsHooked = true;
|
||||||
pInfo->Callback->OnUserMessageSent(m_CurId);
|
pInfo->Callback->OnUserMessageSent(m_CurId);
|
||||||
|
if (pInfo->IsNew)
|
||||||
|
{
|
||||||
|
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
|
||||||
|
}
|
||||||
|
|
||||||
if (pInfo->KillMe)
|
if (pInfo->KillMe)
|
||||||
{
|
{
|
||||||
@ -495,7 +536,6 @@ void UserMessages::OnMessageEnd_Pre()
|
|||||||
|
|
||||||
RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
|
RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
|
||||||
supercede:
|
supercede:
|
||||||
m_InHook = false;
|
|
||||||
m_BlockEndPost = true;
|
m_BlockEndPost = true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ struct ListenerInfo
|
|||||||
IUserMessageListener *Callback;
|
IUserMessageListener *Callback;
|
||||||
bool IsHooked;
|
bool IsHooked;
|
||||||
bool KillMe;
|
bool KillMe;
|
||||||
|
bool IsNew;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef List<ListenerInfo *> MsgList;
|
typedef List<ListenerInfo *> MsgList;
|
||||||
@ -71,6 +72,12 @@ public: //IUserMessages
|
|||||||
bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false);
|
bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false);
|
||||||
bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
|
bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
|
||||||
bool EndMessage();
|
bool EndMessage();
|
||||||
|
bool HookUserMessage2(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept=false);
|
||||||
|
bool UnhookUserMessage2(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept=false);
|
||||||
public:
|
public:
|
||||||
#if SOURCE_ENGINE == SE_LEFT4DEAD
|
#if SOURCE_ENGINE == SE_LEFT4DEAD
|
||||||
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
||||||
@ -82,6 +89,8 @@ public:
|
|||||||
void OnMessageEnd_Pre();
|
void OnMessageEnd_Pre();
|
||||||
void OnMessageEnd_Post();
|
void OnMessageEnd_Post();
|
||||||
private:
|
private:
|
||||||
|
bool InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
|
||||||
|
bool InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
|
||||||
void _DecRefCounter();
|
void _DecRefCounter();
|
||||||
private:
|
private:
|
||||||
List<ListenerInfo *> m_msgHooks[255];
|
List<ListenerInfo *> m_msgHooks[255];
|
||||||
|
@ -309,7 +309,7 @@ ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IR
|
|||||||
return static_cast<ResultType>(res);
|
return static_cast<ResultType>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MsgListenerWrapper::OnUserMessageSent(int msg_id)
|
void MsgListenerWrapper::OnPostUserMessage(int msg_id, bool sent)
|
||||||
{
|
{
|
||||||
if (!m_Notify)
|
if (!m_Notify)
|
||||||
{
|
{
|
||||||
@ -318,6 +318,7 @@ void MsgListenerWrapper::OnUserMessageSent(int msg_id)
|
|||||||
|
|
||||||
cell_t res;
|
cell_t res;
|
||||||
m_Notify->PushCell(msg_id);
|
m_Notify->PushCell(msg_id);
|
||||||
|
m_Notify->PushCell(sent ? 1 : 0);
|
||||||
m_Notify->Execute(&res);
|
m_Notify->Execute(&res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +491,7 @@ static cell_t smn_HookUserMessage(IPluginContext *pCtx, const cell_t *params)
|
|||||||
pListener = s_UsrMessageNatives.CreateListener(pCtx);
|
pListener = s_UsrMessageNatives.CreateListener(pCtx);
|
||||||
pListener->Initialize(msgid, pHook, pNotify, intercept);
|
pListener->Initialize(msgid, pHook, pNotify, intercept);
|
||||||
|
|
||||||
g_UserMsgs.HookUserMessage(msgid, pListener, intercept);
|
g_UserMsgs.HookUserMessage2(msgid, pListener, intercept);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -521,7 +522,7 @@ static cell_t smn_UnhookUserMessage(IPluginContext *pCtx, const cell_t *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pListener = (*iter);
|
pListener = (*iter);
|
||||||
if (!g_UserMsgs.UnhookUserMessage(msgid, pListener, intercept))
|
if (!g_UserMsgs.UnhookUserMessage2(msgid, pListener, intercept))
|
||||||
{
|
{
|
||||||
return pCtx->ThrowNativeError("Unable to unhook the current user message");
|
return pCtx->ThrowNativeError("Unable to unhook the current user message");
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
public: //IUserMessageListener
|
public: //IUserMessageListener
|
||||||
void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
||||||
ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
|
||||||
void OnUserMessageSent(int msg_id);
|
void OnPostUserMessage(int msg_id, bool sent);
|
||||||
private:
|
private:
|
||||||
size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
|
size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
|
||||||
private:
|
private:
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
#include <version>
|
#include <version>
|
||||||
|
|
||||||
/** If this gets changed, you need to update Core's check. */
|
/** If this gets changed, you need to update Core's check. */
|
||||||
#define SOURCEMOD_PLUGINAPI_VERSION 4
|
#define SOURCEMOD_PLUGINAPI_VERSION 5
|
||||||
|
|
||||||
struct PlVers
|
struct PlVers
|
||||||
{
|
{
|
||||||
|
@ -127,11 +127,12 @@ native EndMessage();
|
|||||||
functag public Action:MsgHook(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init);
|
functag public Action:MsgHook(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a message is finished sending.
|
* Called when a message hook has completed.
|
||||||
*
|
*
|
||||||
* @param msg_id Message index.
|
* @param msg_id Message index.
|
||||||
|
* @param sent True if message was sent, false if blocked.
|
||||||
*/
|
*/
|
||||||
functag public MsgSentNotify(UserMsg:msg_id);
|
functag public MsgPostHook(UserMsg:msg_id, bool:sent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooks a user message.
|
* Hooks a user message.
|
||||||
@ -145,7 +146,7 @@ functag public MsgSentNotify(UserMsg:msg_id);
|
|||||||
* @noreturn
|
* @noreturn
|
||||||
* @error Invalid message index.
|
* @error Invalid message index.
|
||||||
*/
|
*/
|
||||||
native HookUserMessage(UserMsg:msg_id, MsgHook:hook, bool:intercept=false, MsgSentNotify:notify=MsgSentNotify:-1);
|
native HookUserMessage(UserMsg:msg_id, MsgHook:hook, bool:intercept=false, MsgPostHook:post=MsgPostHook:-1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes one usermessage hook.
|
* Removes one usermessage hook.
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define SMINTERFACE_USERMSGS_NAME "IUserMessages"
|
#define SMINTERFACE_USERMSGS_NAME "IUserMessages"
|
||||||
#define SMINTERFACE_USERMSGS_VERSION 1
|
#define SMINTERFACE_USERMSGS_VERSION 2
|
||||||
|
|
||||||
namespace SourceMod
|
namespace SourceMod
|
||||||
{
|
{
|
||||||
@ -81,11 +81,35 @@ namespace SourceMod
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a hooked user message is sent, regardless of the hook type.
|
* @brief Called when a hooked user message is sent, regardless of the hook type.
|
||||||
|
*
|
||||||
|
* Note: This is called regardless of the API version, though it only happens if the
|
||||||
|
* message is successfully sent.
|
||||||
|
*
|
||||||
* @param msg_id Message Id.
|
* @param msg_id Message Id.
|
||||||
*/
|
*/
|
||||||
virtual void OnUserMessageSent(int msg_id)
|
virtual void OnUserMessageSent(int msg_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the user message API version.
|
||||||
|
*/
|
||||||
|
virtual unsigned int GetUserMessageAPIVersion()
|
||||||
|
{
|
||||||
|
return SMINTERFACE_USERMSGS_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a hooked user message hook is finished, regardless of the hook type.
|
||||||
|
*
|
||||||
|
* Note: this is only called if hooked using the new API (version 2 or greater).
|
||||||
|
*
|
||||||
|
* @param msg_id Message Id.
|
||||||
|
* @param sent True if message was sent, false if blocked.
|
||||||
|
*/
|
||||||
|
virtual void OnPostUserMessage(int msg_id, bool sent)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USERMSG_RELIABLE (1<<2) /**< Message will be set to reliable */
|
#define USERMSG_RELIABLE (1<<2) /**< Message will be set to reliable */
|
||||||
@ -123,17 +147,22 @@ namespace SourceMod
|
|||||||
* @param intercept If true, message will be intercepted rather than merely hooked.
|
* @param intercept If true, message will be intercepted rather than merely hooked.
|
||||||
* @return True on success, false otherwise.
|
* @return True on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false) =0;
|
virtual bool HookUserMessage(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept=false) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unhooks a user message.
|
* @brief Unhooks a user message.
|
||||||
*
|
*
|
||||||
* @param msg_id Message Id.
|
* @param msg_id Message Id.
|
||||||
* @param pListener Pointer to an IUserMessageListener.
|
* @param pListener Pointer to an IUserMessageListener.
|
||||||
* @param intercept If true, removed message will from interception pool rather than normal hook pool.
|
* @param intercept If true, message is removed from interception pool rather than the
|
||||||
|
* normal hook pool.
|
||||||
* @return True on success, false otherwise.
|
* @return True on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false) =0;
|
virtual bool UnhookUserMessage(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept=false) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wrapper around UserMessageBegin for more options.
|
* @brief Wrapper around UserMessageBegin for more options.
|
||||||
@ -144,13 +173,41 @@ namespace SourceMod
|
|||||||
* @param flags Flags to use for sending the message.
|
* @param flags Flags to use for sending the message.
|
||||||
* @return bf_write structure to write message with, or NULL on failure.
|
* @return bf_write structure to write message with, or NULL on failure.
|
||||||
*/
|
*/
|
||||||
virtual bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags) =0;
|
virtual bf_write *StartMessage(int msg_id,
|
||||||
|
const cell_t players[],
|
||||||
|
unsigned int playersNum,
|
||||||
|
int flags) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wrapper around UserMessageEnd for use with StartMessage().
|
* @brief Wrapper around UserMessageEnd for use with StartMessage().
|
||||||
* @return True on success, false otherwise.
|
* @return True on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool EndMessage() =0;
|
virtual bool EndMessage() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a hook on a user message using the newer API (OnPostUserMessage).
|
||||||
|
*
|
||||||
|
* @param msg_id Message Id.
|
||||||
|
* @param pListener Pointer to an IUserMessageListener.
|
||||||
|
* @param intercept If true, message will be intercepted rather than merely hooked.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool HookUserMessage2(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept=false) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unhooks a user message using the newer API (OnPostUserMessage).
|
||||||
|
*
|
||||||
|
* @param msg_id Message Id.
|
||||||
|
* @param pListener Pointer to an IUserMessageListener.
|
||||||
|
* @param intercept If true, message is removed from interception pool rather than the
|
||||||
|
* normal hook pool.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool UnhookUserMessage2(int msg_id,
|
||||||
|
IUserMessageListener *pListener,
|
||||||
|
bool intercept=false) =0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user