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);
|
||||
m_FileVersion = info->version;
|
||||
if (m_FileVersion >= 3)
|
||||
if (m_FileVersion >= 4)
|
||||
{
|
||||
base->LocalToString(info->date, (char **)&pDate);
|
||||
base->LocalToString(info->time, (char **)&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);
|
||||
SetErrorState(Plugin_Failed, "Newer SourceMod required (%s or higher)", pFileVers);
|
||||
|
@ -205,7 +205,31 @@ bool UserMessages::EndMessage()
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -224,6 +248,7 @@ bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener,
|
||||
pInfo->Callback = pListener;
|
||||
pInfo->IsHooked = false;
|
||||
pInfo->KillMe = false;
|
||||
pInfo->IsNew = isNew;
|
||||
|
||||
if (!m_HookCount++)
|
||||
{
|
||||
@ -243,8 +268,8 @@ bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener,
|
||||
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;
|
||||
MsgIter iter;
|
||||
ListenerInfo *pInfo;
|
||||
@ -259,7 +284,7 @@ bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener
|
||||
for (iter=pList->begin(); iter!=pList->end(); iter++)
|
||||
{
|
||||
pInfo = (*iter);
|
||||
if (pInfo->Callback == pListener)
|
||||
if (pInfo->Callback == pListener && pInfo->IsNew == isNew)
|
||||
{
|
||||
if (pInfo->IsHooked)
|
||||
{
|
||||
@ -339,7 +364,7 @@ bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_ty
|
||||
|
||||
void UserMessages::OnMessageEnd_Post()
|
||||
{
|
||||
if (!m_InHook || m_BlockEndPost)
|
||||
if (!m_InHook)
|
||||
{
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
@ -354,8 +379,16 @@ void UserMessages::OnMessageEnd_Post()
|
||||
for (iter=pList->begin(); iter!=pList->end(); )
|
||||
{
|
||||
pInfo = (*iter);
|
||||
if (m_BlockEndPost && !pInfo->IsNew)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
pInfo->IsHooked = true;
|
||||
pInfo->Callback->OnUserMessageSent(m_CurId);
|
||||
if (pInfo->IsNew)
|
||||
{
|
||||
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
|
||||
}
|
||||
|
||||
if (pInfo->KillMe)
|
||||
{
|
||||
@ -373,8 +406,16 @@ void UserMessages::OnMessageEnd_Post()
|
||||
for (iter=pList->begin(); iter!=pList->end(); )
|
||||
{
|
||||
pInfo = (*iter);
|
||||
if (m_BlockEndPost && !pInfo->IsNew)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
pInfo->IsHooked = true;
|
||||
pInfo->Callback->OnUserMessageSent(m_CurId);
|
||||
if (pInfo->IsNew)
|
||||
{
|
||||
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
|
||||
}
|
||||
|
||||
if (pInfo->KillMe)
|
||||
{
|
||||
@ -495,7 +536,6 @@ void UserMessages::OnMessageEnd_Pre()
|
||||
|
||||
RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
|
||||
supercede:
|
||||
m_InHook = false;
|
||||
m_BlockEndPost = true;
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ struct ListenerInfo
|
||||
IUserMessageListener *Callback;
|
||||
bool IsHooked;
|
||||
bool KillMe;
|
||||
bool IsNew;
|
||||
};
|
||||
|
||||
typedef List<ListenerInfo *> MsgList;
|
||||
@ -71,6 +72,12 @@ public: //IUserMessages
|
||||
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);
|
||||
bool EndMessage();
|
||||
bool HookUserMessage2(int msg_id,
|
||||
IUserMessageListener *pListener,
|
||||
bool intercept=false);
|
||||
bool UnhookUserMessage2(int msg_id,
|
||||
IUserMessageListener *pListener,
|
||||
bool intercept=false);
|
||||
public:
|
||||
#if SOURCE_ENGINE == SE_LEFT4DEAD
|
||||
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
||||
@ -82,6 +89,8 @@ public:
|
||||
void OnMessageEnd_Pre();
|
||||
void OnMessageEnd_Post();
|
||||
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();
|
||||
private:
|
||||
List<ListenerInfo *> m_msgHooks[255];
|
||||
|
@ -309,7 +309,7 @@ ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IR
|
||||
return static_cast<ResultType>(res);
|
||||
}
|
||||
|
||||
void MsgListenerWrapper::OnUserMessageSent(int msg_id)
|
||||
void MsgListenerWrapper::OnPostUserMessage(int msg_id, bool sent)
|
||||
{
|
||||
if (!m_Notify)
|
||||
{
|
||||
@ -318,6 +318,7 @@ void MsgListenerWrapper::OnUserMessageSent(int msg_id)
|
||||
|
||||
cell_t res;
|
||||
m_Notify->PushCell(msg_id);
|
||||
m_Notify->PushCell(sent ? 1 : 0);
|
||||
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->Initialize(msgid, pHook, pNotify, intercept);
|
||||
|
||||
g_UserMsgs.HookUserMessage(msgid, pListener, intercept);
|
||||
g_UserMsgs.HookUserMessage2(msgid, pListener, intercept);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -521,7 +522,7 @@ static cell_t smn_UnhookUserMessage(IPluginContext *pCtx, const cell_t *params)
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
public: //IUserMessageListener
|
||||
void OnUserMessage(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:
|
||||
size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
|
||||
private:
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <version>
|
||||
|
||||
/** If this gets changed, you need to update Core's check. */
|
||||
#define SOURCEMOD_PLUGINAPI_VERSION 4
|
||||
#define SOURCEMOD_PLUGINAPI_VERSION 5
|
||||
|
||||
struct PlVers
|
||||
{
|
||||
|
@ -127,11 +127,12 @@ native EndMessage();
|
||||
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 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.
|
||||
@ -145,7 +146,7 @@ functag public MsgSentNotify(UserMsg:msg_id);
|
||||
* @noreturn
|
||||
* @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.
|
||||
|
@ -44,7 +44,7 @@
|
||||
*/
|
||||
|
||||
#define SMINTERFACE_USERMSGS_NAME "IUserMessages"
|
||||
#define SMINTERFACE_USERMSGS_VERSION 1
|
||||
#define SMINTERFACE_USERMSGS_VERSION 2
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
@ -81,11 +81,35 @@ namespace SourceMod
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
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 */
|
||||
@ -123,17 +147,22 @@ namespace SourceMod
|
||||
* @param intercept If true, message will be intercepted rather than merely hooked.
|
||||
* @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.
|
||||
*
|
||||
* @param msg_id Message Id.
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
@ -144,13 +173,41 @@ namespace SourceMod
|
||||
* @param flags Flags to use for sending the message.
|
||||
* @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().
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
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