From 89958d348ea617227a4e4360b76900423527bd9e Mon Sep 17 00:00:00 2001 From: s1lentq Date: Fri, 28 Mar 2025 02:41:18 +0700 Subject: [PATCH 1/7] Update build.yml --- .github/workflows/build.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c7d66acf..8547aa3e4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,6 +25,9 @@ jobs: buildTest: 'Test Fixes' steps: + - name: Configure + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: Checkout uses: actions/checkout@v4 with: @@ -90,8 +93,9 @@ jobs: shell: "pwsh" - name: Import PFX and sign + if: github.event_name != 'pull_request' env: - KEY_PFX_PASS: ${{ secrets.KEY_PFX_PASS}} + KEY_PFX_PASS: ${{ secrets.KEY_PFX_PASS }} run: | $pfxBase64 = "${{ secrets.KEY_PFX_B64 }}" [IO.File]::WriteAllBytes("${{ github.workspace }}\signing-cert.pfx", [Convert]::FromBase64String($pfxBase64)) @@ -158,11 +162,6 @@ jobs: container: debian:11-slim steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Install dependencies run: | dpkg --add-architecture i386 @@ -174,6 +173,14 @@ jobs: git cmake rsync \ g++ gcc + - name: Configure + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: GPG Import run: | echo "${{ secrets.PUB_ASC }}" > "${{ secrets.PUB_ASC_FILE }}" From 45fe816fdd6bd9eca557455fcf2d358ae2f5fe16 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Sat, 29 Mar 2025 02:46:36 +0700 Subject: [PATCH 2/7] 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 534051932..fa4a52635 100644 --- a/rehlds/rehlds/rehlds_messagemngr_impl.cpp +++ b/rehlds/rehlds/rehlds_messagemngr_impl.cpp @@ -213,13 +213,13 @@ class MessageImpl: public IMessage 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 @@ class MessageImpl: public IMessage 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 f016b193e..dbb96367e 100644 --- a/rehlds/rehlds/rehlds_messagemngr_impl.h +++ b/rehlds/rehlds/rehlds_messagemngr_impl.h @@ -93,7 +93,7 @@ class MessageManagerImpl: public IMessageManager 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 From a2953ea3749b25f21e424defb7e277280b937f88 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Tue, 1 Apr 2025 22:26:38 +0700 Subject: [PATCH 3/7] API game message manager: fix typo --- rehlds/rehlds/rehlds_messagemngr_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rehlds/rehlds/rehlds_messagemngr_impl.cpp b/rehlds/rehlds/rehlds_messagemngr_impl.cpp index fa4a52635..6179504b3 100644 --- a/rehlds/rehlds/rehlds_messagemngr_impl.cpp +++ b/rehlds/rehlds/rehlds_messagemngr_impl.cpp @@ -421,7 +421,7 @@ void MessageImpl::setParamPrimitive(size_t index, T value, bool sign) break; case IMessage::ParamType::Angle: // Convert angle value to byte representation with loss of precision - *(uint8 *)pbuf = (int64)(fmod((double)value, 360.0) * 256.0 / 360.0) & 0xff; + setValue(pbuf, (int64)(fmod((double)value, 360.0) * 256.0 / 360.0) & 0xff); break; case IMessage::ParamType::Coord: // Convert coordinate value to short integer representation with loss of precision @@ -1051,7 +1051,7 @@ void EXT_FUNC PF_WriteCoord_Intercept(float flValue) void EXT_FUNC PF_WriteString_Intercept(const char *sz) { - if (MessageManager().WriteParam(IMessage::ParamType::String, sz ? Q_strlen(sz) + 1 : 1)) + if (MessageManager().WriteParam(IMessage::ParamType::String, false, sz ? Q_strlen(sz) + 1 : 1)) PF_WriteString_I(sz); } From 2f87ace7fc380e2710518b0e25b14409f0b53de6 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Wed, 2 Apr 2025 21:16:17 +0700 Subject: [PATCH 4/7] Fix dumb bug where skip logos without advancing to next iter, causing an endless loop when sv_send_logos is disabled Fixes #1085 --- rehlds/engine/sv_main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index 20ba978ff..6b70b8835 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -5781,8 +5781,12 @@ void SV_PropagateCustomizations(void) pResource = &pCust->resource; #ifdef REHLDS_FIXES + // skip logos if sv_send_logos is 0 if ((pResource->ucFlags & RES_CUSTOM) && !sv_send_logos.value) + { + pCust = pCust->pNext; continue; + } #endif MSG_WriteByte(&host_client->netchan.message, svc_customization); From 98b4103b868f97a01793b70f1cdb7a555519cd82 Mon Sep 17 00:00:00 2001 From: Splatt581 <31417200+Splatt581@users.noreply.github.com> Date: Fri, 4 Apr 2025 01:08:30 +0300 Subject: [PATCH 5/7] Added check for invalid utf8 chars in userinfo (#1074) --- rehlds/engine/info.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rehlds/engine/info.cpp b/rehlds/engine/info.cpp index 6680d3571..d0a36e331 100644 --- a/rehlds/engine/info.cpp +++ b/rehlds/engine/info.cpp @@ -856,6 +856,12 @@ qboolean Info_IsValid(const char *s) return false; }; + // invalid utf8 chars are deprecated + if (!Q_UnicodeValidate(s)) + { + return FALSE; + } + while (*s == '\\') { const char* key = ++s; From 7bc5d86add2dc4b8bbafd427180f50c860620c76 Mon Sep 17 00:00:00 2001 From: Faruk <98034193+farukerdem34@users.noreply.github.com> Date: Fri, 4 Apr 2025 01:09:13 +0300 Subject: [PATCH 6/7] cmake dependecy (#1080) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3ca47c715..7533e4b43 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ sudo apt-get update sudo apt-get install -y gcc-multilib g++-multilib sudo apt-get install -y build-essential sudo apt-get install -y libc6-dev libc6-dev-i386 +sudo apt-get install -y cmake From 44e510a25cba2f48f2d70f6074abb94dc4631cf1 Mon Sep 17 00:00:00 2001 From: s1lentq Date: Sat, 5 Apr 2025 02:20:58 +0700 Subject: [PATCH 7/7] SV_EmitSound2: Add new flag SND_EMIT2_USE_ORIGIN for using custom origin instead of entity origin --- rehlds/common/const.h | 1 + rehlds/rehlds/rehlds_api_impl.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rehlds/common/const.h b/rehlds/common/const.h index 721a8dab2..f498db153 100644 --- a/rehlds/common/const.h +++ b/rehlds/common/const.h @@ -74,6 +74,7 @@ // SV_EmitSound2 flags #define SND_EMIT2_NOPAS (1<<0) // never to do check PAS #define SND_EMIT2_INVOKER (1<<1) // do not send to the client invoker +#define SND_EMIT2_USE_ORIGIN (1<<2) // use given origin instead of entity origin // Engine edict->spawnflags #define SF_NOTINDEATHMATCH 0x0800 // Do not spawn when deathmatch and loading entities from a file diff --git a/rehlds/rehlds/rehlds_api_impl.cpp b/rehlds/rehlds/rehlds_api_impl.cpp index e4f0e00bc..9cdd7e196 100644 --- a/rehlds/rehlds/rehlds_api_impl.cpp +++ b/rehlds/rehlds/rehlds_api_impl.cpp @@ -579,7 +579,7 @@ bool EXT_FUNC SV_EmitSound2_internal(edict_t *entity, IGameClient *pReceiver, in bool bSendPAS = (channel != CHAN_STATIC && !(flags & SND_FL_STOP) && !(emitFlags & SND_EMIT2_NOPAS)); vec3_t origin = {0, 0, 0}; - if (entity && entity != g_psv.edicts) + if ((!pOrigin || !(emitFlags & SND_EMIT2_USE_ORIGIN)) && entity && entity != g_psv.edicts) { for (int i = 0; i < 3; ++i) origin[i] = (entity->v.maxs[i] + entity->v.mins[i]) * 0.5f + entity->v.origin[i];