Added part of amb1604: unregister_message - OH GOD I HOPE I DIDNT BREAK IT
This commit is contained in:
parent
9100ec753c
commit
f410ea743d
|
@ -2,7 +2,8 @@
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
Message Msg;
|
Message Msg;
|
||||||
CVector<int> msgHooks[256];
|
//CVector<int> msgHooks[256];
|
||||||
|
RegisteredMessage msgHooks[256];
|
||||||
int msgBlocks[256] = {BLOCK_NOT};
|
int msgBlocks[256] = {BLOCK_NOT};
|
||||||
int msgDest;
|
int msgDest;
|
||||||
int msgType;
|
int msgType;
|
||||||
|
@ -16,7 +17,7 @@ void ClearMessages()
|
||||||
{
|
{
|
||||||
for (size_t i=0; i<MAX_MESSAGES; i++)
|
for (size_t i=0; i<MAX_MESSAGES; i++)
|
||||||
{
|
{
|
||||||
msgHooks[i].clear();
|
msgHooks[i].Clear();
|
||||||
msgBlocks[i] = BLOCK_NOT;
|
msgBlocks[i] = BLOCK_NOT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +201,7 @@ void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *e
|
||||||
inblock = true;
|
inblock = true;
|
||||||
msgType = msg_type;
|
msgType = msg_type;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
} else if (msgHooks[msg_type].size()) {
|
} else if (msgHooks[msg_type].Hooked()) {
|
||||||
inhook = true;
|
inhook = true;
|
||||||
msgDest = msg_dest;
|
msgDest = msg_dest;
|
||||||
msgType = msg_type;
|
msgType = msg_type;
|
||||||
|
@ -318,8 +319,8 @@ void C_WriteEntity(int iValue)
|
||||||
|
|
||||||
void C_MessageEnd(void)
|
void C_MessageEnd(void)
|
||||||
{
|
{
|
||||||
int mres = 0, mresB = 0;
|
int mres = 0;
|
||||||
unsigned int i = 0;
|
|
||||||
if (inblock)
|
if (inblock)
|
||||||
{
|
{
|
||||||
inblock = false;
|
inblock = false;
|
||||||
|
@ -329,12 +330,17 @@ void C_MessageEnd(void)
|
||||||
}
|
}
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
} else if (inhook) {
|
} else if (inhook) {
|
||||||
|
|
||||||
|
mres = msgHooks[msgType].Execute((cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
||||||
|
|
||||||
|
/*
|
||||||
for (i=0; i<msgHooks[msgType].size(); i++)
|
for (i=0; i<msgHooks[msgType].size(); i++)
|
||||||
{
|
{
|
||||||
mresB = executeForwards(msgHooks[msgType].at(i), (cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
mresB = executeForwards(msgHooks[msgType].at(i), (cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
||||||
if (mresB > mres)
|
if (mresB > mres)
|
||||||
mres = mresB;
|
mres = mresB;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
inhook = false;
|
inhook = false;
|
||||||
if (mres & 1)
|
if (mres & 1)
|
||||||
{
|
{
|
||||||
|
@ -477,7 +483,7 @@ static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
|
||||||
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||||
if (id != -1)
|
if (id != -1)
|
||||||
{
|
{
|
||||||
msgHooks[params[1]].push_back(id);
|
msgHooks[params[1]].AddHook(id);
|
||||||
return id;
|
return id;
|
||||||
} else {
|
} else {
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
|
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
|
||||||
|
@ -488,6 +494,29 @@ static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unregister_message(msgid, msghandle)
|
||||||
|
static cell AMX_NATIVE_CALL unregister_message(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
if (!Msg.Ready())
|
||||||
|
Msg.Init();
|
||||||
|
|
||||||
|
if (params[1]>0 && params[1] < 256)
|
||||||
|
{
|
||||||
|
int id = params[2];
|
||||||
|
if (id != -1)
|
||||||
|
{
|
||||||
|
msgHooks[params[1]].RemoveHook(id);
|
||||||
|
return id;
|
||||||
|
} else {
|
||||||
|
LogError(amx, AMX_ERR_NOTFOUND, "Invalid registered message handle");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_msg_block(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL set_msg_block(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
int msgid = params[1];
|
int msgid = params[1];
|
||||||
|
@ -775,6 +804,7 @@ AMX_NATIVE_INFO msg_Natives[] =
|
||||||
{"write_string", write_string},
|
{"write_string", write_string},
|
||||||
|
|
||||||
{"register_message", register_message},
|
{"register_message", register_message},
|
||||||
|
{"unregister_message", unregister_message},
|
||||||
|
|
||||||
{"set_msg_block", set_msg_block},
|
{"set_msg_block", set_msg_block},
|
||||||
{"get_msg_block", get_msg_block},
|
{"get_msg_block", get_msg_block},
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "amx.h"
|
#include "amx.h"
|
||||||
#include "CVector.h"
|
#include "CVector.h"
|
||||||
#include "CString.h"
|
#include "CString.h"
|
||||||
|
#include "sh_stack.h"
|
||||||
|
|
||||||
#define MAX_MESSAGES 255
|
#define MAX_MESSAGES 255
|
||||||
|
|
||||||
|
@ -15,6 +16,136 @@
|
||||||
#define BLOCK_ONCE 1
|
#define BLOCK_ONCE 1
|
||||||
#define BLOCK_SET 2
|
#define BLOCK_SET 2
|
||||||
|
|
||||||
|
class RegisteredMessage
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CVector<int> m_Forwards;
|
||||||
|
CStack<int> m_InExecution;
|
||||||
|
bool m_Cleanup;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisteredMessage() : m_Cleanup(false) { }
|
||||||
|
~RegisteredMessage() { this->Clear(); }
|
||||||
|
|
||||||
|
void AddHook(int fwd)
|
||||||
|
{
|
||||||
|
m_Forwards.push_back(fwd);
|
||||||
|
}
|
||||||
|
bool RemoveHook(int fwd)
|
||||||
|
{
|
||||||
|
// Don't erase a forward if we're in the middle of execution; this
|
||||||
|
// could throw off the iterator that is going through the forwards
|
||||||
|
// and executing them. Instead, unregister the forward and set it
|
||||||
|
// to -1 from within the vector.
|
||||||
|
if (m_InExecution.size())
|
||||||
|
{
|
||||||
|
this->m_Cleanup = true;
|
||||||
|
|
||||||
|
CVector<int>::iterator iter = m_Forwards.begin();
|
||||||
|
CVector<int>::iterator end = m_Forwards.end();
|
||||||
|
while (iter != end)
|
||||||
|
{
|
||||||
|
if (*iter == fwd)
|
||||||
|
{
|
||||||
|
if (*iter != -1)
|
||||||
|
{
|
||||||
|
unregisterSPForward(*iter);
|
||||||
|
}
|
||||||
|
*iter = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CVector<int>::iterator iter = m_Forwards.begin();
|
||||||
|
CVector<int>::iterator end = m_Forwards.end();
|
||||||
|
while (iter != end)
|
||||||
|
{
|
||||||
|
if (*iter == fwd)
|
||||||
|
{
|
||||||
|
if (fwd != -1)
|
||||||
|
{
|
||||||
|
unregisterSPForward(fwd);
|
||||||
|
|
||||||
|
m_Forwards.erase(iter);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// -1 could be in here more than once
|
||||||
|
m_Forwards.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
while (m_InExecution.size())
|
||||||
|
{
|
||||||
|
m_InExecution.pop();
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < m_Forwards.size(); i++)
|
||||||
|
{
|
||||||
|
int fwd = m_Forwards[i];
|
||||||
|
|
||||||
|
if (fwd != -1)
|
||||||
|
{
|
||||||
|
unregisterSPForward(m_Forwards[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Forwards.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
cell Execute(cell type, cell dest, cell entity)
|
||||||
|
{
|
||||||
|
m_InExecution.push(1);
|
||||||
|
cell res = 0;
|
||||||
|
cell thisres = 0;
|
||||||
|
for (size_t i = 0; i < m_Forwards.size(); i++)
|
||||||
|
{
|
||||||
|
int fwd = m_Forwards[i];
|
||||||
|
|
||||||
|
if (fwd != -1)
|
||||||
|
{
|
||||||
|
thisres = executeForwards(fwd, type, dest, entity);
|
||||||
|
if (thisres > res)
|
||||||
|
{
|
||||||
|
res = thisres;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_InExecution.pop();
|
||||||
|
|
||||||
|
if (m_InExecution.size() == 0 && m_Cleanup)
|
||||||
|
{
|
||||||
|
this->RemoveHook(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
bool Hooked() const
|
||||||
|
{
|
||||||
|
return m_Forwards.size() != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
enum msgtype
|
enum msgtype
|
||||||
{
|
{
|
||||||
arg_byte = 1,
|
arg_byte = 1,
|
||||||
|
@ -76,7 +207,7 @@ void C_WriteString(const char *sz);
|
||||||
void C_WriteEntity(int iValue);
|
void C_WriteEntity(int iValue);
|
||||||
void C_MessageEnd(void);
|
void C_MessageEnd(void);
|
||||||
|
|
||||||
extern CVector<int> msgHooks[256];
|
extern RegisteredMessage msgHooks[256];
|
||||||
extern int msgBlocks[256];
|
extern int msgBlocks[256];
|
||||||
|
|
||||||
void ClearMessages();
|
void ClearMessages();
|
||||||
|
|
|
@ -55,9 +55,15 @@ native get_msg_block(iMessage);
|
||||||
* or fully block it. Here is how it works:
|
* or fully block it. Here is how it works:
|
||||||
* If you hook a message, the message is stored but not sent. You have the opportunity to
|
* If you hook a message, the message is stored but not sent. You have the opportunity to
|
||||||
* not only execute code, but to get/set the contents of the message, before you choose to
|
* not only execute code, but to get/set the contents of the message, before you choose to
|
||||||
* either block it or let it go on its way. The hooked function will be passed a msg_id, msg_dest, and entity index. */
|
* either block it or let it go on its way. The hooked function will be passed a msg_id, msg_dest, and entity index.
|
||||||
|
* The return value can be passed to unregister_message() to stop the message from being hooked */
|
||||||
native register_message(iMsgId, const szFunction[]);
|
native register_message(iMsgId, const szFunction[]);
|
||||||
|
|
||||||
|
/* Unregisters a message hook previously created with register_message
|
||||||
|
* You must pass the proper message id, and return value from the message to unregister the message successfully. */
|
||||||
|
native unregister_message(iMsgId, registeredmsg);
|
||||||
|
|
||||||
|
|
||||||
/* The get/set _msg commands will fail if used outside a hooked message scope.
|
/* The get/set _msg commands will fail if used outside a hooked message scope.
|
||||||
* They should never be used unless inside a registered message function.
|
* They should never be used unless inside a registered message function.
|
||||||
* There are eight different ways of sending a message, five are ints, two are floats, and one is string.
|
* There are eight different ways of sending a message, five are ints, two are floats, and one is string.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user