Added part of amb1604: unregister_message - OH GOD I HOPE I DIDNT BREAK IT
This commit is contained in:
		@@ -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.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user