From 45fe816fdd6bd9eca557455fcf2d358ae2f5fe16 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Sat, 29 Mar 2025 02:46:36 +0700 Subject: [PATCH] API game message manager: add support signed/unsigned value for char,short types --- rehlds/rehlds/rehlds_messagemngr_impl.cpp | 91 ++++++++++++++--------- rehlds/rehlds/rehlds_messagemngr_impl.h | 2 +- 2 files changed, 56 insertions(+), 37 deletions(-) diff --git a/rehlds/rehlds/rehlds_messagemngr_impl.cpp b/rehlds/rehlds/rehlds_messagemngr_impl.cpp index 5340519..fa4a526 100644 --- a/rehlds/rehlds/rehlds_messagemngr_impl.cpp +++ b/rehlds/rehlds/rehlds_messagemngr_impl.cpp @@ -213,13 +213,13 @@ private: void setCopybackBuffer(sizebuf_t *pbuf); // Adds a parameter to the message - void addParam(IMessage::ParamType type, size_t length); + void addParam(IMessage::ParamType type, bool sign, size_t length); // Clears the message after execution void clear(); template - void setParamPrimitive(size_t index, T value); + void setParamPrimitive(size_t index, T value, bool sign = false); // Transforms buffer after sets string for a parameter at the given index void setTxformBuffer(size_t index, size_t startPos, size_t oldLength, size_t newLength); @@ -263,6 +263,7 @@ private: size_t posFront : 9; // The stock position of the parameter in the buffer size_t oldlen : 9; // The length of the parameter in the buffer size_t newlen : 9; // The length of the parameter in the buffer + bool sign[MAX_STORAGE]; // Flag indicating that it has a signed value }; #pragma pack(pop) @@ -369,17 +370,31 @@ static size_t SIZEOF_PARAMTYPE[] = }; // Adds a parameter to the message -void MessageImpl::addParam(IMessage::ParamType type, size_t length) +void MessageImpl::addParam(IMessage::ParamType type, bool sign, size_t length) { Param_t ¶m = m_params[m_paramCount++]; - param.type = type; - param.newlen = param.oldlen = (length == -1) ? SIZEOF_PARAMTYPE[static_cast(type)] : length; - param.posBack = param.posFront = gMsgBuffer.cursize; + param.type = type; + param.newlen = param.oldlen = (length == -1) ? SIZEOF_PARAMTYPE[static_cast(type)] : length; + param.posBack = param.posFront = gMsgBuffer.cursize; + param.sign[BACK] = param.sign[FRONT] = sign; +} + +template +inline void setValue(void *pbuf, T value) +{ + *static_cast(pbuf) = value; +} + +template +inline int getValueInt(const void *pbuf, bool sign = false) +{ + return sign ? + *static_cast(pbuf) : *static_cast *>(pbuf); } // Sets the value of a primitive parameter at the given index template -void MessageImpl::setParamPrimitive(size_t index, T value) +void MessageImpl::setParamPrimitive(size_t index, T value, bool sign) { // Ensure index is within bounds if (index >= m_paramCount) @@ -392,17 +407,17 @@ void MessageImpl::setParamPrimitive(size_t index, T value) switch (param.type) { case IMessage::ParamType::Byte: - *(uint8 *)pbuf = value; + setValue(pbuf, value); break; case IMessage::ParamType::Char: - *(int8 *)pbuf = value; + setValue(pbuf, value); break; case IMessage::ParamType::Short: case IMessage::ParamType::Entity: - *(int16 *)pbuf = value; + setValue(pbuf, value); break; case IMessage::ParamType::Long: - *(uint32 *)pbuf = value; + setValue(pbuf, value); break; case IMessage::ParamType::Angle: // Convert angle value to byte representation with loss of precision @@ -410,12 +425,14 @@ void MessageImpl::setParamPrimitive(size_t index, T value) break; case IMessage::ParamType::Coord: // Convert coordinate value to short integer representation with loss of precision - *(int16 *)pbuf = (int16)(int)(value * 8.0); + setValue(pbuf, (int)(value * 8.0)); break; default: return; // bad type } + param.sign[BACK] = sign; + // Mark message as modified param.modified = true; @@ -469,14 +486,14 @@ int MessageImpl::getParamInt(size_t index) const switch (param.type) { case IMessage::ParamType::Byte: - return *(uint8 *)buf; + return getValueInt(buf); case IMessage::ParamType::Char: - return *(int8 *)buf; + return getValueInt(buf, param.sign[BACK]); case IMessage::ParamType::Short: case IMessage::ParamType::Entity: - return *(int16 *)buf; + return getValueInt(buf, param.sign[BACK]); case IMessage::ParamType::Long: - return *(uint32 *)buf; + return getValueInt(buf); default: return 0; // bad type } @@ -495,9 +512,9 @@ float MessageImpl::getParamFloat(size_t index) const switch (param.type) { case IMessage::ParamType::Angle: - return (float)(*(uint8 *)buf * (360.0 / 256.0)); + return (float)((uint8)getValueInt(buf) * (360.0 / 256.0)); case IMessage::ParamType::Coord: - return (float)(*(int16 *)buf * (1.0 / 8)); + return (float)((int16)getValueInt(buf) * (1.0 / 8)); default: break; // bad type } @@ -532,14 +549,14 @@ int MessageImpl::getOriginalParamInt(size_t index) const switch (param.type) { case IMessage::ParamType::Byte: - return *(uint8 *)buf; + return getValueInt(buf); case IMessage::ParamType::Char: - return *(int8 *)buf; + return getValueInt(buf, param.sign[FRONT]); case IMessage::ParamType::Short: case IMessage::ParamType::Entity: - return *(int16 *)buf; + return getValueInt(buf, param.sign[FRONT]); case IMessage::ParamType::Long: - return *(uint32 *)buf; + return getValueInt(buf); default: return 0; // bad type } @@ -557,9 +574,9 @@ float MessageImpl::getOriginalParamFloat(size_t index) const switch (param.type) { case IMessage::ParamType::Angle: - return (float)(*(uint8 *)buf * (360.0 / 256.0)); + return (float)((uint8)getValueInt(buf) * (360.0 / 256.0)); case IMessage::ParamType::Coord: - return (float)(*(int16 *)buf * (1.0 / 8)); + return (float)((int16)getValueInt(buf) * (1.0 / 8)); default: break; // bad type } @@ -584,7 +601,7 @@ const char *MessageImpl::getOriginalParamString(size_t index) const // Sets the integer value of the parameter at the given index void MessageImpl::setParamInt(size_t index, int value) { - setParamPrimitive(index, value); + setParamPrimitive(index, value, value < 0); } // Sets the float value of the parameter at the given index @@ -710,23 +727,23 @@ void MessageImpl::resetParam(size_t index) switch (param.type) { case IMessage::ParamType::Byte: - *(uint8 *)pbackbuf = *(uint8 *)pfrontbuf; + setValue(pbackbuf, getValueInt(pfrontbuf)); break; case IMessage::ParamType::Char: - *(int8 *)pbackbuf = *(int8 *)pfrontbuf; + setValue(pbackbuf, getValueInt(pfrontbuf)); break; case IMessage::ParamType::Short: case IMessage::ParamType::Entity: - *(int16 *)pbackbuf = *(int16 *)pfrontbuf; + setValue(pbackbuf, getValueInt(pfrontbuf)); break; case IMessage::ParamType::Long: - *(uint32 *)pbackbuf = *(uint32 *)pfrontbuf; + setValue(pbackbuf, getValueInt(pfrontbuf)); break; case IMessage::ParamType::Angle: - *(uint8 *)pbackbuf = *(uint8 *)pfrontbuf; + setValue(pbackbuf, getValueInt(pfrontbuf)); break; case IMessage::ParamType::Coord: - *(int16 *)pbackbuf = *(int16 *)pfrontbuf; + setValue(pbackbuf, getValueInt(pfrontbuf)); break; case IMessage::ParamType::String: // Return the original string value from the front buffer @@ -740,6 +757,8 @@ void MessageImpl::resetParam(size_t index) // Unmark message as modified param.modified = false; + + param.sign[BACK] = param.sign[FRONT]; } // Resets a specific message parameter to its original value @@ -955,7 +974,7 @@ bool MessageManagerImpl::MessageEnd() return false; } -bool MessageManagerImpl::WriteParam(IMessage::ParamType type, size_t length) +bool MessageManagerImpl::WriteParam(IMessage::ParamType type, bool sign, size_t length) { // Check if in block mode if (m_inblock) @@ -966,7 +985,7 @@ bool MessageManagerImpl::WriteParam(IMessage::ParamType type, size_t length) { // Add parameter to top stack message MessageImpl &msg = m_stack.top(); - msg.addParam(type, length); + msg.addParam(type, sign, length); } return true; @@ -1002,13 +1021,13 @@ void EXT_FUNC PF_WriteByte_Intercept(int iValue) void EXT_FUNC PF_WriteChar_Intercept(int iValue) { - if (MessageManager().WriteParam(IMessage::ParamType::Char)) + if (MessageManager().WriteParam(IMessage::ParamType::Char, iValue < 0)) PF_WriteChar_I(iValue); } void EXT_FUNC PF_WriteShort_Intercept(int iValue) { - if (MessageManager().WriteParam(IMessage::ParamType::Short)) + if (MessageManager().WriteParam(IMessage::ParamType::Short, iValue < 0)) PF_WriteShort_I(iValue); } @@ -1038,7 +1057,7 @@ void EXT_FUNC PF_WriteString_Intercept(const char *sz) void EXT_FUNC PF_WriteEntity_Intercept(int iValue) { - if (MessageManager().WriteParam(IMessage::ParamType::Entity)) + if (MessageManager().WriteParam(IMessage::ParamType::Entity, iValue < 0)) PF_WriteEntity_I(iValue); } diff --git a/rehlds/rehlds/rehlds_messagemngr_impl.h b/rehlds/rehlds/rehlds_messagemngr_impl.h index f016b19..dbb9636 100644 --- a/rehlds/rehlds/rehlds_messagemngr_impl.h +++ b/rehlds/rehlds/rehlds_messagemngr_impl.h @@ -93,7 +93,7 @@ private: bool MessageEnd(); private: - bool WriteParam(IMessage::ParamType type, size_t length = -1); + bool WriteParam(IMessage::ParamType type, bool sign = false, size_t length = -1); bool m_inblock; // Flag indicating whether a message block is currently active bool m_inhook; // Flag indicating whether a message hook is currently active