Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand All @@ -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 }}"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
</pre>
</li>

Expand Down
1 change: 1 addition & 0 deletions rehlds/common/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions rehlds/engine/info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions rehlds/engine/sv_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion rehlds/rehlds/rehlds_api_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
95 changes: 57 additions & 38 deletions rehlds/rehlds/rehlds_messagemngr_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
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);
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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 &param = m_params[m_paramCount++];
param.type = type;
param.newlen = param.oldlen = (length == -1) ? SIZEOF_PARAMTYPE[static_cast<size_t>(type)] : length;
param.posBack = param.posFront = gMsgBuffer.cursize;
param.type = type;
param.newlen = param.oldlen = (length == -1) ? SIZEOF_PARAMTYPE[static_cast<size_t>(type)] : length;
param.posBack = param.posFront = gMsgBuffer.cursize;
param.sign[BACK] = param.sign[FRONT] = sign;
}

template <typename T>
inline void setValue(void *pbuf, T value)
{
*static_cast<T *>(pbuf) = value;
}

template <typename T>
inline int getValueInt(const void *pbuf, bool sign = false)
{
return sign ?
*static_cast<const T *>(pbuf) : *static_cast<std::make_unsigned_t<const T> *>(pbuf);
}

// Sets the value of a primitive parameter at the given index
template <typename T>
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)
Expand All @@ -392,30 +407,32 @@ void MessageImpl::setParamPrimitive(size_t index, T value)
switch (param.type)
{
case IMessage::ParamType::Byte:
*(uint8 *)pbuf = value;
setValue<uint8>(pbuf, value);
break;
case IMessage::ParamType::Char:
*(int8 *)pbuf = value;
setValue<int8>(pbuf, value);
break;
case IMessage::ParamType::Short:
case IMessage::ParamType::Entity:
*(int16 *)pbuf = value;
setValue<int16>(pbuf, value);
break;
case IMessage::ParamType::Long:
*(uint32 *)pbuf = value;
setValue<uint32>(pbuf, value);
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<uint8>(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
*(int16 *)pbuf = (int16)(int)(value * 8.0);
setValue<int16>(pbuf, (int)(value * 8.0));
break;
default:
return; // bad type
}

param.sign[BACK] = sign;

// Mark message as modified
param.modified = true;

Expand Down Expand Up @@ -469,14 +486,14 @@ int MessageImpl::getParamInt(size_t index) const
switch (param.type)
{
case IMessage::ParamType::Byte:
return *(uint8 *)buf;
return getValueInt<uint8>(buf);
case IMessage::ParamType::Char:
return *(int8 *)buf;
return getValueInt<int8>(buf, param.sign[BACK]);
case IMessage::ParamType::Short:
case IMessage::ParamType::Entity:
return *(int16 *)buf;
return getValueInt<int16>(buf, param.sign[BACK]);
case IMessage::ParamType::Long:
return *(uint32 *)buf;
return getValueInt<uint32>(buf);
default:
return 0; // bad type
}
Expand All @@ -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<uint8>(buf) * (360.0 / 256.0));
case IMessage::ParamType::Coord:
return (float)(*(int16 *)buf * (1.0 / 8));
return (float)((int16)getValueInt<int16>(buf) * (1.0 / 8));
default:
break; // bad type
}
Expand Down Expand Up @@ -532,14 +549,14 @@ int MessageImpl::getOriginalParamInt(size_t index) const
switch (param.type)
{
case IMessage::ParamType::Byte:
return *(uint8 *)buf;
return getValueInt<uint8>(buf);
case IMessage::ParamType::Char:
return *(int8 *)buf;
return getValueInt<int8>(buf, param.sign[FRONT]);
case IMessage::ParamType::Short:
case IMessage::ParamType::Entity:
return *(int16 *)buf;
return getValueInt<int16>(buf, param.sign[FRONT]);
case IMessage::ParamType::Long:
return *(uint32 *)buf;
return getValueInt<uint32>(buf);
default:
return 0; // bad type
}
Expand All @@ -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<uint8>(buf) * (360.0 / 256.0));
case IMessage::ParamType::Coord:
return (float)(*(int16 *)buf * (1.0 / 8));
return (float)((int16)getValueInt<int16>(buf) * (1.0 / 8));
default:
break; // bad type
}
Expand All @@ -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
Expand Down Expand Up @@ -710,23 +727,23 @@ void MessageImpl::resetParam(size_t index)
switch (param.type)
{
case IMessage::ParamType::Byte:
*(uint8 *)pbackbuf = *(uint8 *)pfrontbuf;
setValue<uint8>(pbackbuf, getValueInt<uint8>(pfrontbuf));
break;
case IMessage::ParamType::Char:
*(int8 *)pbackbuf = *(int8 *)pfrontbuf;
setValue<int8>(pbackbuf, getValueInt<int8>(pfrontbuf));
break;
case IMessage::ParamType::Short:
case IMessage::ParamType::Entity:
*(int16 *)pbackbuf = *(int16 *)pfrontbuf;
setValue<int16>(pbackbuf, getValueInt<int16>(pfrontbuf));
break;
case IMessage::ParamType::Long:
*(uint32 *)pbackbuf = *(uint32 *)pfrontbuf;
setValue<uint32>(pbackbuf, getValueInt<uint32>(pfrontbuf));
break;
case IMessage::ParamType::Angle:
*(uint8 *)pbackbuf = *(uint8 *)pfrontbuf;
setValue<uint8>(pbackbuf, getValueInt<uint8>(pfrontbuf));
break;
case IMessage::ParamType::Coord:
*(int16 *)pbackbuf = *(int16 *)pfrontbuf;
setValue<int16>(pbackbuf, getValueInt<int16>(pfrontbuf));
break;
case IMessage::ParamType::String:
// Return the original string value from the front buffer
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand All @@ -1032,13 +1051,13 @@ 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);
}

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);
}

Expand Down
2 changes: 1 addition & 1 deletion rehlds/rehlds/rehlds_messagemngr_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading