mirror of
https://github.com/rehlds/reapi.git
synced 2024-12-29 16:15:34 +03:00
Rework message hook/natives
This commit is contained in:
parent
06743d6eb9
commit
ab14d37b0a
@ -280,8 +280,13 @@ enum MessageHook
|
|||||||
* @param callback The name of the callback function.
|
* @param callback The name of the callback function.
|
||||||
* @param post Whether the callback should be invoked before or after processing the message. (optional)
|
* @param post Whether the callback should be invoked before or after processing the message. (optional)
|
||||||
*
|
*
|
||||||
* @note You can modify the message content using SetMessageParam native before the original function is invoked.
|
* @note The callback arguments have:
|
||||||
* Also can reading the message content using GetMessageParam native.
|
* msg_id - Message id
|
||||||
|
* msg_dest - Destination type (see MSG_* constants in messages_const.inc)
|
||||||
|
* msg_entity - Entity receiving the message
|
||||||
|
*
|
||||||
|
* @note You can modify the message content using SetMessageData native before the original function is invoked.
|
||||||
|
* Also can reading the message content using GetMessageData native.
|
||||||
*
|
*
|
||||||
* In the callback function, use the return values from Hookchain return types, such as HC_CONTINUE, HC_SUPERCEDE, etc.
|
* In the callback function, use the return values from Hookchain return types, such as HC_CONTINUE, HC_SUPERCEDE, etc.
|
||||||
* to control the flow of message processing.
|
* to control the flow of message processing.
|
||||||
@ -318,56 +323,50 @@ native bool:EnableHookMessage(const MessageHook:handle);
|
|||||||
native bool:DisableHookMessage(const MessageHook:handle);
|
native bool:DisableHookMessage(const MessageHook:handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the parameter value for the specified index in the current game message.
|
* Sets the message data in the current game message.
|
||||||
*
|
*
|
||||||
* @param index The index of the parameter to set.
|
* @param type The type of the message data that can be changed
|
||||||
* @param value The value to set for the parameter.
|
* @param ... Additional args depending on the type of the message argument being retrieved (For more details, look at the enum MsgArgType)
|
||||||
*
|
*
|
||||||
* @return Returns true if the parameter value is successfully set, otherwise false.
|
* @return Returns true if the message data is successfully set, otherwise false.
|
||||||
*/
|
*/
|
||||||
native bool:SetMessageParam(const number, any:...);
|
native bool:SetMessageData(const MsgDataType:type, any:...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the parameter value for the specified index in the current game message.
|
* Gets the message data value in the current game message
|
||||||
*
|
*
|
||||||
* @param index The index of the parameter to retrieve.
|
* @param type The type of message data that can be get
|
||||||
* @param ... Additional parameters depending on the type of the parameter being retrieved.
|
* @param ... Additional args depending on the type of the message argument being retrieved (For more details, look at the enum MsgArgType)
|
||||||
*
|
*
|
||||||
* @return Returns the retrieved parameter value.
|
* @return Returns value of argument in the current message
|
||||||
*/
|
*/
|
||||||
native any:GetMessageParam(const number, any:...);
|
native any:GetMessageData(const MsgDataType:type, any:...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the type of the parameter at the specified index in the current game message.
|
* Gets the message data original value in the current game message.
|
||||||
*
|
*
|
||||||
* @param index The index of the parameter to retrieve the type for.
|
* @param type The type of message data that can be get
|
||||||
|
* @param ... Additional args depending on the type of the message argument being retrieved (For more details, look at the enum MsgArgType)
|
||||||
*
|
*
|
||||||
* @return Returns the type of the parameter, look at the enum MsgParamType
|
* @return Returns original value of argument in the current message
|
||||||
*/
|
*/
|
||||||
native MsgParamType:GetMessageParamType(const number);
|
native any:GetMessageOrigData(const MsgDataType:type, any:...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the number of parameters in the current game message.
|
* Retrieves the type of the argument at the specified number in the current game message.
|
||||||
*
|
*
|
||||||
* @return Returns the number of parameters in the current game message.
|
* @param number The number of the argument to retrieve the type for.
|
||||||
|
*
|
||||||
|
* @return Returns the type of the argument, look at the enum MsgArgType
|
||||||
*/
|
*/
|
||||||
native GetMessageParamCount();
|
native MsgArgType:GetMessageArgType(const number);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the origin of the current game message.
|
* Retrieves the number of argument in the current game message.
|
||||||
*
|
*
|
||||||
* @param origin An array to store the origin coordinates of the game message.
|
* @return Returns the number of argument in the current game message.
|
||||||
*
|
|
||||||
* @return Returns true if the origin is successfully retrieved, otherwise false.
|
|
||||||
*/
|
*/
|
||||||
native bool:GetMessageOrigin(Float:origin[3]);
|
native GetMessageArgsNum();
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the destination of the current message.
|
|
||||||
*
|
|
||||||
* @return Returns the destination of the current message.
|
|
||||||
*/
|
|
||||||
native GetMessageDest();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the block type for the specified message ID.
|
* Sets the block type for the specified message ID.
|
||||||
@ -387,3 +386,44 @@ native bool:SetMessageBlock(const msgid, MsgBlockType:type);
|
|||||||
* @return Returns the block type of the specified message, look at the enum MsgBlockType
|
* @return Returns the block type of the specified message, look at the enum MsgBlockType
|
||||||
*/
|
*/
|
||||||
native MsgBlockType:GetMessageBlock(const msgid);
|
native MsgBlockType:GetMessageBlock(const msgid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the specified type of message data has been modified
|
||||||
|
*
|
||||||
|
* This native allows you to check if any part of the message data, such as its
|
||||||
|
* destination, type, origin, receiver, or any the specific argument of the message, has been modified
|
||||||
|
*
|
||||||
|
* @param type The type of the data to check for modification
|
||||||
|
* This can be one of the following:
|
||||||
|
* - MsgAny: Check if any part of the message has been modified
|
||||||
|
* - MsgDest: Check if the destination has been modified
|
||||||
|
* - MsgIndex: Check if the message ID has been modified
|
||||||
|
* - MsgOrigin: Check if the origin has been modified
|
||||||
|
* - MsgTargetId: Check if the index of the recipient client has been modified
|
||||||
|
* - MsgArg: Check if a specific argument of the message has been modified
|
||||||
|
*
|
||||||
|
* @param number The number of the argument to check for modification (used only when type is MsgDataType:MsgArg)
|
||||||
|
* Default value is -1, which means the argument number is not applicable
|
||||||
|
*
|
||||||
|
* @return Returns true if the specified data type has been modified, false otherwise
|
||||||
|
*/
|
||||||
|
native bool:IsMessageDataModified(MsgDataType:type = MsgAny, const number = -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets a specific type of message data to its original value
|
||||||
|
*
|
||||||
|
* @param type The type of the data to check for modification
|
||||||
|
* This can be one of the following:
|
||||||
|
* - MsgAny: Reset all modified message data to its original values
|
||||||
|
* - MsgDest: Reset the destination to its original value
|
||||||
|
* - MsgIndex: Reset the message ID to its original value
|
||||||
|
* - MsgOrigin: Reset the origin to its original value
|
||||||
|
* - MsgTargetId: Reset the index of the recipient client to its original value
|
||||||
|
* - MsgArg: Reset a specific argument of the message to its original value
|
||||||
|
*
|
||||||
|
* @param number The number of the argument to reset (used only when type is MsgDataType:MsgArg)
|
||||||
|
* Default value is -1, which means all arguments will be reset.
|
||||||
|
*
|
||||||
|
* @return Returns true if the modified data type was reset, otherwise false.
|
||||||
|
*/
|
||||||
|
native bool:ResetModifiedMessageData(MsgDataType:type = MsgAny, const number = -1);
|
||||||
|
@ -1323,18 +1323,79 @@ enum NetAdrVars
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message param types used with GetMessageParamType()
|
* Message argument types used with GetMessageArgType()
|
||||||
*/
|
*/
|
||||||
enum MsgParamType
|
enum MsgArgType
|
||||||
{
|
{
|
||||||
ParamByte,
|
ArgByte,
|
||||||
ParamChar,
|
ArgChar,
|
||||||
ParamShort,
|
ArgShort,
|
||||||
ParamLong,
|
ArgLong,
|
||||||
ParamAngle,
|
ArgAngle,
|
||||||
ParamCoord,
|
ArgCoord,
|
||||||
ParamString,
|
ArgString,
|
||||||
ParamEntity,
|
ArgEntity,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message data types used with SetMessageData()/GetMessageData()
|
||||||
|
* HasModifiedMessageData()/ResetModifiedMessageData()
|
||||||
|
*/
|
||||||
|
enum MsgDataType
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Description: Any part of the message
|
||||||
|
*/
|
||||||
|
MsgAny,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description: The destination of the message
|
||||||
|
* Return type: integer
|
||||||
|
* Get params: new dest = GetMessageData(MsgDest);
|
||||||
|
* Set params: SetMessageData(MsgDest, MSG_ALL);
|
||||||
|
*/
|
||||||
|
MsgDest,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description: The index of the message
|
||||||
|
* Return type: integer
|
||||||
|
* Get params: new msg_id = GetMessageData(MsgMsgId);
|
||||||
|
* Set params: SetMessageData(MsgMsgId, const msg_id);
|
||||||
|
*/
|
||||||
|
MsgMsgId,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description: The origin of the message
|
||||||
|
* Return type: float [3]
|
||||||
|
* Get params: GetMessageData(MsgOrigin, Float:dstVector[3]);
|
||||||
|
* Set params: SetMessageData(MsgOrigin, Float:srcVector[3]);
|
||||||
|
*/
|
||||||
|
MsgOrigin,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description: The index of the recipient client
|
||||||
|
* Return type: integer
|
||||||
|
* Get params: new targetId = GetMessageData(MsgTargetId);
|
||||||
|
* Set params: SetMessageData(MsgTargetId, const targetId); (acceptable indexes 0-32, 0 index also as -1 means NULLENT)
|
||||||
|
*/
|
||||||
|
MsgTargetId,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Description: The arguments of the message
|
||||||
|
*
|
||||||
|
* Arg type: string (MSG_ARG_String)
|
||||||
|
* Get params: bool:GetMessageData(MsgArg, const argnumber, value[], const maxlen);
|
||||||
|
* Set params: bool:SetMessageData(MsgArg, const argnumber, const value[]);
|
||||||
|
*
|
||||||
|
* Arg type: float (MSG_ARG_Angle, MSG_ARG_Coord)
|
||||||
|
* Get params: Float:GetMessageData(MsgArg, const argnumber, &Float:value = 0.0);
|
||||||
|
* Set params: bool:SetMessageData(MsgArg, const argnumber, const Float:value);
|
||||||
|
*
|
||||||
|
* Arg type: integer (MSG_ARG_Byte, MSG_ARG_Char, MSG_ARG_Short, MSG_ARG_Long, MSG_ARG_Entity)
|
||||||
|
* Get params: GetMessageData(MsgArg, const argnumber);
|
||||||
|
* Set params: bool:SetMessageData(MsgArg, const argnumber, const value);
|
||||||
|
*/
|
||||||
|
MsgArg
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
210
reapi/extra/amxmodx/scripting/message_test.sma
Normal file
210
reapi/extra/amxmodx/scripting/message_test.sma
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
#include <amxmodx>
|
||||||
|
#include <reapi>
|
||||||
|
|
||||||
|
public plugin_init()
|
||||||
|
{
|
||||||
|
register_plugin("ReAPI MessageHook Test", "1.0", "s1lent");
|
||||||
|
RegisterMessage(get_user_msgid("SayText"), "MessageSayText_Pre", .post = false);
|
||||||
|
RegisterMessage(get_user_msgid("SayText"), "MessageSayText_Post", .post = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destination types for message hook
|
||||||
|
*/
|
||||||
|
new const g_MsgDestination[][] =
|
||||||
|
{
|
||||||
|
"MSG_BROADCAST", // Unreliable to all
|
||||||
|
"MSG_ONE", // Reliable to one (msg_entity)
|
||||||
|
"MSG_ALL", // Reliable to all
|
||||||
|
"MSG_INIT", // Write to the init string
|
||||||
|
"MSG_PVS", // Ents in PVS of org
|
||||||
|
"MSG_PAS", // Ents in PAS of org
|
||||||
|
"MSG_PVS_R", // Reliable to PVS
|
||||||
|
"MSG_PAS_R", // Reliable to PAS
|
||||||
|
"MSG_ONE_UNRELIABLE", // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped)
|
||||||
|
"MSG_SPEC" // Sends to all spectator proxies
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message argument types used with GetMessageArgType()
|
||||||
|
*/
|
||||||
|
new const g_MsgArgType[][] =
|
||||||
|
{
|
||||||
|
"Byte",
|
||||||
|
"Char",
|
||||||
|
"Short",
|
||||||
|
"Long",
|
||||||
|
"Angle",
|
||||||
|
"Coord",
|
||||||
|
"String",
|
||||||
|
"Entity",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking behavior types for messages used with SetMessageBlock()/GetMessageBlock()
|
||||||
|
*/
|
||||||
|
new const g_MsgBlockType[][] =
|
||||||
|
{
|
||||||
|
"MSG_BLOCK_NOT", // Not a block
|
||||||
|
"MSG_BLOCK_ONCE", // Block once
|
||||||
|
"MSG_BLOCK_SET" // Set block
|
||||||
|
};
|
||||||
|
|
||||||
|
public MessageSayText_Pre(const msg_id, const msg_dest, const id)
|
||||||
|
{
|
||||||
|
server_print("^nMessageSayText_Pre");
|
||||||
|
|
||||||
|
DumpMessageArgs(msg_id);
|
||||||
|
|
||||||
|
static bool:recursive_guard = false;
|
||||||
|
if (!recursive_guard)
|
||||||
|
{
|
||||||
|
recursive_guard = true; // avoid deadlock
|
||||||
|
|
||||||
|
// Modify original text message in chat
|
||||||
|
SetMessageData(MsgDest, MSG_ALL); // send text messages in the chat to everyone
|
||||||
|
SetMessageData(MsgTargetId, NULLENT);
|
||||||
|
SetMessageData(MsgArg, 2, "^4(Test) ^3%s1^1 @ ^4%s3^1 : %s2"); // change format
|
||||||
|
|
||||||
|
if (is_user_connected(id))
|
||||||
|
{
|
||||||
|
// Send another chat message, test deadlock
|
||||||
|
new szPlayerName[32];
|
||||||
|
get_user_name(id, szPlayerName, charsmax(szPlayerName));
|
||||||
|
|
||||||
|
new szTextMsg[256];
|
||||||
|
GetMessageData(MsgArg, 4, szTextMsg, charsmax(szTextMsg));
|
||||||
|
|
||||||
|
message_begin(MSG_ONE, msg_id, .player = id);
|
||||||
|
write_byte(id);
|
||||||
|
write_string("^3%s1^1 @ ^4%s3^1 : %s2");
|
||||||
|
write_string(szPlayerName);
|
||||||
|
write_string(szTextMsg);
|
||||||
|
write_string("Courtyard");
|
||||||
|
message_end();
|
||||||
|
|
||||||
|
// Send another text message, but on screen in center
|
||||||
|
message_begin(MSG_ONE, get_user_msgid("TextMsg"), .player = id);
|
||||||
|
write_byte(print_center);
|
||||||
|
|
||||||
|
for (new i = 1; i <= GetMessageArgsNum(); i++)
|
||||||
|
{
|
||||||
|
new MsgArgType:type = GetMessageArgType(i);
|
||||||
|
if (type == ArgString)
|
||||||
|
{
|
||||||
|
new szBuffer[256];
|
||||||
|
GetMessageOrigData(MsgArg, i, szBuffer, charsmax(szBuffer));
|
||||||
|
write_string(szBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
recursive_guard = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageSayText_Post(const msg_id, const msg_dest, const id)
|
||||||
|
{
|
||||||
|
server_print("^nMessageSayText_Post");
|
||||||
|
DumpMessageArgs(msg_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
stock Float:fabs(Float:x)
|
||||||
|
{
|
||||||
|
return x > 0 ? x : -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
stock DumpMessageArgs(const msg_id)
|
||||||
|
{
|
||||||
|
// indicates that the message data has been modified
|
||||||
|
new const symbolIndicateModified[] = "+";
|
||||||
|
|
||||||
|
if (IsMessageDataModified(MsgDest))
|
||||||
|
server_print("Dest = %s (%d) > changed to > %s (%d)", g_MsgDestination[GetMessageOrigData(MsgDest)], GetMessageOrigData(MsgDest), g_MsgDestination[GetMessageData(MsgDest)], GetMessageData(MsgDest));
|
||||||
|
else
|
||||||
|
server_print("Dest = %s (%d)", g_MsgDestination[GetMessageData(MsgDest)], GetMessageData(MsgDest));
|
||||||
|
|
||||||
|
new Float:vecOrigin[3];
|
||||||
|
GetMessageData(MsgOrigin, vecOrigin);
|
||||||
|
|
||||||
|
if (IsMessageDataModified(MsgOrigin))
|
||||||
|
{
|
||||||
|
new Float:vecSourceOrigin[3];
|
||||||
|
GetMessageOrigData(MsgOrigin, vecSourceOrigin);
|
||||||
|
server_print("Origin = (%0.2f, %0.2f, %0.2f) > changed to > (%0.2f, %0.2f, %0.2f)", vecSourceOrigin[0], vecSourceOrigin[1], vecSourceOrigin[2], vecOrigin[0], vecOrigin[1], vecOrigin[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server_print("Origin = (%0.2f, %0.2f, %0.2f)", vecOrigin[0], vecOrigin[1], vecOrigin[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsMessageDataModified(MsgTargetId))
|
||||||
|
server_print("Receiver = %d > changed to > %d", GetMessageOrigData(MsgTargetId), GetMessageData(MsgTargetId));
|
||||||
|
else
|
||||||
|
server_print("Receiver = %d", GetMessageData(MsgTargetId));
|
||||||
|
|
||||||
|
server_print("Block state = %s", g_MsgBlockType[any:GetMessageBlock(msg_id)]);
|
||||||
|
server_print("Args count = %d", GetMessageArgsNum());
|
||||||
|
server_print("Message modified %s", IsMessageDataModified() ? symbolIndicateModified : "-");
|
||||||
|
|
||||||
|
// Iterate over all arguments of current message
|
||||||
|
for (new i = 1; i <= GetMessageArgsNum(); i++)
|
||||||
|
{
|
||||||
|
new MsgArgType:type = GetMessageArgType(i);
|
||||||
|
new bool:isModified = IsMessageDataModified(MsgArg, i);
|
||||||
|
|
||||||
|
// Print string values of argument
|
||||||
|
if (type == ArgString)
|
||||||
|
{
|
||||||
|
new curString[256], origString[256];
|
||||||
|
GetMessageData(MsgArg, i, curString, charsmax(curString));
|
||||||
|
GetMessageOrigData(MsgArg, i, origString, charsmax(origString));
|
||||||
|
|
||||||
|
replace_all(curString, charsmax(curString), "^n", "");
|
||||||
|
replace_all(origString, charsmax(origString), "^n", "");
|
||||||
|
|
||||||
|
if (!equal(origString, curString) || isModified)
|
||||||
|
{
|
||||||
|
server_print(" %-2d %-13s %s ^"%s^" > changed to > ^"%s^"", i, g_MsgArgType[any:type], isModified ? symbolIndicateModified : "-", origString, curString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server_print(" %-2d %-13s %s ^"%s^"", i, g_MsgArgType[any:type], isModified ? symbolIndicateModified : "-", curString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Print float point values of argument
|
||||||
|
else if (type == ArgAngle || type == ArgCoord)
|
||||||
|
{
|
||||||
|
new Float:flCurValue = Float:GetMessageData(MsgArg, i);
|
||||||
|
new Float:flOrigValue = Float:GetMessageOrigData(MsgArg, i);
|
||||||
|
|
||||||
|
if (fabs(flCurValue - flOrigValue) > 0.1 || isModified)
|
||||||
|
{
|
||||||
|
server_print(" %-2d %-13s %s ^"%f^" > changed to > ^"%f^"", i, g_MsgArgType[any:type], isModified ? symbolIndicateModified : "-", flOrigValue, flCurValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server_print(" %-2d %-13s %s ^"%f^"", i, g_MsgArgType[any:type], isModified ? symbolIndicateModified : "-", flCurValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Print integer values of argument
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new iCurValue = GetMessageData(MsgArg, i);
|
||||||
|
new iOrigValue = GetMessageOrigData(MsgArg, i);
|
||||||
|
|
||||||
|
if (iCurValue != iOrigValue || isModified)
|
||||||
|
{
|
||||||
|
server_print(" %-2d %-13s %s ^"%i^" > changed to > ^"%i^"", i, g_MsgArgType[any:type], isModified ? symbolIndicateModified : "-", iOrigValue, iCurValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server_print(" %-2d %-13s %s ^"%i^"", i, g_MsgArgType[any:type], isModified ? symbolIndicateModified : "-", iCurValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server_print("^n");
|
||||||
|
}
|
@ -66,7 +66,21 @@ public:
|
|||||||
SPEC, // Sends to all spectator proxies
|
SPEC, // Sends to all spectator proxies
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~IMessage() {};
|
/**
|
||||||
|
* @brief Data types for message data
|
||||||
|
*/
|
||||||
|
enum class DataType : uint8_t
|
||||||
|
{
|
||||||
|
Any, // Any part of the message
|
||||||
|
Dest, // Destination of the message
|
||||||
|
Index, // Index of the message
|
||||||
|
Origin, // Origin of the message
|
||||||
|
Edict, // Pointer to the edict of the recipient client
|
||||||
|
Param, // Parameter of the message
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~IMessage() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of parameters in the message
|
* @brief Returns the number of parameters in the message
|
||||||
@ -137,10 +151,10 @@ public:
|
|||||||
virtual Dest getDest() const = 0;
|
virtual Dest getDest() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the type of the message
|
* @brief Returns the index of the message
|
||||||
* @return The type of the message
|
* @return The index of the message
|
||||||
*/
|
*/
|
||||||
virtual int getType() const = 0;
|
virtual int getId() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the origin of the message
|
* @brief Returns the origin of the message
|
||||||
@ -155,10 +169,110 @@ public:
|
|||||||
virtual struct edict_s* getEdict() const = 0;
|
virtual struct edict_s* getEdict() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns whether the message has been modified
|
* @brief Checks if the specified type of message data has been modified
|
||||||
* @return True if the message has been modified, false otherwise
|
*
|
||||||
|
* This function allows you to check if any part of the message data, such as its
|
||||||
|
* destination, type, origin, edict, or any specific parameter, has been modified
|
||||||
|
*
|
||||||
|
* @param type The type of the data to check for modification
|
||||||
|
* This can be one of the following:
|
||||||
|
* - DataType::Any: Check if any part of the message has been modified
|
||||||
|
* - DataType::Dest: Check if the destination has been modified
|
||||||
|
* - DataType::Index: Check if the message ID has been modified
|
||||||
|
* - DataType::Origin: Check if the origin has been modified
|
||||||
|
* - DataType::Edict: Check if the edict pointer has been modified
|
||||||
|
* - DataType::Param: Check if a specific parameter has been modified
|
||||||
|
*
|
||||||
|
* @param index The index of the parameter to check for modification (used only when type is DataType::Param)
|
||||||
|
* Default value is -1, which means the parameter index is not applicable
|
||||||
|
*
|
||||||
|
* @return True if the specified data type has been modified, false otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool isModified() const = 0;
|
virtual bool isDataModified(DataType type = DataType::Any, size_t index = -1) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets a specific type of message data to its original value
|
||||||
|
*
|
||||||
|
* @param type The type of data to reset to its original value
|
||||||
|
* This can be one of the following:
|
||||||
|
* - DataType::Any: Reset all modified message data to its original values
|
||||||
|
* - DataType::Dest: Reset the destination to its original value
|
||||||
|
* - DataType::Index: Reset the message ID to its original value
|
||||||
|
* - DataType::Origin: Reset the origin to its original value
|
||||||
|
* - DataType::Edict: Reset the edict pointer of the recipient client to its original value
|
||||||
|
* - DataType::Param: Reset a specific parameter to its original value
|
||||||
|
*
|
||||||
|
* @param index The index of the parameter to reset (used only when type is DataType::Param)
|
||||||
|
* Default value is -1, which means the parameter index is not applicable
|
||||||
|
*
|
||||||
|
* @return True if the modified data type was reset, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool resetModifiedData(DataType type = DataType::Any, size_t index = -1) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the destination of the message
|
||||||
|
*/
|
||||||
|
virtual void setDest(Dest dest) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the index of the message
|
||||||
|
*/
|
||||||
|
virtual void setId(int msg_id) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the origin of the message
|
||||||
|
*/
|
||||||
|
virtual void setOrigin(const float *origin) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the edict associated with the message
|
||||||
|
*/
|
||||||
|
virtual void setEdict(struct edict_s *pEdict) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original destination of the message before any modifications
|
||||||
|
* @return The original destination of the message
|
||||||
|
*/
|
||||||
|
virtual Dest getOriginalDest() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original type of the message before any modifications
|
||||||
|
* @return The original type of the message
|
||||||
|
*/
|
||||||
|
virtual int getOriginalId() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original origin of the message before any modifications
|
||||||
|
* @return The original origin of the message
|
||||||
|
*/
|
||||||
|
virtual const float* getOriginalOrigin() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original edict associated with the message before any modifications
|
||||||
|
* @return The original edict associated with the message
|
||||||
|
*/
|
||||||
|
virtual struct edict_s* getOriginalEdict() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original integer value of the parameter at the given index before any modifications
|
||||||
|
* @param index The index of the parameter
|
||||||
|
* @return The original integer value of the parameter
|
||||||
|
*/
|
||||||
|
virtual int getOriginalParamInt(size_t index) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original float value of the parameter at the given index before any modifications
|
||||||
|
* @param index The index of the parameter
|
||||||
|
* @return The original float value of the parameter
|
||||||
|
*/
|
||||||
|
virtual float getOriginalParamFloat(size_t index) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the original string value of the parameter at the given index before any modifications
|
||||||
|
* @param index The index of the parameter
|
||||||
|
* @return The original string value of the parameter
|
||||||
|
*/
|
||||||
|
virtual const char* getOriginalParamString(size_t index) const = 0;
|
||||||
|
|
||||||
// This must be the last virtual function in class
|
// This must be the last virtual function in class
|
||||||
#ifdef REHLDS_SELF
|
#ifdef REHLDS_SELF
|
||||||
@ -167,7 +281,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MESSAGEMNGR_VERSION_MAJOR 1
|
#define MESSAGEMNGR_VERSION_MAJOR 2
|
||||||
#define MESSAGEMNGR_VERSION_MINOR 0
|
#define MESSAGEMNGR_VERSION_MINOR 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,7 +292,7 @@ class IMessageManager
|
|||||||
public:
|
public:
|
||||||
using hookfunc_t = void (*)(IVoidHookChain<IMessage *> *chain, IMessage *msg);
|
using hookfunc_t = void (*)(IVoidHookChain<IMessage *> *chain, IMessage *msg);
|
||||||
|
|
||||||
virtual ~IMessageManager() {};
|
virtual ~IMessageManager() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the major version of the MessageManager
|
* @brief Returns the major version of the MessageManager
|
||||||
@ -194,30 +308,30 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the blocking behavior for the given message type
|
* @brief Returns the blocking behavior for the given message type
|
||||||
* @param msgType The message type
|
* @param msg_id The message type
|
||||||
* @return The blocking behavior for the given message type
|
* @return The blocking behavior for the given message type
|
||||||
*/
|
*/
|
||||||
virtual IMessage::BlockType getMessageBlock(int msgType) const = 0;
|
virtual IMessage::BlockType getMessageBlock(int msg_id) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the blocking behavior for the given message type
|
* @brief Sets the blocking behavior for the given message type
|
||||||
* @param msgType The message type
|
* @param msg_id The message type
|
||||||
* @param blockType The blocking behavior to set
|
* @param blockType The blocking behavior to set
|
||||||
*/
|
*/
|
||||||
virtual void setMessageBlock(int msgType, IMessage::BlockType blockType) = 0;
|
virtual void setMessageBlock(int msg_id, IMessage::BlockType blockType) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Registers a hook function for the given message type
|
* @brief Registers a hook function for the given message type
|
||||||
* @param msgType The message type to register the hook for
|
* @param msg_id The message type to register the hook for
|
||||||
* @param handler The hook function to register
|
* @param handler The hook function to register
|
||||||
* @param priority The priority of the hook function (see enum HookChainPriority)
|
* @param priority The priority of the hook function (see enum HookChainPriority)
|
||||||
*/
|
*/
|
||||||
virtual void registerHook(int msgType, hookfunc_t handler, int priority = HC_PRIORITY_DEFAULT) = 0;
|
virtual void registerHook(int msg_id, hookfunc_t handler, int priority = HC_PRIORITY_DEFAULT) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unregisters a hook function for the given message type
|
* @brief Unregisters a hook function for the given message type
|
||||||
* @param msgType The message type to unregister the hook for
|
* @param msg_id The message type to unregister the hook for
|
||||||
* @param handler The hook function to unregister
|
* @param handler The hook function to unregister
|
||||||
*/
|
*/
|
||||||
virtual void unregisterHook(int msgType, hookfunc_t handler) = 0;
|
virtual void unregisterHook(int msg_id, hookfunc_t handler) = 0;
|
||||||
};
|
};
|
||||||
|
@ -15,24 +15,20 @@ IMessage *g_activeMessageContext = nullptr;
|
|||||||
* @param chain Pointer to the hook chain for the message
|
* @param chain Pointer to the hook chain for the message
|
||||||
* @param message Pointer to the message parameters
|
* @param message Pointer to the message parameters
|
||||||
*/
|
*/
|
||||||
void MessageHookManager::DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *params)
|
void MessageHookManager::DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *message)
|
||||||
{
|
{
|
||||||
// Get the hook associated with the given message type
|
// Get the hook associated with the given message type
|
||||||
MessageHook *msg = getHook(params->getType());
|
MessageHook *msg = getHook(message->getId());
|
||||||
|
|
||||||
// If somehow no hook is found, just continue hookchain
|
// If somehow no hook is found, just continue hookchain
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
chain->callNext(params);
|
chain->callNext(message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the current message context and set the new one
|
// Save the current message context and set the new one
|
||||||
IMessage *savedContext = g_activeMessageContext;
|
IMessage *savedContext = g_activeMessageContext;
|
||||||
g_activeMessageContext = params;
|
g_activeMessageContext = message;
|
||||||
|
|
||||||
// Get the entity index of the message (if applicable)
|
|
||||||
edict_t *entityEdict = params->getEdict();
|
|
||||||
int entityIndex = entityEdict ? indexOfEdict(entityEdict) : 0;
|
|
||||||
|
|
||||||
int hookState = HC_CONTINUE;
|
int hookState = HC_CONTINUE;
|
||||||
|
|
||||||
@ -41,7 +37,7 @@ void MessageHookManager::DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IM
|
|||||||
{
|
{
|
||||||
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
||||||
{
|
{
|
||||||
int ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), entityIndex, (cell)params);
|
int ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), message->getId(), message->getDest(), indexOfEdictAmx(message->getEdict(), 0 /* most friendly to use 0 as invalid index for message */));
|
||||||
if (unlikely(ret == HC_BREAK)) {
|
if (unlikely(ret == HC_BREAK)) {
|
||||||
g_activeMessageContext = savedContext;
|
g_activeMessageContext = savedContext;
|
||||||
return;
|
return;
|
||||||
@ -55,8 +51,8 @@ void MessageHookManager::DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IM
|
|||||||
// If the hook state is not superseded, continue hookchain
|
// If the hook state is not superseded, continue hookchain
|
||||||
if (hookState != HC_SUPERCEDE) {
|
if (hookState != HC_SUPERCEDE) {
|
||||||
g_activeMessageContext = nullptr;
|
g_activeMessageContext = nullptr;
|
||||||
chain->callNext(params);
|
chain->callNext(message);
|
||||||
g_activeMessageContext = savedContext;
|
g_activeMessageContext = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute post-hooks
|
// Execute post-hooks
|
||||||
@ -64,7 +60,7 @@ void MessageHookManager::DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IM
|
|||||||
{
|
{
|
||||||
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
if (likely(fwd->GetState() == FSTATE_ENABLED))
|
||||||
{
|
{
|
||||||
int ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), entityIndex, (cell)params);
|
int ret = g_amxxapi.ExecuteForward(fwd->GetFwdIndex(), message->getId(), message->getDest(), indexOfEdictAmx(message->getEdict(), 0 /* most friendly to use 0 as invalid index for message */));
|
||||||
if (unlikely(ret == HC_BREAK))
|
if (unlikely(ret == HC_BREAK))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -87,7 +83,7 @@ void MessageHookManager::DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IM
|
|||||||
*/
|
*/
|
||||||
cell MessageHookManager::addHook(AMX *amx, int msg_id, const char *funcname, bool post)
|
cell MessageHookManager::addHook(AMX *amx, int msg_id, const char *funcname, bool post)
|
||||||
{
|
{
|
||||||
int fwid = g_amxxapi.RegisterSPForwardByName(amx, funcname, FP_CELL, FP_DONE);
|
int fwid = g_amxxapi.RegisterSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||||
if (unlikely(fwid == -1)) {
|
if (unlikely(fwid == -1)) {
|
||||||
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: register forward failed.", __FUNCTION__);
|
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: register forward failed.", __FUNCTION__);
|
||||||
return 0;
|
return 0;
|
||||||
@ -224,7 +220,7 @@ void MessageHookManager::Clear()
|
|||||||
/**
|
/**
|
||||||
* @brief Dispatches the message callbacks as a routine
|
* @brief Dispatches the message callbacks as a routine
|
||||||
*/
|
*/
|
||||||
void MessageHookManager::RoutineMessageCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *params)
|
void MessageHookManager::RoutineMessageCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *message)
|
||||||
{
|
{
|
||||||
g_messageHookManager.DispatchCallbacks(chain, params);
|
g_messageHookManager.DispatchCallbacks(chain, message);
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Dispatches the callbacks for the message hooks
|
// Dispatches the callbacks for the message hooks
|
||||||
void DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *params);
|
void DispatchCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *message);
|
||||||
|
|
||||||
// Routine function for dispatching message callbacks
|
// Routine function for dispatching message callbacks
|
||||||
static void RoutineMessageCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *params);
|
static void RoutineMessageCallbacks(IVoidHookChain<IMessage *> *chain, IMessage *message);
|
||||||
|
|
||||||
// Getter the message hook by ID
|
// Getter the message hook by ID
|
||||||
MessageHook *getHook(size_t id);
|
MessageHook *getHook(size_t id);
|
||||||
|
@ -7,6 +7,8 @@ IRehldsHookchains* g_RehldsHookchains;
|
|||||||
IRehldsServerStatic* g_RehldsSvs;
|
IRehldsServerStatic* g_RehldsSvs;
|
||||||
IMessageManager* g_RehldsMessageManager;
|
IMessageManager* g_RehldsMessageManager;
|
||||||
|
|
||||||
|
void RehldsMessageMngr_Init();
|
||||||
|
|
||||||
bool RehldsApi_Init()
|
bool RehldsApi_Init()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -79,14 +81,43 @@ bool RehldsApi_Init()
|
|||||||
|
|
||||||
// message manager is available in "ReHLDS API" >= 3.14
|
// message manager is available in "ReHLDS API" >= 3.14
|
||||||
if (majorVersion >= 3 && minorVersion >= 14)
|
if (majorVersion >= 3 && minorVersion >= 14)
|
||||||
{
|
RehldsMessageMngr_Init();
|
||||||
IMessageManager *messageManager = g_RehldsApi->GetMessageManager();
|
|
||||||
if (messageManager->getMajorVersion() == MESSAGEMNGR_VERSION_MAJOR &&
|
|
||||||
messageManager->getMinorVersion() >= MESSAGEMNGR_VERSION_MINOR)
|
|
||||||
{
|
|
||||||
g_RehldsMessageManager = messageManager;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RehldsMessageMngr_Init()
|
||||||
|
{
|
||||||
|
IMessageManager *messageManager = g_RehldsApi->GetMessageManager();
|
||||||
|
|
||||||
|
int majorMessageMngrVersion = messageManager->getMajorVersion();
|
||||||
|
int minorMessageMngrVersion = messageManager->getMinorVersion();
|
||||||
|
|
||||||
|
if (majorMessageMngrVersion != MESSAGEMNGR_VERSION_MAJOR)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("[%s]: ReHLDS MessageMngr API major version mismatch; expected %d.%d, real %d.%d\n", Plugin_info.logtag, MESSAGEMNGR_VERSION_MAJOR, MESSAGEMNGR_VERSION_MINOR, majorMessageMngrVersion, minorMessageMngrVersion);
|
||||||
|
|
||||||
|
// need to notify that it is necessary to update the ReHLDS
|
||||||
|
if (majorMessageMngrVersion < MESSAGEMNGR_VERSION_MAJOR)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("[%s]: Please update ReHLDS to a newer version for the required MessageMngr API %d.%d\n", Plugin_info.logtag, MESSAGEMNGR_VERSION_MAJOR, MESSAGEMNGR_VERSION_MINOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to notify that it is necessary to update the module
|
||||||
|
else if (majorMessageMngrVersion > MESSAGEMNGR_VERSION_MAJOR)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("[%s]: Please update the %s to a newer version for the required MessageMngr API %d.%d\n", Plugin_info.logtag, Plugin_info.logtag, MESSAGEMNGR_VERSION_MAJOR, MESSAGEMNGR_VERSION_MINOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minorMessageMngrVersion < MESSAGEMNGR_VERSION_MINOR)
|
||||||
|
{
|
||||||
|
UTIL_ServerPrint("[%s]: ReHLDS MessageMngr API minor version mismatch; expected at least %d.%d, real %d.%d\n", Plugin_info.logtag, MESSAGEMNGR_VERSION_MAJOR, MESSAGEMNGR_VERSION_MINOR, majorMessageMngrVersion, minorMessageMngrVersion);
|
||||||
|
UTIL_ServerPrint("[%s]: Please update ReHLDS to a newer version for the required MessageMngr API %d.%d\n", Plugin_info.logtag, MESSAGEMNGR_VERSION_MAJOR, MESSAGEMNGR_VERSION_MINOR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_RehldsMessageManager = messageManager;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#define CHECK_PARAMBOUNDS(x, y) if (unlikely(x > (size_t)y)) { AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: invalid message argument %d/max:%d", __FUNCTION__, x, y); }
|
||||||
|
|
||||||
enum MessageHook
|
enum MessageHook
|
||||||
{
|
{
|
||||||
INVALID_MESSAGEHOOK = 0
|
INVALID_MESSAGEHOOK = 0
|
||||||
@ -12,8 +14,13 @@ enum MessageHook
|
|||||||
* @param callback The name of the callback function.
|
* @param callback The name of the callback function.
|
||||||
* @param post Whether the callback should be invoked before or after processing the message. (optional)
|
* @param post Whether the callback should be invoked before or after processing the message. (optional)
|
||||||
*
|
*
|
||||||
* @note You can modify the message content using SetMessageParam native before the original function is invoked.
|
* @note The callback arguments have:
|
||||||
* Also can reading the message content using GetMessageParam native.
|
* msg_id - Message id
|
||||||
|
* msg_dest - Destination type (see MSG_* constants in messages_const.inc)
|
||||||
|
* msg_entity - Entity receiving the message
|
||||||
|
*
|
||||||
|
* @note You can modify the message content using SetMessageData native before the original function is invoked.
|
||||||
|
* Also can reading the message content using GetMessageData native.
|
||||||
*
|
*
|
||||||
* In the callback function, use the return values from Hookchain return types, such as HC_CONTINUE, HC_SUPERCEDE, etc.
|
* In the callback function, use the return values from Hookchain return types, such as HC_CONTINUE, HC_SUPERCEDE, etc.
|
||||||
* to control the flow of message processing.
|
* to control the flow of message processing.
|
||||||
@ -24,11 +31,11 @@ enum MessageHook
|
|||||||
*/
|
*/
|
||||||
cell AMX_NATIVE_CALL RegisterMessage(AMX *amx, cell *params)
|
cell AMX_NATIVE_CALL RegisterMessage(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_id, arg_handler, arg_post };
|
enum args_e { arg_count, arg_msgid, arg_handler, arg_post };
|
||||||
|
|
||||||
CHECK_REQUIREMENTS(ReHLDS);
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
int msg_id = params[arg_id];
|
int msg_id = params[arg_msgid];
|
||||||
|
|
||||||
// svc_bad (0) is not allowed for hook
|
// svc_bad (0) is not allowed for hook
|
||||||
if (msg_id <= 0 || msg_id >= MAX_USERMESSAGES)
|
if (msg_id <= 0 || msg_id >= MAX_USERMESSAGES)
|
||||||
@ -127,18 +134,18 @@ cell AMX_NATIVE_CALL DisableHookMessage(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the parameter value for the specified index in the current game message.
|
* Sets the message data in the current game message.
|
||||||
*
|
*
|
||||||
* @param index The index of the parameter to set.
|
* @param type The type of the message data that can be changed
|
||||||
* @param value The value to set for the parameter.
|
* @param ... Additional args depending on the type of the message argument being retrieved (For more details, look at the enum MsgArgType)
|
||||||
*
|
*
|
||||||
* @return Returns true if the parameter value is successfully set, otherwise false.
|
* @return Returns true if the message data is successfully set, otherwise false.
|
||||||
*
|
*
|
||||||
* native bool:SetMessageParam(const number, any:...);
|
* native bool:SetMessageData(const MsgDataType:type, any:...);
|
||||||
*/
|
*/
|
||||||
cell AMX_NATIVE_CALL SetMessageParam(AMX *amx, cell *params)
|
cell AMX_NATIVE_CALL SetMessageData(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_number, arg_value };
|
enum args_e { arg_count, arg_type, arg_value, arg_param_value };
|
||||||
|
|
||||||
CHECK_REQUIREMENTS(ReHLDS);
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
@ -148,41 +155,74 @@ cell AMX_NATIVE_CALL SetMessageParam(AMX *amx, cell *params)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t number = params[arg_number] - 1;
|
IMessage::DataType type = static_cast<IMessage::DataType>(params[arg_type]);
|
||||||
|
|
||||||
cell *value = getAmxAddr(amx, params[arg_value]);
|
cell *value = getAmxAddr(amx, params[arg_value]);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IMessage::DataType::Dest:
|
||||||
|
g_activeMessageContext->setDest(static_cast<IMessage::Dest>(*value));
|
||||||
|
break;
|
||||||
|
case IMessage::DataType::Index:
|
||||||
|
g_activeMessageContext->setId(*value);
|
||||||
|
break;
|
||||||
|
case IMessage::DataType::Origin:
|
||||||
|
g_activeMessageContext->setOrigin(*(Vector *)value);
|
||||||
|
break;
|
||||||
|
case IMessage::DataType::Edict:
|
||||||
|
g_activeMessageContext->setEdict(edictByIndexAmx(*value, 0 /* most friendly to use 0 as invalid index for message */));
|
||||||
|
break;
|
||||||
|
case IMessage::DataType::Param:
|
||||||
|
{
|
||||||
|
// bool:SetMessageData(MsgDataType:type, const argnumber, const value[]);
|
||||||
|
cell *value = getAmxAddr(amx, params[arg_param_value]);
|
||||||
|
size_t number = *getAmxAddr(amx, params[arg_value]) - 1;
|
||||||
|
|
||||||
|
CHECK_PARAMBOUNDS(number, g_activeMessageContext->getParamCount());
|
||||||
|
|
||||||
switch (g_activeMessageContext->getParamType(number))
|
switch (g_activeMessageContext->getParamType(number))
|
||||||
{
|
{
|
||||||
case IMessage::ParamType::String:
|
case IMessage::ParamType::String:
|
||||||
char stringbuf[256];
|
char stringbuf[256];
|
||||||
g_activeMessageContext->setParamString(number, getAmxString(amx, params[arg_value], stringbuf));
|
g_activeMessageContext->setParamString(number, getAmxString(amx, params[arg_param_value], stringbuf));
|
||||||
break;
|
break;
|
||||||
case IMessage::ParamType::Angle:
|
case IMessage::ParamType::Angle:
|
||||||
case IMessage::ParamType::Coord:
|
case IMessage::ParamType::Coord:
|
||||||
g_activeMessageContext->setParamFloat(number, *(float *)value);
|
g_activeMessageContext->setParamFloat(number, *(float *)value);
|
||||||
break;
|
break;
|
||||||
default:
|
case IMessage::ParamType::Byte:
|
||||||
|
case IMessage::ParamType::Char:
|
||||||
|
case IMessage::ParamType::Short:
|
||||||
|
case IMessage::ParamType::Long:
|
||||||
|
case IMessage::ParamType::Entity:
|
||||||
g_activeMessageContext->setParamInt(number, *value);
|
g_activeMessageContext->setParamInt(number, *value);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the parameter value for the specified index in the current game message.
|
* Gets the message data value in the current game message
|
||||||
*
|
*
|
||||||
* @param index The index of the parameter to retrieve.
|
* @param type The type of message data that can be get
|
||||||
* @param ... Additional parameters depending on the type of the parameter being retrieved.
|
* @param ... Additional args depending on the type of the message argument being retrieved (For more details, look at the enum MsgArgType)
|
||||||
*
|
*
|
||||||
* @return Returns the retrieved parameter value.
|
* @return Returns value of argument in the current message
|
||||||
*
|
*
|
||||||
* native any:GetMessageParam(const number, any:...);
|
* native any:GetMessageData(MsgDataType:type, any:...);
|
||||||
*/
|
*/
|
||||||
cell AMX_NATIVE_CALL GetMessageParam(AMX *amx, cell *params)
|
cell AMX_NATIVE_CALL GetMessageData(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_number, arg_value, arg_maxlen };
|
enum args_e { arg_count, arg_type, arg_value, arg_param_value, arg_maxlen };
|
||||||
|
|
||||||
CHECK_REQUIREMENTS(ReHLDS);
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
@ -192,15 +232,31 @@ cell AMX_NATIVE_CALL GetMessageParam(AMX *amx, cell *params)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t number = params[arg_number] - 1;
|
IMessage::DataType type = static_cast<IMessage::DataType>(params[arg_type]);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IMessage::DataType::Dest:
|
||||||
|
return static_cast<cell>(g_activeMessageContext->getDest());
|
||||||
|
case IMessage::DataType::Index:
|
||||||
|
return g_activeMessageContext->getId();
|
||||||
|
case IMessage::DataType::Origin:
|
||||||
|
*(Vector *)getAmxAddr(amx, params[arg_value]) = g_activeMessageContext->getOrigin();
|
||||||
|
return TRUE;
|
||||||
|
case IMessage::DataType::Edict:
|
||||||
|
return indexOfEdictAmx(g_activeMessageContext->getEdict(), 0 /* most friendly to use 0 as invalid index for message */);
|
||||||
|
case IMessage::DataType::Param:
|
||||||
|
{
|
||||||
|
size_t number = *getAmxAddr(amx, params[arg_value]) - 1; // arg_value as number
|
||||||
|
|
||||||
cell *dstAddr = getAmxAddr(amx, params[arg_value]);
|
CHECK_PARAMBOUNDS(number, g_activeMessageContext->getParamCount());
|
||||||
|
|
||||||
|
cell *dstAddr = getAmxAddr(amx, params[arg_param_value]);
|
||||||
|
|
||||||
switch (g_activeMessageContext->getParamType(number))
|
switch (g_activeMessageContext->getParamType(number))
|
||||||
{
|
{
|
||||||
case IMessage::ParamType::String:
|
case IMessage::ParamType::String:
|
||||||
{
|
{
|
||||||
if (PARAMS_COUNT != 3)
|
if (PARAMS_COUNT != 4)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
const char *argString = g_activeMessageContext->getParamString(number);
|
const char *argString = g_activeMessageContext->getParamString(number);
|
||||||
@ -211,7 +267,7 @@ cell AMX_NATIVE_CALL GetMessageParam(AMX *amx, cell *params)
|
|||||||
case IMessage::ParamType::Coord:
|
case IMessage::ParamType::Coord:
|
||||||
{
|
{
|
||||||
float flValue = g_activeMessageContext->getParamFloat(number);
|
float flValue = g_activeMessageContext->getParamFloat(number);
|
||||||
if (PARAMS_COUNT > 1)
|
if (PARAMS_COUNT > 2)
|
||||||
*dstAddr = flValue;
|
*dstAddr = flValue;
|
||||||
return flValue;
|
return flValue;
|
||||||
}
|
}
|
||||||
@ -225,19 +281,105 @@ cell AMX_NATIVE_CALL GetMessageParam(AMX *amx, cell *params)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the type of the parameter at the specified index in the current game message.
|
* Gets the message data original value in the current game message.
|
||||||
*
|
*
|
||||||
* @param index The index of the parameter to retrieve the type for.
|
* @param type The type of message data that can be get
|
||||||
|
* @param ... Additional args depending on the type of the message argument being retrieved (For more details, look at the enum MsgArgType)
|
||||||
*
|
*
|
||||||
* @return Returns the type of the parameter, look at the enum MsgParamType
|
* @return Returns original value of argument in the current message
|
||||||
*
|
*
|
||||||
* native MsgParamType:GetMessageParamType(const number);
|
* native any:GetMessageOrigData(MsgDataType:type, any:...);
|
||||||
*/
|
*/
|
||||||
cell AMX_NATIVE_CALL GetMessageParamType(AMX *amx, cell *params)
|
cell AMX_NATIVE_CALL GetMessageOrigData(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
enum args_e { arg_count, arg_type, arg_value, arg_param_value, arg_maxlen };
|
||||||
|
|
||||||
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
|
if (!g_activeMessageContext)
|
||||||
|
{
|
||||||
|
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get argument without active hook.", __FUNCTION__);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMessage::DataType type = static_cast<IMessage::DataType>(params[arg_type]);
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case IMessage::DataType::Dest:
|
||||||
|
return static_cast<cell>(g_activeMessageContext->getOriginalDest());
|
||||||
|
case IMessage::DataType::Index:
|
||||||
|
return g_activeMessageContext->getId();
|
||||||
|
case IMessage::DataType::Origin:
|
||||||
|
*(Vector *)getAmxAddr(amx, params[arg_value]) = g_activeMessageContext->getOriginalOrigin();
|
||||||
|
return TRUE;
|
||||||
|
case IMessage::DataType::Edict:
|
||||||
|
return indexOfEdictAmx(g_activeMessageContext->getOriginalEdict());
|
||||||
|
case IMessage::DataType::Param:
|
||||||
|
{
|
||||||
|
size_t number = *getAmxAddr(amx, params[arg_value]) - 1; // arg_value as number
|
||||||
|
|
||||||
|
CHECK_PARAMBOUNDS(number, g_activeMessageContext->getParamCount());
|
||||||
|
|
||||||
|
cell *dstAddr = getAmxAddr(amx, params[arg_param_value]);
|
||||||
|
|
||||||
|
switch (g_activeMessageContext->getParamType(number))
|
||||||
|
{
|
||||||
|
case IMessage::ParamType::String:
|
||||||
|
{
|
||||||
|
if (PARAMS_COUNT != 4)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
const char *argString = g_activeMessageContext->getOriginalParamString(number);
|
||||||
|
setAmxString(dstAddr, argString ? argString : "", params[arg_maxlen]);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case IMessage::ParamType::Angle:
|
||||||
|
case IMessage::ParamType::Coord:
|
||||||
|
{
|
||||||
|
float flValue = g_activeMessageContext->getOriginalParamFloat(number);
|
||||||
|
if (PARAMS_COUNT > 2)
|
||||||
|
*dstAddr = flValue;
|
||||||
|
return flValue;
|
||||||
|
}
|
||||||
|
case IMessage::ParamType::Entity:
|
||||||
|
case IMessage::ParamType::Byte:
|
||||||
|
case IMessage::ParamType::Char:
|
||||||
|
case IMessage::ParamType::Short:
|
||||||
|
case IMessage::ParamType::Long:
|
||||||
|
return g_activeMessageContext->getOriginalParamInt(number);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the type of the argument at the specified number in the current game message.
|
||||||
|
*
|
||||||
|
* @param number The number of the argument to retrieve the type for.
|
||||||
|
*
|
||||||
|
* @return Returns the type of the argument, look at the enum MsgArgType
|
||||||
|
*
|
||||||
|
* native MsgArgType:GetMessageArgType(const number);
|
||||||
|
*/
|
||||||
|
cell AMX_NATIVE_CALL GetMessageArgType(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_number };
|
enum args_e { arg_count, arg_number };
|
||||||
|
|
||||||
@ -251,26 +393,21 @@ cell AMX_NATIVE_CALL GetMessageParamType(AMX *amx, cell *params)
|
|||||||
|
|
||||||
size_t number = params[arg_number] - 1;
|
size_t number = params[arg_number] - 1;
|
||||||
|
|
||||||
size_t paramCount = g_activeMessageContext->getParamCount();
|
CHECK_PARAMBOUNDS(number, g_activeMessageContext->getParamCount());
|
||||||
if (number < 0 || number >= paramCount)
|
|
||||||
{
|
|
||||||
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: invalid message argument %d.", __FUNCTION__, number);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<cell>(g_activeMessageContext->getParamType(number));
|
return static_cast<cell>(g_activeMessageContext->getParamType(number));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the number of parameters in the current game message.
|
* Retrieves the number of argument in the current game message.
|
||||||
*
|
*
|
||||||
* @return Returns the number of parameters in the current game message.
|
* @return Returns the number of argument in the current game message.
|
||||||
*
|
*
|
||||||
* native GetMessageParamCount();
|
* native GetMessageArgsNum();
|
||||||
*/
|
*/
|
||||||
cell AMX_NATIVE_CALL GetMessageParamCount(AMX *amx, cell *params)
|
cell AMX_NATIVE_CALL GetMessageArgsNum(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
enum args_e { arg_count, arg_number };
|
enum args_e { arg_count };
|
||||||
|
|
||||||
CHECK_REQUIREMENTS(ReHLDS);
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
@ -283,58 +420,6 @@ cell AMX_NATIVE_CALL GetMessageParamCount(AMX *amx, cell *params)
|
|||||||
return g_activeMessageContext->getParamCount();
|
return g_activeMessageContext->getParamCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the origin of the current game message.
|
|
||||||
*
|
|
||||||
* @param origin An array to store the origin coordinates of the game message.
|
|
||||||
*
|
|
||||||
* @return Returns true if the origin is successfully retrieved, otherwise false.
|
|
||||||
*
|
|
||||||
* native bool:GetMessageOrigin(Float:origin[3]);
|
|
||||||
*/
|
|
||||||
cell AMX_NATIVE_CALL GetMessageOrigin(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
enum args_e { arg_count, arg_number, arg_origin };
|
|
||||||
|
|
||||||
CHECK_REQUIREMENTS(ReHLDS);
|
|
||||||
|
|
||||||
if (!g_activeMessageContext)
|
|
||||||
{
|
|
||||||
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get argument without active hook.", __FUNCTION__);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float *messageOrigin = g_activeMessageContext->getOrigin();
|
|
||||||
if (!messageOrigin)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
Vector &outVec = *(Vector *)getAmxAddr(amx, params[arg_origin]);
|
|
||||||
outVec = messageOrigin;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the destination of the current message.
|
|
||||||
*
|
|
||||||
* @return Returns the destination of the current message.
|
|
||||||
*
|
|
||||||
* native GetMessageDest();
|
|
||||||
*/
|
|
||||||
cell AMX_NATIVE_CALL GetMessageDest(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
enum args_e { arg_count, arg_number, arg_origin };
|
|
||||||
|
|
||||||
CHECK_REQUIREMENTS(ReHLDS);
|
|
||||||
|
|
||||||
if (!g_activeMessageContext)
|
|
||||||
{
|
|
||||||
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get argument without active hook.", __FUNCTION__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<cell>(g_activeMessageContext->getDest());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the block type for the specified message ID.
|
* Sets the block type for the specified message ID.
|
||||||
*
|
*
|
||||||
@ -385,6 +470,99 @@ cell AMX_NATIVE_CALL GetMessageBlock(AMX *amx, cell *params)
|
|||||||
return static_cast<cell>(g_RehldsMessageManager->getMessageBlock(params[arg_id]));
|
return static_cast<cell>(g_RehldsMessageManager->getMessageBlock(params[arg_id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the specified type of message data has been modified
|
||||||
|
*
|
||||||
|
* This native allows you to check if any part of the message data, such as its
|
||||||
|
* destination, type, origin, receiver, or any the specific argument of the message, has been modified
|
||||||
|
*
|
||||||
|
* @param type The type of the data to check for modification
|
||||||
|
* This can be one of the following:
|
||||||
|
* - MsgAny: Check if any part of the message has been modified
|
||||||
|
* - MsgDest: Check if the destination has been modified
|
||||||
|
* - MsgIndex: Check if the message ID has been modified
|
||||||
|
* - MsgOrigin: Check if the origin has been modified
|
||||||
|
* - MsgTargetId: Check if the index of the recipient client has been modified
|
||||||
|
* - MsgArg: Check if a specific argument of the message has been modified
|
||||||
|
*
|
||||||
|
* @param number The number of the argument to check for modification (used only when type is MsgDataType:MsgArg)
|
||||||
|
* Default value is -1, which means the argument number is not applicable
|
||||||
|
*
|
||||||
|
* @return Returns true if the specified data type has been modified, false otherwise
|
||||||
|
*
|
||||||
|
* native bool:IsMessageDataModified(MsgDataType:type = MsgAny, const number = -1);
|
||||||
|
*/
|
||||||
|
cell AMX_NATIVE_CALL IsMessageDataModified(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
|
enum args_e { arg_count, arg_type, arg_number };
|
||||||
|
|
||||||
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
|
if (!g_activeMessageContext)
|
||||||
|
{
|
||||||
|
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: trying to get argument without active hook.", __FUNCTION__);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t number = -1;
|
||||||
|
|
||||||
|
IMessage::DataType type = static_cast<IMessage::DataType>(params[arg_type]);
|
||||||
|
if (type == IMessage::DataType::Param)
|
||||||
|
{
|
||||||
|
number = params[arg_number] - 1;
|
||||||
|
|
||||||
|
CHECK_PARAMBOUNDS(number, g_activeMessageContext->getParamCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_activeMessageContext->isDataModified(type, number) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets a specific type of message data to its original value
|
||||||
|
*
|
||||||
|
* @param type The type of the data to check for modification
|
||||||
|
* This can be one of the following:
|
||||||
|
* - MsgAny: Reset all modified message data to its original values
|
||||||
|
* - MsgDest: Reset the destination to its original value
|
||||||
|
* - MsgIndex: Reset the message ID to its original value
|
||||||
|
* - MsgOrigin: Reset the origin to its original value
|
||||||
|
* - MsgTargetId: Reset the index of the recipient client to its original value
|
||||||
|
* - MsgArg: Reset a specific argument of the message to its original value
|
||||||
|
*
|
||||||
|
* @param number The number of the argument to reset (used only when type is MsgDataType:MsgArg)
|
||||||
|
* Default value is -1, which means all arguments will be reset.
|
||||||
|
*
|
||||||
|
* @return Returns true if the modified data type was reset, otherwise false.
|
||||||
|
*
|
||||||
|
* native bool:ResetModifiedMessageData(MsgDataType:type = MsgAny, const number = -1);
|
||||||
|
*/
|
||||||
|
cell AMX_NATIVE_CALL ResetModifiedMessageData(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
enum args_e { arg_count, arg_type, arg_number };
|
||||||
|
|
||||||
|
CHECK_REQUIREMENTS(ReHLDS);
|
||||||
|
|
||||||
|
if (!g_activeMessageContext)
|
||||||
|
{
|
||||||
|
AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: trying to set argument without active hook.", __FUNCTION__);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t number = -1;
|
||||||
|
|
||||||
|
IMessage::DataType type = static_cast<IMessage::DataType>(params[arg_type]);
|
||||||
|
if (type == IMessage::DataType::Param && params[arg_number] != -1)
|
||||||
|
{
|
||||||
|
number = params[arg_number] - 1;
|
||||||
|
|
||||||
|
CHECK_PARAMBOUNDS(number, g_activeMessageContext->getParamCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_activeMessageContext->resetModifiedData(type, number) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO HookMessage_Natives[] =
|
AMX_NATIVE_INFO HookMessage_Natives[] =
|
||||||
{
|
{
|
||||||
{ "RegisterMessage", RegisterMessage },
|
{ "RegisterMessage", RegisterMessage },
|
||||||
@ -393,18 +571,20 @@ AMX_NATIVE_INFO HookMessage_Natives[] =
|
|||||||
{ "EnableHookMessage", EnableHookMessage },
|
{ "EnableHookMessage", EnableHookMessage },
|
||||||
{ "DisableHookMessage", DisableHookMessage },
|
{ "DisableHookMessage", DisableHookMessage },
|
||||||
|
|
||||||
{ "GetMessageParam", GetMessageParam },
|
{ "SetMessageData", SetMessageData },
|
||||||
{ "GetMessageParamType", GetMessageParamType },
|
{ "GetMessageData", GetMessageData },
|
||||||
{ "GetMessageParamCount", GetMessageParamCount },
|
|
||||||
|
|
||||||
{ "GetMessageOrigin", GetMessageOrigin },
|
{ "GetMessageOrigData", GetMessageOrigData },
|
||||||
{ "GetMessageDest", GetMessageDest },
|
|
||||||
|
|
||||||
{ "SetMessageParam", SetMessageParam },
|
{ "GetMessageArgType", GetMessageArgType },
|
||||||
|
{ "GetMessageArgsNum", GetMessageArgsNum },
|
||||||
|
|
||||||
{ "SetMessageBlock", SetMessageBlock },
|
{ "SetMessageBlock", SetMessageBlock },
|
||||||
{ "GetMessageBlock", GetMessageBlock },
|
{ "GetMessageBlock", GetMessageBlock },
|
||||||
|
|
||||||
|
{ "IsMessageDataModified", IsMessageDataModified },
|
||||||
|
{ "ResetModifiedMessageData", ResetModifiedMessageData },
|
||||||
|
|
||||||
{ nullptr, nullptr }
|
{ nullptr, nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ inline size_t indexOfEdictAmx(const entvars_t* pev)
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t indexOfEdictAmx(const edict_t *pEdict)
|
inline size_t indexOfEdictAmx(const edict_t *pEdict, const int INVALID_INDEX = AMX_NULLENT)
|
||||||
{
|
{
|
||||||
size_t index = AMX_NULLENT;
|
size_t index = INVALID_INDEX;
|
||||||
if (likely(pEdict != nullptr))
|
if (likely(pEdict != nullptr))
|
||||||
index = indexOfEdict(pEdict);
|
index = indexOfEdict(pEdict);
|
||||||
return index;
|
return index;
|
||||||
@ -54,10 +54,10 @@ inline IGameClient* clientByIndex(const int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// safe to index -1
|
// safe to index -1
|
||||||
inline edict_t* edictByIndexAmx(const int index)
|
inline edict_t* edictByIndexAmx(const int index, const int INVALID_INDEX = AMX_NULLENT)
|
||||||
{
|
{
|
||||||
auto ed = g_pEdicts + index;
|
auto ed = g_pEdicts + index;
|
||||||
if (unlikely(index < 0)) // == AMX_NULLENT
|
if (unlikely(index <= INVALID_INDEX)) // == AMX_NULLENT
|
||||||
ed = nullptr;
|
ed = nullptr;
|
||||||
return ed;
|
return ed;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user